Velloo documentation
Markdown for LLMs ↗The design folder
The on-disk format, covering screens, boards, snippets, theme, assets, config, and sidecars. Pure local data, optionally versioned with Git.
A Velloo design is a folder. Not a proprietary file, not a database, not a cloud document: a directory of JSON that lives anywhere on disk. Keep it in your app repo or elsewhere; the folder remains the unit either way.
The layout
my-product/
├── apps/web/ # your real app, untouched
└── velloo/ # the design "file" (a folder)
├── .design/
│ ├── config.json # tool version, library declaration, viewport presets, codegen options
│ └── cache/ # gitignored: runtime state, screenshots, build artifacts
├── theme/
│ ├── default.json # unified tokens (colors + explicit colorsDark, fonts, typesets, spacing, radius)
│ ├── Night Shift.json # optional: a named theme, saved under the name you gave it
│ └── custom.css # optional escape-hatch CSS, injected into every render
├── snippets/ # reusable subtrees with typed params
│ ├── elsewhere-destination.json
│ └── elsewhere-metric.json
├── assets/ # imported images and SVGs, served at /assets/<name>
├── assets.json # optional: prompts and provenance for generated assets
├── screens/ # one file per screen, plus optional annotation sidecars
│ ├── elsewhere-discover.json
│ ├── elsewhere-stay.json
│ └── elsewhere-discover.annotations.json # sidecar: node-anchored markdown
├── boards/ # one file per board, plus optional note sidecars
│ ├── main.json # frames (placements of screens) + groups + optional flow arrows
│ ├── elsewhere-details.json
│ └── elsewhere-details.notes.json # sidecar: free-positioned markdown notes
├── guidance.md # optional: the design's rules in words (Overview, Do's and Don'ts)
├── preview.tsx # optional: providers + global CSS your own components need
├── repo-components.json # optional: corrections to discovered app components
├── ASSET-SOURCES.md # welcome sample only: where its photographs came from
├── README.md # written by init: a guide for you and your agent
└── .gitignore # ignores .design/cache/ and .velloo/
The file names above come from the Elsewhere welcome sample; a blank folder starts with empty screens/, boards/, snippets/, and assets/ directories.
What each part is
.design/config.jsonis the folder’s contract with the tool: schema and tool versions, the library declaration (which framework this folder targets and where its components come from), declared extensions, viewport presets, board order, and codegen hints likecomponentsAlias. Full field reference in Config..design/cache/holds daemon runtime state: the running daemon’sruntime.jsonrecord, screenshots, build artifacts. Regenerated on demand, gitignored, safe to delete.theme/holds the token tree (default.json, plus any named themes) and the optionalcustom.cssescape hatch. A named theme’s file is its name as typed, so “Night Shift” istheme/Night Shift.json.screens/holds one JSON file per screen: an id, a name, and one tree of nodes.boards/holds one JSON file per board: frames and groups. Layout data only; never emitted as code. Two optional fields are newer:edgeson a board holds its flow arrows:[{ from, to, label?, state?, labelAt? }], frame id to frame id, at most one per ordered pair.labelAtis layout only: where along the arrow its label was slid to on the canvas. A board with no arrows has noedgesfield, and an arrow whose frame is gone is dropped on the next write.fit: "content"on a frame means its height follows its screen. A frame without it keeps the height it was given.
guidance.mdholds the design’s rules in words, in two sections:OverviewandDo's and Don'ts. The canvas’s Design language stage and theset_design_languageoperation write it, and agents read it before composing. A design that follows a repositoryDESIGN.mdhas no need for one. See Themes.snippets/holds one JSON file per snippet: typed params plus a body tree.assets/: images and SVGs the agent uploads viaupload_assetorimport_assets(or generates withgenerate_asset), referenced from screens as/assets/<name>.assets.jsoncarries provenance for generated images: the prompt, intent, aspect, and timestamp, keyed by asset path (assets/hero.png). The canvas uses it to show an Image node’s prompt and offer regeneration, andlist_assetsreturns it. Assets without an entry simply weren’t generated by Velloo. A missing or corrupt file only means no provenance; it never blocks the folder from loading.preview.tsxis the preview entry: the module whose default export wraps your app’s own components in the providers and global CSS they need when the canvas mounts them. Optional — a folder whose app has no components of its own, or whose library has a built-in recipe, doesn’t need one. In a monorepo,preview.<app>.tsxtargets a named host app. It is the one file here that is code rather than data, and the only one Velloo executes — in your local browser, never in the cloud.repo-components.jsonholds checked-in corrections to what component discovery inferred: a better description, extra preview states, a proxy snippet, or an exclusion. Overrides refine discovery rather than replacing it, and a key that stops matching is reported as stale.ASSET-SOURCES.mdis not a Velloo format file.velloo initwrites it with the welcome sample to credit the sample’s photographs and explain that itsassets.jsonprompts are seeded demo metadata.
There is no node_modules, no lockfile, no build step, and, pointedly, no components/ directory. Components come from the framework provider or from your app itself, so the folder stays essentially pure data and there’s never a second button.tsx competing with your app’s for source-of-truth. preview.tsx is the deliberate exception: a fixture that points at your components, not a copy of them.
Sidecars
Two kinds of human/agent commentary live next to the data they describe, not inside it:
- Annotations: markdown anchored to specific nodes within a screen, at
screens/<screenId>.annotations.json. Agents read them withlist_annotationsand write them withadd_annotation/update_annotation/remove_annotation. - Canvas notes: markdown notes, free in board coordinates or attached to a node, at
boards/<boardId>.notes.json. Readable and writable by agents (list_notes/add_note/update_note/remove_note), good for tour steps, review remarks, handoff context.
Sidecars are tidy by construction: persisting an empty array deletes the file, so the directory never accumulates husks. Codegen ignores both kinds.
History is your choice
Velloo has no proprietary document history or merge server. When a design is under Git, it restores byte-identically from any commit: review a change as a diff, branch an exploration, or revert a bad direction. The .design/config.json records the toolVersion that created the folder so a newer binary can offer an upgrade path.
Velloo uses Git without depending on it: it never commits or reverts for you, and a folder outside any repository works the same. A design kept outside your app’s repository, whether in Velloo-managed storage (velloo init --external, under ~/.velloo/designs) or a directory you chose, is a local design: recorded only on your machine, never in the repository’s velloo.json, and not versioned unless you run git init in that folder yourself.
Two consequences worth internalizing:
- If you version a design, commit the whole folder: screens, boards, snippets, theme, assets,
assets.json, and — when present —guidance.md,preview.tsx, andrepo-components.json. Those last two are how a teammate’s canvas renders your app’s components the same way yours does. Only.design/cache/and.velloo/(trace tapes) are ignored; the shipped.gitignorealready covers them. - Write through the tools, read however you like. The JSON is deliberately readable and diffable, but mutations should flow through the canvas or the MCP tools: they hold the folder’s locks, validate against the schema, keep the watcher and undo history coherent, and broadcast changes to every open canvas. Hand-editing a screen file while a daemon is running invites the watcher to fight you.
Next
- What a screen tree is made of: Nodes.
- The config file in full: Config reference.