Skip to Content
Getting Started

Getting Started

This guide walks you from zero to a rendered canvas, a first edit, and an exported image in under five minutes. You will need:

  • Node.js β‰₯ 20.19
  • A Chromium-based browser (Chrome, Edge, Brave, Arc) β€” for the studio. The CLI itself runs anywhere Node runs.

1. Scaffold a project

npx create-lerret my-canvas

The scaffolder downloads from npm and writes a new project at ./my-canvas/. Total install β€” including Vite and React, downloaded once and cached β€” typically runs in under a minute on a warm broadband connection. No global install is required.

If my-canvas already exists, the scaffolder refuses to overwrite a non-empty directory but is happy to populate an empty one.

You can also use other runners:

pnpm dlx create-lerret my-canvas yarn dlx create-lerret my-canvas bunx create-lerret my-canvas

What you got

my-canvas/ └── .lerret/ β”œβ”€β”€ config.json β”œβ”€β”€ _fonts/ β”‚ └── LerretFixtureMono.woff2 └── social/ β”œβ”€β”€ instagram-square.jsx β”œβ”€β”€ twitter-banner.jsx β”œβ”€β”€ twitter-banner.data.json └── youtube-thumbnail.jsx

The .lerret/ folder is the only thing Lerret cares about. Everything else in the project is yours β€” Lerret never touches files outside it (the separation invariant).

PathWhat it is
.lerret/config.jsonProject-root config. The vars block flows down the cascade as CSS-like variables.
.lerret/_fonts/Reserved folder. Any .woff2 / .woff / .ttf / .otf here is auto-registered as a CSS @font-face rule. Available to every asset by its file name.
.lerret/social/A page β€” top-level non-underscore folders become pages on the canvas.
*.jsxEach component file becomes an artboard. The default export is the primary variant; named exports become extra variants.
*.data.jsonCo-located data file for an asset (here, twitter-banner.data.json). Overrides component props at runtime.

Want a minimal start?

For an empty project β€” just .lerret/config.json with { "vars": {} }, no sample assets:

npx create-lerret my-canvas --no-samples

2. Start the studio

cd my-canvas npx @lerret/cli dev

The Vite dev server boots and your default browser opens to the studio. You should see three artboards on the canvas: a Twitter banner, an Instagram square, and a YouTube thumbnail β€” each rendered at its real pixel dimensions.

Common flags

npx @lerret/cli dev --port 4000 # custom port (default: Vite's default, usually 5173) npx @lerret/cli dev --no-open # don't auto-open the browser npx @lerret/cli dev --folder ./ # explicit project folder (bypasses walk-up)

If you do not pass --folder, the CLI walks up from the current working directory looking for the nearest .lerret/ β€” like git walks up looking for .git/.

3. Edit a component

Open .lerret/social/twitter-banner.jsx in your editor. Find the headline and change it:

// Before <div style={{ fontSize: 80, fontWeight: 800, ... }}> {headline} </div> // After <div style={{ fontSize: 80, fontWeight: 800, ... }}> Hello from my first Lerret canvas </div>

Save the file. The Twitter banner artboard re-renders in under a second. No page reload, no manual rebuild. The watcher detects the change, Vite’s React Fast Refresh swaps the module, and the canvas updates in place.

4. Add a second asset

Create a new file .lerret/social/release-card.jsx:

export const meta = { dimensions: { width: 1200, height: 630 }, label: 'Release card', tags: ['release', 'og'], }; export default function ReleaseCard() { return ( <div style={{ width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'var(--brandColor, #3D5A80)', color: 'white', fontSize: 72, fontWeight: 800, fontFamily: 'system-ui', }}> v1.0 β€” Shipping today </div> ); }

Save it. A new artboard appears on the canvas β€” at exactly 1200Γ—630 β€” alongside the others. The watcher reports an add event, the loader incorporates the new asset into the project model, and the canvas adds the artboard.

Notice the var(--brandColor, #3D5A80). The project-root config.json declares vars.brandColor = "#3D5A80", which the studio exposes as a CSS custom property on the artboard. Change the value in config.json, save, and every artboard re-renders with the new color.

5. Add a variant

Variants are extra components in the same file, exported by name. Add this to release-card.jsx:

export const Dark = () => ( <div style={{ width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#0A0A0A', color: '#E0FBFC', fontSize: 72, fontWeight: 800, fontFamily: 'system-ui', }}> v1.0 β€” Shipping today </div> );

Save. A second artboard appears next to the original β€” labelled Dark β€” also at 1200Γ—630. The meta export is shared across all variants in the file; the default export is the primary variant; each named function export is an extra variant.

Component-valued exports = variants. Non-function exports (constants, the meta object) are ignored.

6. Add data

Lerret can supply props to your component from a co-located data file β€” no code change required.

Create .lerret/social/release-card.data.json:

{ "default": { "label": "v1.0 β€” Shipping today" }, "Dark": { "label": "v1.0 β€” Shipping today (dark mode)" } }

Then accept label as a prop in your component:

export default function ReleaseCard({ label = 'Untitled' }) { return ( <div style={{ /* ... */ }}> {label} </div> ); }

The top-level keys match your variant export names (default, Dark), so each variant gets its own data. This is per-variant data keying. If the top-level keys do not match any export name, the entire data object is applied as shared data to every variant.

There is also a .data.js form when you need computed or conditional data β€” see Authoring Assets for the full mechanics.

7. Export to image files

When you are happy with the canvas, render every artboard to image files from the command line:

npx @lerret/cli export

By default, output goes to ./lerret-export/ (relative to your CWD, never inside .lerret/). Each artboard becomes a PNG, nested under folders that mirror the project’s page/group structure:

lerret-export/ └── social/ β”œβ”€β”€ instagram-square.png β”œβ”€β”€ release-card.png β”œβ”€β”€ release-card-Dark.png β”œβ”€β”€ twitter-banner.png └── youtube-thumbnail.png

Useful flags:

npx @lerret/cli export --format jpg # JPG instead of PNG (jpeg also accepted) npx @lerret/cli export --out ./assets # custom output directory npx @lerret/cli export --flat # all images at one level, no nested folders npx @lerret/cli export .lerret/social # scope: only this page

The CLI boots a headless Chromium through Playwright and uses the same rendering path the in-studio export buttons use, so a lerret export run produces a pixel-faithful match to what the studio captures.

See CLI Reference for the full flag list, including the --data and --config override flags that let you re-render an entire project with different data or theming without modifying any files.

What’s next

  • Concepts β€” the mental model: pages, groups, variants, the four-tier prop cascade.
  • Authoring Assets β€” the full guide to writing components, schemas, data files, and fonts.
  • Examples β€” eight runnable patterns to copy and adapt: OG cards, YouTube thumbnails, repo cards, release graphics, more.
  • CLI Reference β€” every flag and exit code for dev and export.
  • Deployment β€” local CLI, hosted browser, or self-hosted static studio.

Welcome to Lerret.

Last updated on