CLI workflow
The Windmill CLI provides commands to scaffold, develop and deploy full-code apps entirely from your terminal.
Create a new app
wmill app new
The interactive wizard prompts for:
- Summary: short description of the app
- Path: app path (e.g.,
f/folder/my_app) - Framework: React 19, React 18 or Svelte 5
- Data configuration: optional datatable and schema setup
This creates a directory with the .raw_app suffix (or __raw_app if nonDottedPaths: true is set in wmill.yaml):
f/folder/my_app.raw_app/ # or my_app__raw_app/
├── raw_app.yaml
├── package.json
├── index.tsx
├── App.tsx
├── index.css
├── AGENTS.md
├── CLAUDE.md
├── DATATABLES.md
├── backend/
│ ├── a.yaml
│ └── a.ts
└── sql_to_apply/
└── README.md
After scaffolding, install dependencies:
cd f/folder/my_app.raw_app # or my_app__raw_app
npm install
Start the dev server
From inside the app directory:
cd f/folder/my_app.raw_app # or my_app__raw_app
wmill app dev
Options
| Option | Description |
|---|---|
--port <number> | Dev server port (default: 4000) |
--host <string> | Dev server host (default: localhost) |
--entry <string> | Entry point file (default: index.tsx or index.ts) |
--no-open | Don't auto-open the browser |
Dev server features
- Hot module replacement: frontend changes reload instantly
- WebSocket backend: backend runnables execute on Windmill workers with results streamed back
- Type generation:
wmill.d.tsis regenerated when runnables change - Schema inference: runnable parameter types are inferred without modifying YAML files
- SQL migrations: a modal appears for pending files in
sql_to_apply/
Generate agent documentation
From the app directory:
wmill app generate-agents
Generates or updates:
AGENTS.md: instructions for AI coding agents describing the project structureDATATABLES.md: data table schema documentation
Generate lock files
From the app directory:
wmill app generate-locks
Generates .lock files for each backend runnable that has dependencies (TypeScript, Python, PHP).
| Option | Description |
|---|---|
--yes, -y | Skip confirmation prompt |
--dry-run | Show what would be updated |
--default-ts <bun|deno> | Default TypeScript runtime |
Deploy with sync
Full-code apps are deployed using the standard sync commands:
Push to Windmill
wmill sync push
The push process:
- Reads
raw_app.yamlfor metadata and policy - Loads backend runnables from
backend/ - Collects frontend files (excluding
node_modules,dist,backend/, etc.) - Bundles frontend code with esbuild
- Uploads everything as a multipart request (app JSON + JS bundle + CSS bundle)
Pull from Windmill
wmill sync pull
The pull process:
- Fetches the app definition from the API
- Extracts frontend files to the app directory
- Writes
raw_app.yamlwith metadata - Extracts backend runnables to
backend/with individual.yaml, code and.lockfiles
Typical workflow
# 1. Create a new app
wmill app new
# 2. Install dependencies
cd f/folder/my_app.raw_app # or my_app__raw_app # or my_app__raw_app
npm install
# 3. Develop locally with hot reload
wmill app dev
# 4. Generate lock files before deploying
wmill app generate-locks
# 5. Deploy to Windmill
wmill sync push