LeCodesdocs

LeCodes Design

A canvas for designing an app before it exists. Every screen is a file — design/screens/<id>.ts — live and executable; meta.json ties the screens into a flow map. lecodes design opens the board in the browser: screens render for real, and the selected one is interactive.

It's built for a human + AI pair: the assistant writes screens as code and looks at the result itself; you watch the board, move things, connect them and edit. This is the intent-capture stage — screens run on inline mock data, before any backend exists.

Setup & first board

The canvas is an optional package next to the CLI. It works inside a cloned project or standalone in any folder — no login needed:

bash
npm i -D lecodes-design lecodes-renderer
lecodes design init   # scaffold: screens/, shared/, meta.json, spec.md, CLAUDE.md
lecodes design        # dev server + the board in your browser (port 4477)

init also writes the SDK types and a tsconfig.json (IntelliSense in screen files) and registers the board's MCP server in .mcp.json, so Claude Code sees its tools right away. lecodes-renderer powers headless rendering — the snapshot command and the render_screen MCP tool.

The board

Screens hot-reload as you save files, and everything you do on the board is written back to the files:

  • Drag an unselected screen — the position lands in meta.json. Click to select a screen and it becomes interactive: taps, scrolling and typing work.
  • Pull the connect handle onto another screen to draw a flow edge; click an edge to edit its label and activator (the element that triggers the transition) or delete it.
  • Double-click any text to edit it in place — the string literal is rewritten right in the screen's source. Double-click an image (or drop a file from your OS) to replace it: the file is stored in design/assets/ and the asset() path is rewritten.
  • H — hint mode: outlines interactive elements, editable texts and replaceable images.

Screens in meta.json can be gathered into groups (rendered as labeled regions) and tagged with a role (list, form, auth, …) — on a big board that's the only way to stay oriented.

Screens are code

The rules are simple, and they're exactly what makes the design AI-friendly:

  • One file = one screen. screens/<id>.ts default-exports a UIScreen; the filename is the screen's identity.
  • Screens are islands. They import only from shared/ (tokens, shared components) — screens don't know about each other; every relationship lives in meta.json.
  • Mock data is the domain. Realistic data at the top of the file is the first draft of the future schema; entities that stabilize graduate to spec.md — the narrative half of the design (data model, actors, rules).
  • Screen states aren't separate files but a function of a string-literal union; the union IS the state list:
TypeScript
export default (state: "default" | "empty" = "default") => UIScreen([
  Header(),
  state === "empty" ? EmptyState("Nothing here yet") : UIScrollable(items.map(Card)),
])
  • Icons go through the compile-time macro assetIcon("lucide:bell"): the SVG is vendored at build time, so screens render offline and deterministically.

Working with an AI assistant

init drops a CLAUDE.md into the folder — the conventions spec, written for the assistant — and registers the board's MCP server. While the server runs, Claude Code has the tools: render_screen (what a screen actually looks like — JSON or PNG), check_screens (a fast compile check), design_state (the live screens and edges), check_concept (coherence between spec.md and the screens) and board_activity (what you just did on the board). The assistant builds a screen, renders it, spots problems and fixes them — before showing you.

When the server is down, the same is available from the CLI:

bash
lecodes design snapshot home --png   # headless-render a screen → JSON/PNG
lecodes design check                 # coherence: edges, states, spec.md links
lecodes design arrange --new         # place new screens next to their flow neighbours

Sharing the design

Inside a cloned project the design pushes with the rest of the files (lecodes push), and lecodes design share turns on a public link: anyone with it sees the working mockups — your app code stays private. Turn it off with lecodes design share --off.