Skip to content

Prototypes

nib's prototype pipeline turns .pen design files into shareable HTML prototypes — complete with hotspot navigation, device frames, and offline-ready bundles.

How It Works

.pen file  →  MCP (Pencil.dev)  →  DesignDocument JSON  →  HTML Prototype
    ↓                ↓                       ↓                     ↓
 your design    reads nodes,           intermediate           styled pages,
                variables &            contract               canvas nav,
                assets inline          (resolved,             device frame
                                       no refs)               (optional)

The pipeline has two stages:

  • Capture — reads the .pen file via the Pencil.dev MCP server, resolves all component references inline, and outputs a self-contained DesignDocument JSON.
  • Build — transforms the DesignDocument into HTML using the chosen template. Works fully offline from the JSON snapshot.

What Requires Pencil Open

This is the most important thing to understand about the pipeline:

CommandPencil open?Why
nib captureYesReads live node tree, variables, and assets from the running editor
nib prototypeYesRuns capture internally
nib devYesRe-captures on every file save
nib brand pushYesWrites variables into the open file
nib brand importYesReads variables from the open file
nib pencil openYesTells Pencil to open a file
nib buildNoReads a .design.json snapshot — pure file I/O
nib brand init/build/auditNoToken generation — no design tool involved

Rule of thumb: If the command touches a .pen file directly, Pencil must be open. Everything that operates on a .design.json snapshot is fully offline.

Quick Start

sh
# Full pipeline: .pen → HTML in one command
nib prototype my-design.pen

# With a device frame and presentation template
nib prototype app.pen -t presentation -d "iPhone 16 Pro"

# Standalone output — embed all assets for sharing
nib prototype app.pen --standalone -o dist/

MCP Required

nib prototype (and nib capture) need a running Pencil.dev instance with its MCP server accessible. nib build works fully offline from a .design.json snapshot.

Three Modes

prototype — Full pipeline

The default. Runs capture + build in sequence. Use this when you have Pencil.dev open and want to go from .pen to HTML in one step.

sh
nib prototype my-design.pen

capture + build — Split pipeline

Run the stages separately. Useful for CI/CD: capture once, then rebuild the HTML as many times as you need without re-reading the .pen file.

sh
# Stage 1: capture from Pencil.dev (requires MCP)
nib capture my-design.pen -o snapshots/my-design.design.json

# Stage 2: build HTML from snapshot (offline, no MCP)
nib build snapshots/my-design.design.json -t presentation

The .design.json snapshot is version-controllable — commit it to run nib build in CI without Pencil.dev.

dev — Live reload

Start a local dev server that watches your .pen file and rebuilds on changes. Ideal for rapid iteration.

sh
nib dev my-design.pen

Opens a browser automatically at http://localhost:3142. Change your design in Pencil.dev, save, and the browser refreshes.

Templates

clean (default)

Minimal prototype viewer. Canvas thumbnails on the left, full-size canvas on the right. Best for:

  • Design handoff and review
  • Developer reference
  • Quick sharing
sh
nib prototype my-design.pen -t clean

presentation

Slide-style viewer with keyboard navigation ( / ) and smooth transitions. Best for:

  • Stakeholder presentations
  • Walkthroughs and demos
  • Pitch decks
sh
nib prototype my-design.pen -t presentation

List all available templates:

sh
nib templates

See the Templates overview for a visual comparison of both templates.

Device Frames

Wrap your prototype in a realistic device bezel to simulate the target platform. Pass any device name from nib devices:

sh
# Mobile
nib prototype app.pen -d "iPhone 16 Pro"
nib prototype app.pen -d "Pixel 9"

# Tablet
nib prototype app.pen -d "iPad Pro 11\""

# Desktop
nib prototype app.pen -d "MacBook Pro 14\""

List all available devices and their dimensions:

sh
nib devices

Offline & CI

nib build works entirely from a .design.json snapshot — no MCP, no Pencil.dev, no network.

Workflow for CI/CD:

  1. Capture once locally (Pencil must be open for this step only):

    sh
    nib capture my-design.pen -o design-snapshots/my-design.design.json
  2. Commit the snapshot to your repo.

  3. In CI, run nib build to regenerate HTML on every push — no Pencil, no MCP:

    sh
    nib build design-snapshots/my-design.design.json --standalone -o dist/

The --standalone flag embeds all assets (CSS, fonts, images) into a single self-contained HTML file — no external dependencies, no server required.

One capture, many builds

You only need Pencil open when your design changes and you want to re-capture. Iterating on templates, device frames, or hotspot links only requires nib build — which is instant and offline.

Wire up navigation between screens so your prototype is clickable end-to-end. Pass a links array to nib build (or nib prototype):

sh
# Via nib.config.json
nib build my-design.design.json --config nib.config.json

nib.config.json example:

json
{
  "links": [
    { "from": "Home", "nodeId": "btn-signup", "to": "Signup", "transition": "slide-left" },
    { "from": "Signup", "nodeId": "btn-back",  "to": "Home",   "transition": "slide-right" }
  ]
}

When using the MCP tool, pass links inline — nib writes the config file for you:

nib_build_prototype {
  "input": "my-design.design.json",
  "links": [
    { "from": "Home", "nodeId": "btn-signup", "to": "Signup", "transition": "slide-left" }
  ]
}

Finding node IDs

After nib capture, the .design.json contains every node with its id field. Each node looks like:

json
{
  "id": "btn-signup",
  "name": "Sign Up Button",
  "type": "rectangle",
  "x": 120, "y": 340,
  "width": 160, "height": 44
}

To find IDs, open the .design.json file and search for the element's display name — the id field next to it is what you pass to nodeId in your links config.

You can also see the IDs printed in the nib capture output summary — it lists all top-level canvases and their direct children with IDs.

Opening Files in Pencil

Use nib pencil open to open a file in Pencil from the terminal — useful for first-time setup or switching between files in a script.

sh
# Open an existing .pen file
nib pencil open docs/design/system/design-system.pen

# Create a blank canvas in Pencil
nib pencil open new

# Check whether Pencil is running and MCP is responding
nib pencil status

After nib pencil open new, Pencil opens a blank canvas. Save it where you want (Cmd+S), then push your tokens into it:

sh
nib brand push --file docs/design/system/design-system.pen

Canonical file path

nib uses docs/design/system/design-system.pen as the conventional path for your design system file. It's set in .nib/brand.config.json under platforms.penFile and created automatically by nib brand push if it doesn't exist yet.

Try It Yourself

Running from source vs installed

The steps below use bun src/cli/index.ts — this is the in-repo dev path for contributors. If you installed nib globally (npm install -g usenib), replace bun src/cli/index.ts with nib in every command.

Run this walkthrough inside the nib repo — no external setup needed beyond a running Pencil.dev instance.

1. Open a .pen file in Pencil

Have Pencil.app running with a .pen file open. You can open a file from the terminal:

sh
nib pencil open my-design.pen   # open existing file
nib pencil open new             # blank canvas
nib pencil status               # confirm Pencil is responding

2. Capture to JSON

sh
bun src/cli/index.ts capture my-design.pen -o my-design.design.json

Inspect the output — you'll see all canvases, nodes, variables, and assets resolved inline with no component references.

3. Build an HTML prototype

sh
bun src/cli/index.ts build my-design.design.json

Open prototype/index.html in a browser to see the result.

4. Try the presentation template

sh
bun src/cli/index.ts build my-design.design.json -t presentation -o dist/

Open dist/index.html and use / to navigate between canvases.

5. Add a device frame

sh
bun src/cli/index.ts build my-design.design.json -d "iPhone 16 Pro" -o dist-mobile/

6. Run the full pipeline in one step

sh
bun src/cli/index.ts prototype my-design.pen -t presentation -d "iPhone 16 Pro" --standalone -o dist/

7. Start the dev server

sh
bun src/cli/index.ts dev my-design.pen

Make a change in Pencil.dev, save, and watch the browser update automatically.

Offline after first capture

Steps 1, 2, 6, and 7 require Pencil open. Steps 3–5 work fully offline from the captured .design.json — no Pencil, no MCP, no network.

Released under the AGPL-3.0 License.