Sketch Plugin Development Guide: From Setup to Advanced Features
This article provides a comprehensive tutorial on developing Sketch plugins using JavaScript, CocoaScript, and skpm, covering background motivation, required knowledge, quick start steps, project structure, manifest configuration, menu nesting, API usage, actions, WebView integration, debugging, hands‑on examples, and best practices for front‑end engineers seeking to bridge design and code.
Background: Sketch is a UI design tool and many plugins improve designers' efficiency; front‑end engineers can boost productivity by generating code from Sketch files, which is the motivation for learning Sketch plugin development.
Prerequisites: JavaScript + CocoaScript, optional React/Vue for WebView, and build tools such as webpack and the skpm CLI.
Quick start with skpm: install globally, create a project with a template, install dependencies, run watch for hot‑reloading, and build the plugin.
npm install -g skpm
skpm create
--template=
npm install
npm run watch
npm run buildProject structure: shows assets, the generated .sketchplugin bundle, manifest.json, source files, and WebView resources.
├── assets
│ └── icon.png // plugin icon
├── sketch-plugin-demo.sketchplugin // built plugin package
│ └── Contents
│ ├── Resources
│ │ └── _webpack_resources
│ │ └── resources_webview.js
│ └── Sketch
│ ├── manifest.json
│ ├── __my-command.js
│ └── __my-command.js.map
├── package.json
├── webpack.skpm.config.js // webpack config
├── resources // WebView assets
│ ├── style.css
│ ├── webview.html
│ └── webview.js
└── src
├── manifest.json // plugin manifest
└── my-command.js // command scriptmanifest.json: defines compatibleVersion, bundleVersion, commands (name, identifier, shortcut, script, handlers) and menu items linking commands to UI.
{
"compatibleVersion": 3,
"bundleVersion": 1,
"commands": [
{
"name": "生成随机色",
"identifier": "sketch-plugin-demo.generate-random-color",
"shortcut": "ctrl shift r",
"script": "./generateColor.js",
"handlers": {
"run": "onRun",
"actions": {
"OpenDocument": "onOpenDocument"
}
}
}
],
"menu": {
"title": "sketch-plugin-demo",
"items": ["my-plugin-with-webview.my-command-identifier"]
}
}Menu configuration can be nested to multiple levels, illustrated with a JSON example.
{
"commands": [
{
"name": "第三级菜单项",
"identifier": "my-plugin-with-webview.my-command-identifier",
"script": "./my-command.js",
"handlers": {
"run": "onRun",
"actions": {"Shutdown": "onShutdown"}
}
}
],
"menu": {
"title": "my-plugin-with-webview",
"items": [
{
"title": "第一级菜单项",
"items": [
{
"title": "第二级菜单项",
"items": ["my-plugin-with-webview.my-command-identifier"]
}
]
}
]
}
}Development tools: the Sketch DevTools plugin helps inspect document structure, network, actions, and console output.
JavaScript API: import modules (sketch/dom, sketch/async, sketch/data‑supplier, sketch/ui, sketch/settings) and use them to read and modify documents, e.g., retrieve selected layers and display their text.
import SketchDom from 'sketch/dom';
import UI from 'sketch/ui';
const strArray = [];
const getTextValue = (layers) => {
if (layers.length) {
layers.forEach(layer => {
const { type, layers: subLayers = [] } = layer;
if (type === 'Text') {
strArray.push(layer.text);
}
if (subLayers.length) {
getTextValue(subLayers);
}
});
}
};
export default () => {
const doc = SketchDom.getSelectedDocument();
const layers = doc.selectedLayers.layers;
getTextValue(layers);
UI.message('已选择的文本内容:' + strArray.toString());
};Actions: register actions in manifest.json and implement callbacks (onStartUp, onShutdown) that receive a Context object containing action, scriptPath, command, document, and selection.
export const onStartUp = context => {
UI.message('Sketch-plugin-demo 插件已启动');
};
export const onShutdown = context => {
UI.message('Sketch-plugin-demo 插件已被禁用');
};WebView: create a BrowserWindow, load HTML, communicate between plugin and WebView via executeJavaScript and postMessage, and enable debugging with WebKitDeveloperExtras.
const createWebView = () => {
const options = {
identifier: 'my-plugin-with-webview.webview',
title: 'This is a WebView',
width: 600,
height: 200,
resizable: true
};
const browserWindow = new BrowserWindow(options);
browserWindow.once('ready-to-show', () => { browserWindow.show(); });
const webContents = browserWindow.webContents;
webContents.on('did-finish-load', () => { UI.message('UI loaded!'); });
browserWindow.loadURL(require('../resources/webview.html'));
};
// Plugin → WebView
webContents.executeJavaScript(`setRandomNumber(${Math.random()})`).catch(console.error);
// WebView → Plugin
window.postMessage('nativeLog', 'Called from the webview');
webContents.on('nativeLog', s => { UI.message(s); });Hands‑on examples:
Example 1 – Random color generator that updates a rectangle's fill color and its label text using Mock.js.
import SketchDom from 'sketch/dom';
import UI from 'sketch/ui';
import Mock from 'mockjs';
const Random = Mock.Random;
export default () => {
const doc = SketchDom.getSelectedDocument();
const layers = doc.selectedLayers.layers;
if (layers.length) {
layers.forEach(layer => {
const { type, layers: subLayers = [] } = layer;
if (type === 'Group') {
subLayers.forEach(subLayer => {
const randomColor = Random.hex();
if (subLayer.type === 'ShapePath') {
subLayer.style.fills[0].color = randomColor;
}
if (subLayer.type === 'Text') {
subLayer.text = randomColor;
}
});
}
});
} else {
UI.message('当前没有元素被选中,请选择');
}
};Example 2 – Embedding a Umi + Ant Design login page inside a WebView, with instructions for project setup and code snippets.
import styles from './index.css';
import { Input, Button } from 'antd';
import { EyeInvisibleOutlined, EyeTwoTone } from '@ant-design/icons';
export default function() {
return (
(visible ?
:
)}
/>
登录
);
}Conclusion: Sketch plugins let front‑end teams bridge design and code, automate UI standards, and accelerate delivery; the key is defining useful workflows rather than mastering every technology.
References: official Sketch Plugin documentation (https://developer.sketch.com/) and a tutorial on Sketch WebView development.
政采云技术
ZCY Technology Team (Zero), based in Hangzhou, is a growth-oriented team passionate about technology and craftsmanship. With around 500 members, we are building comprehensive engineering, project management, and talent development systems. We are committed to innovation and creating a cloud service ecosystem for government and enterprise procurement. We look forward to your joining us.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.