Weave realistic data into your Sketch designs using local AI - powered by Ollama, no internet required
Weaver is a Sketch plugin that weaves contextual, realistic data into your designs using local AI. Like a weaver crafting intricate patterns, this plugin seamlessly integrates AI-generated content into your design layers - all running locally on your machine via Ollama. No internet connection, no API keys, no cloud services - just you, your designs, and your local LLM working together.
- 🏠 Local-First Architecture - Uses Ollama running locally, works offline, no API keys or cloud services required
- 🧵 Smart Layer Weaving - Automatically detects and populates layers named with variable syntax (e.g.,
$cardTitle,$price) - 🔄 Symbol Override Support - Works with both text layers and symbol instance overrides
- 🎭 Contextual Generation - Provide natural language prompts to generate themed, realistic data
- 🔒 Private & Secure - Everything runs on your machine, your data never leaves your computer
- 🧪 Fully Tested - Comprehensive test suite ensures reliability
✈️ Offline-Ready - Perfect for working on flights, in cafes, or anywhere without internet
Before installing the plugin, you need to have Ollama installed and running:
-
Download Ollama:
- Visit https://ollama.com
- Download for your operating system (macOS, Linux, Windows)
-
Install Llama 3:
ollama pull llama3
-
Verify Ollama is Running:
curl http://localhost:11434/api/tags
You should see a JSON response with available models.
- Download the latest
weaver.sketchpluginfrom the Releases page - Double-click the file to install
- Sketch will automatically install the plugin
# Clone the repository
git clone https://github.com/kocheck/Weaver.git
cd Weaver
# Install dependencies
npm install
# Build and link the plugin
npm run build
npm run link-
Prepare Your Layers
Name layers using the
$prefix to mark them as variables:$cardTitle- Product title$description- Description text$price- Price information$authorName- Author name
The plugin supports:
- Text layers
- Symbol instance overrides
-
Select Your Layers
Select one or more layers (or groups containing variable layers)
-
Open the Plugin
- Menu: Plugins → Weaver → Generate Mock Data
- Keyboard:
Ctrl + Shift + M
-
Configure Generation
In the plugin UI:
- JSON Keys: Enter the variable names (comma-separated)
- Example:
cardTitle, description, price
- Example:
- Context Prompt: Describe the type of data you need
- Example: "Menu items for a cyberpunk noodle bar in Tokyo"
- JSON Keys: Enter the variable names (comma-separated)
-
Generate
Click "✨ Generate Data" and watch your layers populate with AI-generated content!
Layers:
$productName
$productDescription
$price
$rating
$reviewCount
JSON Keys: productName, productDescription, price, rating, reviewCount
Prompt: "High-end sustainable fashion products for eco-conscious millennials"
Result:
- productName: "Organic Hemp Blazer"
- productDescription: "Ethically sourced, carbon-neutral business wear"
- price: "$189.99"
- rating: "4.8"
- reviewCount: "127 reviews"
Layers:
$dishName
$ingredients
$price
$calories
JSON Keys: dishName, ingredients, price, calories
Prompt: "Fusion sushi restaurant menu items with modern twist"
Result:
- dishName: "Spicy Tuna Volcano Roll"
- ingredients: "Fresh tuna, avocado, jalapeño, tempura flakes"
- price: "$16"
- calories: "380 cal"
Layers:
$userName
$bio
$location
$followers
JSON Keys: userName, bio, location, followers
Prompt: "Social media profiles for travel influencers"
Result:
- userName: "WanderlustSarah"
- bio: "Digital nomad exploring hidden gems 🌍"
- location: "Bali, Indonesia"
- followers: "24.5K"
Prefix layer names with $ to mark them as variables:
✅ Good:
$cardTitle$price$userName$description
❌ Bad:
cardTitle(missing $)$card-title(use camelCase)$(empty variable name)
- Use camelCase:
$productNameinstead of$product_name - Be Descriptive:
$authorBioinstead of$text1 - Match JSON Keys: Layer
$price→ JSON keyprice - Nested Groups: Variable layers work at any nesting level
Click "⚙️ Advanced Settings" in the plugin UI to configure:
- Default:
http://localhost:11434/api/generate - Custom: If running Ollama on a different port or remote server
- Default:
llama3 - Alternatives:
llama3.1,mistral,codellama(any Ollama model)
Click "Test Connection" to verify Ollama is accessible before generating data.
npm testThe test suite includes:
- Unit Tests: Layer traversal, LLM client, data injection
- Integration Tests: Complete workflow testing
- Mocked Dependencies: Tests run without requiring Sketch or Ollama
layerTraversal.test.js- Layer detection and variable extractionllmClient.test.js- Ollama API communicationdataInjector.test.js- Data injection logicintegration.test.js- End-to-end workflows
npm run test:watchnpm run buildOutput: weaver.sketchplugin
npm run watchAutomatically rebuilds the plugin on file changes.
Weaver/
├── src/
│ ├── my-command.js # Main plugin entry point
│ ├── ui.html # WebView UI
│ └── utils/
│ ├── layerTraversal.js # Layer scanning & detection
│ ├── llmClient.js # Ollama API client
│ └── dataInjector.js # Data injection logic
├── __tests__/
│ ├── layerTraversal.test.js
│ ├── llmClient.test.js
│ ├── dataInjector.test.js
│ └── integration.test.js
├── manifest.json # Plugin manifest
├── package.json # NPM configuration
└── README.md
Handles recursive layer scanning to find variable-named layers:
findVariableLayers()- Recursively finds all variable layersextractVariableNames()- Extracts unique variable namesvalidateLayers()- Validates selection contains variables
Manages communication with Ollama:
generateMockData()- Sends prompts and receives JSON datatestConnection()- Verifies Ollama is accessiblegetAvailableModels()- Lists available Ollama models
Injects generated data into layers:
injectData()- Updates text layers and symbol overridespreviewInjection()- Shows what will be updatedvalidateData()- Ensures data matches required structure
Cause: Ollama is not running or not accessible
Solution:
- Start Ollama:
ollama serve - Verify:
curl http://localhost:11434/api/tags - Check firewall settings
Cause: No layers are named with $ prefix
Solution:
- Rename layers to use variable syntax (e.g.,
$cardTitle) - Ensure layers are selected before running the plugin
Cause: LLM generated invalid JSON
Solution:
- Simplify your prompt
- Reduce the number of JSON keys
- Try a different model (e.g.,
llama3.1)
Cause: LLM is taking too long to respond (>60s)
Solution:
- Reduce complexity of the prompt
- Use a smaller model
- Ensure your system has sufficient resources
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Write tests for new functionality
- Run tests:
npm test - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
MIT License - see LICENSE file for details
- Ollama - For making local-first LLM inference accessible and empowering offline workflows
- Meta - For Llama 3 and advancing open-source AI
- Sketch - For the excellent plugin API and supporting the design community
- skpm - For the Sketch plugin development framework
Just as a weaver interlaces threads to create intricate fabrics, this plugin weaves AI-generated data into your design layers, creating rich, contextual content. The name also emphasizes our local-first philosophy - like a traditional weaver working at their loom, you have complete control and ownership, with no dependence on external services or internet connectivity.
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Support for image generation (layer fills)
- Multiple data variants (generate sets)
- Custom model fine-tuning
- Optional cloud LLM provider support (for when you DO have internet)
- Data templates library
- Batch processing for multiple artboards
- Improved offline model management
Made with ❤️ for the Sketch community | Local-first, privacy-focused, always offline-ready