Napkin
From thought to diagram in seconds — entirely offline.
A fast, local-first drawing and diagramming app built with Tauri and rough.js. Create system diagrams, flowcharts, sprint boards, and wireframes — with a hand-drawn feel. No accounts, no cloud, no tracking. Your data stays on your machine.
Examples
A few things you can build with Napkin.
Features
- Instant and private — opens immediately, works offline, nothing leaves your computer
- Hand-drawn feel — rough.js rendering gives diagrams a natural, sketchy look
- Desktop native — built with Tauri, runs as a real app, not a browser tab
- Simple file format —
.napkinfiles are JSON, easy to version control or script - AI-ready — built-in MCP server lets AI agents create and edit diagrams
Drawing
- 13 shape types: rectangles, ellipses, triangles, diamonds, hexagons, stars, clouds, cylinders, sticky notes, lines, arrows, freehand, and text
- Lines and arrows with direct, elbow, or curved routing
- 7 endpoint styles (arrow, open-arrow, triangle, circle, diamond, square, none)
- Configurable fill styles: hachure, solid, zigzag, cross-hatch, dots
- Paste images from clipboard directly onto the canvas
- Resize, rotate, snap, align, and style everything
- Smart guides: alignment lines and equal-spacing indicators when dragging shapes
- Snap to grid, object snap, and alignment hints (independently toggleable)
- Auto-layout: grid and force-directed arrangement via context menu or MCP
- Adjustable roughness (0 = clean, 3 = very sketchy)
Workflow
- Multiple tabs with collection save/restore
- Undo/redo (single undo for drag, resize, and rotate gestures), copy/paste, duplicate
- Export to PNG or SVG
- Presentation mode with fullscreen and pan navigation
- Auto-save with recovery
- Native file dialogs on desktop
Getting Started
Download the latest build for your platform from the GitHub Releases page:
- macOS —
.dmg(Apple Silicon and Intel) - Windows —
.msior.exe - Linux —
.debor.AppImage
Want to build from source or contribute? See the Contributing Guide.
Shapes
| Shape | Description |
|---|---|
| Rectangle | Standard box shape |
| Ellipse | Circle or oval |
| Triangle | Equilateral triangle |
| Diamond | Rotated square / rhombus |
| Hexagon | Six-sided polygon |
| Star | Five-pointed star |
| Cloud | Cloud shape using bezier curves |
| Cylinder | 3D cylinder (databases, storage) |
| Sticky Note | Colored note with text |
| Text | Standalone text label |
| Line | Line without arrowhead |
| Arrow | Line with arrowhead |
| Freehand | Freeform pencil drawing |
All shapes support: stroke color, fill color, fill style, opacity, rotation, roughness (0–3), and text content.
Connections
Lines and arrows can bind to shapes at 5 connection points: top, right, bottom, left, center. Bound connections follow their shapes when moved, resized, or rotated.
Routing modes
- Direct — straight line between endpoints
- Elbow — orthogonal segments (right angles)
- Curved — quadratic bezier via control points
Keyboard Shortcuts
Tools
| Key | Tool | Key | Tool |
|---|---|---|---|
| V | Select | L | Line |
| R | Rectangle | A | Arrow |
| E | Ellipse | D | Freehand |
| G | Triangle | T | Text |
| I | Diamond | S | Sticky Note |
| X | Hexagon | H | Pan |
| P | Star | Space | Temp pan (hold) |
| C | Cloud | Esc | Cancel / Select |
| Y | Cylinder |
Actions
| Shortcut | Action |
|---|---|
| Cmd + Z | Undo |
| Cmd + Shift + Z | Redo |
| Cmd + C | Copy |
| Cmd + V | Paste |
| Cmd + D | Duplicate |
| Cmd + ' | Toggle grid |
| Cmd + Shift + P | Presentation mode |
| Cmd + drag | Pan canvas |
| Delete | Delete selected |
MCP Server
Napkin includes a built-in Model Context Protocol (MCP) server that lets AI agents — like Claude — create and manipulate diagrams programmatically. The server runs locally and bridges tool calls from an AI client through to the Napkin canvas.
Architecture
The MCP server uses a bridge pattern:
- AI client sends JSON-RPC request to
http://127.0.0.1:21420/mcp - Rust (Axum) HTTP server receives the request
- Request is forwarded to the Svelte frontend via Tauri event
- Frontend executes the tool and returns results
- Response flows back to the AI client
MCP Setup
1. Enable the server
In Napkin, click the Settings gear icon in the header bar, then toggle Enable MCP Server. The server listens on port 21420. The setting persists across sessions.
2. Configure your AI client
For Claude Code, add to your .claude.json or project MCP settings:
{
"mcpServers": {
"napkin": {
"type": "url",
"url": "http://127.0.0.1:21420/mcp"
}
}
}
3. Use it
Ask Claude to "draw a diagram in Napkin" or "create a flowchart". The AI agent will use the MCP tools to create shapes, connect them, and arrange the canvas.
MCP Tool Reference
All tools are called via JSON-RPC tools/call method. 22 tools are available:
get_canvas — Get full canvas state
Returns all shapes, viewport position/zoom, and group information.
Parameters: none
list_shapes — List shapes on the canvas
| Param | Type | Description |
|---|---|---|
type | string? | Filter by shape type: rectangle, ellipse, triangle, diamond, hexagon, star, cloud, cylinder, sticky, line, arrow, freedraw, text |
get_shape — Get a shape by ID
| Param | Type | Description |
|---|---|---|
id | string | Shape ID (required) |
create_shape — Create a new shape
| Param | Type | Description |
|---|---|---|
type | string | Shape type (required): rectangle, ellipse, triangle, diamond, hexagon, star, cloud, cylinder, sticky, text |
x | number | X position (required) |
y | number | Y position (required) |
width | number? | Width (default: 200) |
height | number? | Height (default: 150) |
strokeColor | string? | Stroke color (default: #000000) |
strokeWidth | number? | Stroke width (default: 2) |
fillColor | string? | Fill color (default: transparent) |
fillStyle | string? | hachure, solid, zigzag, cross-hatch, dots |
strokeStyle | string? | solid, dashed, dotted |
opacity | number? | 0 to 1 (default: 1) |
roughness | number? | 0 to 3 (default: 1) |
rotation | number? | Degrees |
text | string? | Text content |
fontSize | number? | Font size for text shapes (default: 20) |
stickyColor | string? | Sticky note background color |
update_shape — Update shape properties
Pass id (required) plus any properties to change. Accepts the same optional properties as create_shape.
delete_shape — Delete a shape
| Param | Type | Description |
|---|---|---|
id | string | Shape ID to delete (required) |
create_image — Add an image to the canvas
| Param | Type | Description |
|---|---|---|
url | string | HTTP/HTTPS URL or base64 data URL (required) |
x | number? | X position (default: 0) |
y | number? | Y position (default: 0) |
width | number? | Width (auto-calculated if omitted) |
height | number? | Height (auto-calculated if omitted) |
create_connection — Connect two shapes with a line or arrow
| Param | Type | Description |
|---|---|---|
fromShapeId | string | Source shape ID (required) |
toShapeId | string | Target shape ID (required) |
connectionType | string? | arrow (default) or line |
routingMode | string? | direct (default), elbow, or curved |
text | string? | Label text on the connection |
strokeColor | string? | Line color |
strokeWidth | number? | Line width |
Connections created with this tool are bound to their source and target shapes — they stay connected when shapes are moved, resized, or rotated.
set_viewport — Pan and zoom the canvas
| Param | Type | Description |
|---|---|---|
x | number? | Pan X offset |
y | number? | Pan Y offset |
zoom | number? | Zoom level (0.1 to 10) |
select_shapes — Select shapes by ID
| Param | Type | Description |
|---|---|---|
ids | string[] | Array of shape IDs (required) |
batch_operations — Batch create/update/delete
| Param | Type | Description |
|---|---|---|
operations | array | Array of { action, data } objects (required) |
Each operation has action ("create", "update", or "delete") and data (shape properties for create/update, or { id } for delete).
Note: Use create_connection for arrows that need to bind to shapes. Arrows created via batch_operations are positioned by coordinates but not bound.
list_tabs — List all open tabs
Parameters: none
create_tab — Create a new tab
| Param | Type | Description |
|---|---|---|
title | string? | Tab title (default: "Untitled") |
switch_tab — Switch to a tab
| Param | Type | Description |
|---|---|---|
tabId | string | Tab ID (required) |
rename_tab — Rename a tab
| Param | Type | Description |
|---|---|---|
tabId | string | Tab ID (required) |
title | string | New title (required) |
group_shapes — Group shapes together
| Param | Type | Description |
|---|---|---|
ids | string[] | Shape IDs to group (minimum 2, required) |
ungroup — Ungroup a shape group
| Param | Type | Description |
|---|---|---|
groupId | string | Group ID (required) |
clear_canvas — Clear all shapes
Parameters: none. Removes all shapes from the active canvas.
bring_to_front — Move shape to front of z-order
| Param | Type | Description |
|---|---|---|
id | string | Shape ID (required) |
send_to_back — Move shape to back of z-order
| Param | Type | Description |
|---|---|---|
id | string | Shape ID (required) |
bring_forward — Move shape one step forward in z-order
| Param | Type | Description |
|---|---|---|
id | string | Shape ID (required) |
send_backward — Move shape one step backward in z-order
| Param | Type | Description |
|---|---|---|
id | string | Shape ID (required) |
reorganize — Auto-layout shapes on the canvas
| Param | Type | Description |
|---|---|---|
algorithm | "grid" | "force-directed" | Layout algorithm (required) |
shapeIds | string[] | Shape IDs to reorganize (omit for all shapes) |
padding | number | Padding between shapes for grid layout (default: 40) |
iterations | number | Iterations for force-directed layout (default: 100) |
set_snap_settings — Configure snapping behavior
| Param | Type | Description |
|---|---|---|
snapToGrid | boolean | Enable/disable snap to 20px grid |
alignmentHints | boolean | Enable/disable alignment guide lines |
objectSnap | boolean | Enable/disable magnetic snap to aligned shapes |
File Format
Napkin saves files as .napkin — plain JSON that is easy to version control, diff, and script against.
A collection file contains multiple tabs:
{
"napkin": "1.0",
"documents": [
{
"title": "Tab 1",
"shapes": [...],
"viewport": { "x": 0, "y": 0, "zoom": 1 },
"metadata": { ... }
}
],
"activeDocumentIndex": 0
}