The CLI
The windo bin is the zero-config way in. Point it at the folder that holds your windo.config.ts and *.windo.tsx files and it boots a Vite dev server — already wired with the windo plugin — and prints the URL. You own no vite.config.ts; the CLI carries all of it. When you're ready to share the canvas, the same bin builds it to static files.
One command, no Vite config
The Vite plugin is the engine: it pairs @vitejs/plugin-react with windo, serves the workbench chrome and the preview iframe, and discovers your windos. The CLI exists so you don't have to assemble that yourself. Under the hood it calls Vite's createServer with windoPlugin already in the plugins array, then listens — so there's nothing for you to configure when all you want is to look at your components.
Reach for the plugin directly only when windo has to share a Vite config with something else (an existing app, custom resolve aliases, extra plugins). Otherwise the bin is the whole story.
Running it
The package installs a windo bin. The first positional argument is the command — dev (the default), build, or preview. With no command, dev is implied, so these two lines are equivalent:
windo # 'dev' is implied windo dev
The next positional is the root — the directory Vite treats as the project base, and where windo looks for windo.config.ts and every *.windo.tsx matching your config's include glob. Omit it and the root is your current working directory; pass one to scope discovery to a subfolder.
windo dev # root = cwd windo dev ./src # root = ./src
Most projects don't run the bin globally — they pin it in a package script so the whole team gets the same command. The dependency lives in devDependencies and the script invokes the local bin.
{
"scripts": {
"windo": "windo dev ./src --port 6006"
},
"devDependencies": {
"@westopp/windo": "^0.1.0"
}
}Flags
Everything after the root is options. They map onto the dev server Vite spins up.
windo dev ./src --port 6006 --open windo dev --host windo dev --config ./tools/windo.config.ts
-p, --port <n>sets the port to listen on. Without it, Vite picks its default (5173, or the next free port).--host [host]exposes the server on your network so another device can reach the workbench. Pass it bare to bind every interface, or give it a specific host.-o, --openopens the workbench in your browser as soon as the server is ready.-c, --config <p>points at awindo.config.tssomewhere other than the root — useful when your config lives outside the directory you're serving.-h, --helpprints usage and exits without starting anything.
Building a static canvas
windo build compiles the workbench to a folder of static files — the chrome, the preview iframe, and every windo, bundled and hashed. The result is a plain windo-static/ you can drop on any static host (Netlify, Vercel, GitHub Pages, S3, a bare file server) to share the canvas with people who aren't running it locally.
windo build # build cwd → ./windo-static windo build ./src # build a subfolder root windo build -d out # write to ./out instead windo build -b /canvas/ # set a non-root public base
It writes index.html at the root of the output and the preview document at __windo/iframe.html. The output directory defaults to windo-static/ — not dist/ — so a windo build never clobbers the dist/ your own app's build already owns. The public base defaults to ./ (relative), so the bundle works unchanged whether it's served from a domain root or a subpath — you don't rebuild to move it. Pass -b, --base to pin an absolute base when a host needs one.
-d, --outDir <p>— output directory. Defaults towindo-static.-b, --base <p>— public base path. Defaults to./.-c, --config <p>— path towindo.config.ts, same asdev.
The build is self-contained: it does not read a vite.config.ts from your project, so the canvas never inherits an unrelated app's config. Reach for the plugin + vite build directly when you want that control.
Previewing a build
windo preview serves a built windo-static/ locally — the same files a static host would serve, on a local URL — so you can check it before you deploy.
windo build && windo preview windo preview -d out --port 6006 --open
It takes -d, --outDir (which folder to serve, default windo-static) plus the same --port, --host, and --open flags as dev. Run build first — preview only serves what's already on disk, it doesn't compile.
Where next
- The Vite plugin — what the CLI boots for you, and how to wire
windoPlugininto your own Vite config when you need to. - Writing a windo — author the
*.windo.tsxfiles the dev server discovers and previews.