# pablostanley/squig: shadcn components drawn as a napkin sketch

> An MIT licensed wireframing canvas where real shadcn/ui components render as hand-drawn sketches, kept entirely in browser storage with no accounts and no database. The interesting part is the mechanism underneath: components never reach the DOM, they return drawing primitives, and groups are paths stamped on a flat node map rather than containers.

**pablostanley/squig** — Wireframing tool where real UI components render as hand-drawn sketches

- Repository: https://github.com/pablostanley/squig
- Website: https://squig.sh
- Stars: 78 · Forks: 16
- Language: TypeScript
- License: MIT
- Published: 2026-08-24 · Updated: 2026-08-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/pablostanley-squig

## Nothing renders to the DOM, components return primitives

No component in this project ever becomes DOM. Each one is a `ComponentDef` whose `render()` returns an array of drawing primitives, named rect, line, text and icon among them, and the canvas draws those through rough.js into SVG. That single indirection is what makes three unrelated features cheap at once: previews in the component panel, the thumbnails in the ⌘K sheet, and break-apart all reuse the exact same primitives the canvas itself draws, so a preview cannot drift away from the result. Icons are the deliberate exception to the sketchy treatment. They are Phosphor paths rendered crisp rather than roughened, because at 14px the wobble reads as mush instead of as style. Extending the library means writing a `ComponentDef` and adding it to an array, with lib/library/AUTHORING.md as the guide, which the project also names as the easiest place for a new contributor to start.

## Groups are paths stamped on a flat map, not containers

Documents are a flat map of nodes on an infinite plane, and a node is one of five things: a component instance, a shape, a freehand stroke, text, or an arrow. Hierarchy exists, but it is not structural. Groups and subgroups are paths stamped onto those nodes rather than container nodes, which means there is still no layout nesting and no flow layout anywhere in a document: a group records an address, it does not own children the way a parent element would. The keyboard side follows from that design. `⌘G` and `⇧⌘G` group and ungroup, groups can nest, and ungrouping detaches an instance. `⌘`-click deep-selects and a double-click steps one level into a group, so you walk down a path rather than reaching into a subtree. `⌥⌘B` detaches an instance outright, which is the harder version of the same move.

## Break apart is deliberately one-way

Everything on the canvas is a component with variants, and the inspector switches among them instead of editing shapes. Drop a button and it flips to icon left, icon right, size, filled or outline, and it stays a component for the whole process. That is what keeps a library of real UI parts meaningful on a sketchy canvas instead of decaying into loose rectangles after the first edit. When no variant covers what you want, you break the component apart and its pieces become editable primitives. The README calls that transition one-way on purpose, and there is no reassembly path back into the library. `⌥⌘B` is the other exit of the same kind. The trade is deliberate: the two modes never blur into each other, at the price of making some explorations a one-time expense rather than a repeatable one.

## The drawer holds forty documents and forgets the rest

Files never leave the browser. Every document autosaves as you draw, the file menu keeps a list of recent ones to open again, and New file starts a new document rather than painting over the last one, so a stray click does not destroy the thing you were drawing. The drawer holds the last forty, and past that, and when the browser runs out of room, the oldest ones go. That eviction rule is the real cost of the local-only design, and having no accounts and no cloud does nothing to soften it. Clearing site data clears your files with it, which is the other half of the same problem. `⌘S` saves to this browser and `⇧⌘S` exports a copy, and opening the website in a different browser profile does not bring the drawing along. Anything that matters needs a manual export.

## ⌘K puts tools, actions and the library in one sheet

The component library is the shadcn/ui vocabulary, meaning buttons, inputs, selects, switches, tables, dialogs, tabs, nav and sidebars, plus blocks such as heroes, pricing, FAQ, AI chat, checkout and kanban, and whole screen templates on top of that. All of it is reachable from one sheet opened with `⌘K`, which searches tools, actions, and every component and block, and Enter drops the match into the middle of your view. One behaviour is worth knowing before it surprises you: over a text block, `⌘K` inserts a link instead of opening the sheet, so the shortcut never swallows the keystroke you wanted inside copy. If you would rather browse than type, `⌘C` and `⌘B` open the components and blocks panels directly. The keyboard in general is Figma's, and `?` opens the full list inside the app.

## Paste lands at the pointer, and images shrink on the way in

`⌘V` takes whatever is on the clipboard and puts it where the pointer is, which folds three different jobs into one shortcut: a screenshot to wireframe around, a paragraph of copy, or layers copied out of another squig tab. Images are handled as references rather than decoration. A picture lands as itself inside a drawn frame, on the stated reasoning that a reference you cannot read is no reference at all, and it gets shrunk on the way in so a retina screenshot does not eat the drawer. `⇧⌘V` pastes in place rather than at the cursor, which is the one to reach for when you are rebuilding an existing screen and the original coordinates are the whole point. Everything else in the canvas behaves the Figma way: marquee and multi-select, smart-guide snapping, arrow nudges with a custom big nudge at 10px by default, `⇧0` `⇧1` `⇧2` for 100 percent, fit and selection, and `⌘\` to hide the interface entirely.

## pnpm verify is the gate, and build-xdc is a separate target

The local canvas needs no environment variables, no database and no accounts, because documents live in browser storage. Setup is two commands.

```bash
pnpm install
pnpm dev
```

Testing is run the same way. `pnpm test` type-checks first and then runs every suite under scripts/test-*.ts, and `pnpm test crop text` runs just the suites whose names match, which is how you narrow in on one area. `pnpm verify` is lint, test and build in one go, and it is what the project tells you to run before pushing. package.json pins pnpm@10.4.1 as the package manager, and the package itself is version 0.1.0 and marked private, so there is no published artifact to install from a registry. The Makefile wraps those commands with help as its default goal, listing make install, make dev, make build, make build-xdc, make package as an alias for build-xdc, and make clean. build-xdc is the strange one: a static export plus a Webxdc archive written to dist/squig.xdc, packaged as a fully offline Delta Chat mini-app. It refuses to run without zip, wipes out/ first so a stale file from an earlier build cannot be sealed into the archive, and fails with static export missing out/index.html or missing out/manifest.toml when the export did not produce them. The archive deliberately excludes webxdc.js because the host injects that global itself.

## Two ways to let an agent in: the open tab, or a file on disk

Connect agent copies instructions for an agent that already has access to the browser tab you have open. It checks the document ID and edits through `window.squig` or supported WebMCP tools, human and agent edits appear together, and everything saves automatically in browser storage. No download, installation or companion is needed for that path. The other path targets a chosen `.squig.json` file: an optional companion runs on your own computer, opens the full editor at a loopback address, and exposes MCP and HTTP tools for that file, with components, batch edits, variations, notes, comments, history, text measurement, and SVG and PNG rendering all running locally. From a clone, that path needs Node.js 24 and pnpm 10.

```bash
pnpm install --frozen-lockfile
pnpm build:local
pnpm squig serve /absolute/path/homepage.squig.json
```

You then open the local editor URL the command prints and use Connect agent for the session. The directory layout follows the same split: components/agent/ covers connecting an agent and staying in sync, app/mcp/route.ts explains the move to local MCP, and app/api/v1/ is read-only recovery of old online canvases.

## Conclusion

Squig fits early layout work where the question is which arrangement of real parts works, not whether a corner radius is right, and it fits teams that can live with forty documents in one browser profile. It does not fit work that needs shared editing accounts, version history beyond session undo, or durable storage without an explicit export. Before you commit, note that the package is version 0.1.0 and marked private with pnpm 10.4.1 pinned, that breaking a component apart cannot be undone, and that the repository has no GitHub releases even though the last push to main is dated 2026-09-14.

## FAQ

### What is squig, the wireframing tool?

squig is a wireframing tool on an infinite canvas where real UI components render as hand-drawn sketches. It positions itself between Figma, which pulls you toward high fidelity, and drawing every button from scratch, and it is MIT licensed with the hosted version at squig.sh.

### Which components does squig ship?

The shadcn/ui vocabulary, so buttons, inputs, selects, switches, tables, dialogs, tabs, nav and sidebars, plus blocks such as heroes, pricing, FAQ, AI chat, checkout and kanban, and whole screen templates. ⌘K searches tools, actions, and every component and block in one sheet.

### Where does squig keep my files?

In your browser. Every document autosaves as you draw, the file menu keeps a list of recent ones, and the drawer holds the last forty before the oldest ones go. There are no accounts and no cloud, so clearing site data clears the files and ⇧⌘S exports a copy.

### How do I run squig locally?

From a clone, pnpm install and then pnpm dev. The local canvas needs no environment variables, database or accounts. pnpm verify runs lint, test and build in one go, and the project calls it the thing to run before you push.

### How do agents edit a squig canvas?

Connect agent copies instructions for an agent with access to the browser tab you already have open; it checks the document ID and edits with window.squig or supported WebMCP tools. For a chosen .squig.json file, the optional companion instead runs on your own computer at a loopback address.

## Sources

- [Official documentation](https://squig.sh)
- [Official README](https://github.com/pablostanley/squig#readme)
- [Project repository](https://github.com/pablostanley/squig)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/pablostanley-squig
