A modern Figma plugin boilerplate built with Svelte and the Figma UI3 Kit components.
Clone or download this boilerplate
Install dependencies:
npm install
Build the plugin:
npm run build
Import the plugin in Figma:
Plugins > Development > Import Plugin from Manifestmanifest.json file from the dist/ directoryFor development with hot reload:
npm run dev
Then enable "Hot reload plugin" in Figma's Plugin Development menu.
npm run build - Production build (outputs to dist/)npm run dev - Watch mode for development with hot reloadnpm run lint - Check code quality with ESLint and Prettiernpm run prettier - Auto-format all code filesFigma plugins have two separate parts that communicate with each other:
Plugin Sandbox (code.ts) - Runs in Figma's sandbox environment with access to the Plugin API. This is where you create, modify, and read Figma nodes.
UI Layer (Svelte components) - Runs in an isolated iframe with no direct access to the Plugin API. This is your user interface.
These two parts communicate via postMessage(). The UI sends messages to the plugin code, and the plugin code can send messages back to update the UI.
The custom Vite configuration handles Figma's unique requirements:
dist/index.html and the plugin code in dist/code.jsmanifest.json to the output directory├── src/
│ ├── code.ts # Plugin logic (runs in Figma sandbox)
│ ├── main.js # Entry point for UI
│ ├── PluginUI.svelte # Main UI component
│ ├── index.html # HTML template
│ ├── manifest.json # Plugin configuration
│ ├── env.d.ts # TypeScript environment definitions
│ └── styles/ # CSS variable reference files
│ ├── global.css # UI3 Kit CSS variables
│ └── figma-development-theme.css # Figma theme variables
├── dist/ # Built files (generated)
├── vite.config.ts # Vite build configuration
└── package.json # Dependencies and scripts
The included demo showcases these UI3 Kit components:
Before building your own plugin, update these files:
src/manifest.json - Change the name and id fields to match your pluginpackage.json - Update name and descriptionsrc/PluginUI.svelte - Replace the demo UI with your own interfacesrc/code.ts - Replace the demo logic with your plugin functionalitysrc/PluginUI.sveltesrc/code.ts<style> section in the Svelte componentThe src/styles/ directory contains CSS variable reference files:
global.css - UI3 Kit variables (colors, sizes, spacing, fonts)figma-development-theme.css - Figma's official theme variablesThese files are for reference only (no need to import them). Use the variables in your custom styles:
.my-element {
color: var(--figma-color-text);
padding: var(--size-small);
background: var(--figma-color-bg);
font-family: var(--figma-font-stack);
}
The UI3 Kit components automatically provide these variables, and Figma injects its theme variables when your plugin runs.
Import additional components from the UI3 Kit:
import { NewComponent } from 'figma-ui3-kit-svelte';
The UI communicates with the plugin code via messages:
// In UI (PluginUI.svelte)
function sendMessage(type, data = {}) {
parent.postMessage({ pluginMessage: { type, ...data } }, '*');
}
// In plugin code (code.ts)
figma.ui.onmessage = async (msg) => {
if (msg.type === 'your-action') {
// Handle the action
}
};
When creating text elements in Figma, you must load the font first:
// Load font before creating text
await figma.loadFontAsync({ family: "Inter", style: "Regular" });
const text = figma.createText();
text.characters = "Your text here";
npm run build
This creates optimized files in the dist/ directory ready for distribution.
MIT License - feel free to use this boilerplate for your own Figma plugins.