CLI
- Category: Engine
The point0 CLI ships in @point0/engine. Every command
finds your engine file, imports it, and calls the matching
engine method — point0 dev runs engine.dev(), point0 build runs
engine.build(), and so on. The CLI's own job is small: resolve the
environment, find the engine, parse flags.
// package.json — the scripts a scaffolded app ships with
{
"scripts": {
"dev": "point0 dev --hot",
"generate": "point0 generate",
"build": "point0 build",
// there is NO `point0 start` — production runs the built server directly:
"start": "cross-env NODE_ENV=production bun run ./dist/server/index.server.js",
},
}You rarely type these by hand — they live in package.json and you run them
with bun run dev / bun run build. The rest of this page is one section per
command, then a full flag reference.
point0 dev
Start the dev server and client dev servers. Thin wrapper over
engine.dev().
point0 dev # serve everything
point0 dev --hot # + bun-native server hot reload (the scaffold default)By default dev also generates the src/generated/point0 tree before
serving and watches for changes; pass --no-generate to skip it, --no-watch
to stop restarting on change.
Narrow what runs with --side and --scope:
point0 dev --side server # serve only the server
point0 dev --side client --scope web # one client scopeAnything after -- is forwarded to the spawned bun server process (bun-native
server only):
point0 dev -- --inspect # pass --inspect to the server runtime--hot hot-swaps edited points without restarting the server; cold files (the
@point0/core/cold subtree, the boot entry) still restart. It is
experimental and only affects the bun-native server — the Vite path ignores
it. See Dev for the full restart / hot-reload model.
There is no
point0 stopand no lock file — a running dev tree always sits in a terminal, and the--no-orphansshebang (below) tears the whole process tree down when that terminal dies. See Dev.
point0 build
Build the server and every client for production. Thin wrapper over
engine.build().
point0 build # clean build of server + clients
point0 build --side client # build only the clientsBuild always generates first — there is no "build without generate". It also
forces LOG_MODE=pretty and defaults NODE_ENV to production; building with
any other mode warns and ships unminified, inline-sourcemapped client bundles.
--watch rebuilds on change. With no glob it watches the import graph of
your build entries — no glob needed; a glob value is added on top of that:
point0 build --watch # watch the entries' import graph
point0 build --watch 'src/**/*.css' # + an extra glob--keep-alive holds the process open after a one-shot build, so a long-lived
build plugin (a bundle-analyzer server, say) keeps running until Ctrl-C:
point0 build --keep-aliveOther toggles: --no-clean (skip the pre-build clean), --no-publicdir (skip
copying public assets). Full build flow on Build.
point0 generate
Generate the src/generated/point0 tree — points.server / points.client,
routes, meta, assets.d.ts. Thin wrapper over engine.generate(). This
output is gitignored, so a fresh checkout must run it before typechecking.
point0 generate # generate once
point0 generate --watch # regenerate on changeIt runs as part of every app's setup script:
// package.json
{ "scripts": { "setup": "… && point0 generate && …" } }What each file contains is on Generator.
point0 compile <file>
Print the point0-compiled output of one source file to stdout — useful to see exactly what the compiler strips (server-only code, babel-plugin rewrites).
point0 compile src/pages/home.tsx --side server
point0 compile src/pages/home.tsx -c # -c = --side client--side (or the -c / -s shorthands) picks which side to compile; --scope
is inferred from the side when there is only one. Mode shorthands -p / -d /
-t map to --mode production|development|test. --no-babel strips babel
plugins from the compiler options.
GOTCHA —
-his not help here.compilereassigns help to--helponly, so-his free for--hmr(force the HMR fix on). This is unique tocompile; every other command keeps-has help.
point0 trace <target> <source>
Trace the import chain from a source file to a target import, using the
engine's compiler. Prints each step on its own line.
point0 trace @prisma/client src/pages/home.tsx --side server--side / --scope work as in compile; --cwd overrides the trace root
(defaults to the engine file's directory). Throws Trace was not found when
there is no path from source to target.
point0 prune
Remove point0's temporary directories — the @point0 temp namespace
(node_modules/.cache/@point0) and the server hot-reload store
(node_modules/.cache/server-hot). No flags. Best-effort: errors are swallowed.
point0 prunepoint0 points
Inspect the points your app declares, read from the generated meta.ts. Two
subcommands, both printing JSON. Every invocation needs at least one
--meta <path>.
# list points, with filters / pagination / field selection
point0 points list --meta ./src/generated/point0/meta.ts --type query --limit 20
# get the first point matching the filters
point0 points get --meta ./src/generated/point0/meta.ts --name ideaFilters include --ids / --id, --tags (every tag must match), --scope,
--type, --name, --route / --url, the --endpoint-* trio, --valid /
--ssr booleans, --file, --parent-id, --layout-id, and --fields to
select output keys. list adds --limit (default 100) and --offset (default
0). These are the CLI mirror of the project MCP's list_points /
get_point tools.
point0 docs
Search and read the Point0 documentation offline. Needs the @point0/docs
package installed (bun add -D @point0/docs); the docs and a search index ship
inside it.
point0 docs search "server only imports" # hybrid keyword + semantic search
point0 docs list # table of contents
point0 docs get cli # full markdown of one doc, by slugsearch and list take --limit / --offset; search defaults to 8 results.
This is the CLI mirror of the docs MCP.
The other bins
@point0/engine and @point0/docs also ship MCP servers, and there's a
separate scaffolding CLI. Each has its own page.
point0-project-mcp
An MCP server that exposes your app's points (and compile / trace) to an AI
agent. It reads the generated meta.ts and re-reads it on every call, so it
never serves stale points after a generate.
// package.json
{
"scripts": {
"mcp:project": "point0-project-mcp --meta ./src/generated/point0/meta.ts",
},
}Tools: list_points, get_point, compile, trace. Full setup on
MCP: project.
point0-docs-mcp
An MCP server (shipped in @point0/docs) that serves the Point0 docs to an
agent — list_docs, search_docs, get_doc. No --meta, no project setup; it
runs offline.
// .mcp.json — run the installed copy, matching your point0 version
{
"mcpServers": {
"point0-docs": { "command": "bunx", "args": ["point0-docs-mcp"] },
},
}Full setup, plus the "always latest" variant, on MCP: docs.
create-point0-app
Scaffold a new app. Run it once; it asks for a directory name and a bundler
(Bun or Vite), scaffolds the template, installs deps, and runs
setup.
bun create point0-app my-app # interactive
bun create point0-app my-app --vite --no-interactivebun create point0-app resolves to the create-point0-app bin. Flags: --vite
/ --no-vite, --install / --no-install, -O, --override,
-I, --no-interactive. See Getting started.
How a command runs
Every command does the same three things before it touches your app, in order.
1. Resolve the env mode and load .env files. A command resolves its mode
from flags (--mode, or the -p / -d / -t shorthands where present) and
calls applyEnvMode before importing your engine — your engine reads
process.env at module scope, so the cascade must be loaded first. Precedence:
flag mode > --env NODE_ENV=… > a shell-exported NODE_ENV > the
command's default. The .env cascade (later overrides earlier) is .env,
.env.<mode>, .env.local (skipped in test), .env.<mode>.local; shell
exports always win over files. Defaults: dev / generate / compile /
trace → development, build → production.
point0 build --mode test # load the test cascade
point0 dev --env API_URL=http://localhost # define a var, overrides .env files2. Find the engine file. --engine <path> is explicit; otherwise the CLI
checks POINT0_ENGINE_FILE, then auto-finds a file named engine (.ts /
.js / .tsx / .jsx) in ., ./src, ./lib, and a few point0
subfolders. Not found:
Could not find engine.ts or engine.js file. Searched in: ./, ./src/.
Use --engine <path> to specify the engine file locationThe module must export engine (named) or default, an Engine instance.
3. The hermetic shebang. The bin starts with:
#!/usr/bin/env -S bun --no-orphans --no-env-file --config=/dev/null--no-env-file stops Bun from auto-loading any .env cascade before any CLI
code runs (with NODE_ENV unset it would assume development and load .env +
.env.development); the CLI loads the right-mode cascade itself;
--config=/dev/null keeps your app's bunfig out of the CLI process;
--no-orphans (bun ≥ 1.3.14, no-op on Windows) ties the whole process tree to
its parent — the CLI dies when its launcher dies, even by SIGKILL, and SIGKILLs
every descendant on exit. This is why @point0/engine carries an engines
field, and why each app's bunfig.toml sets [run] noOrphans = true to extend
it to your bun run dev wrapper.
AGENT GOTCHA: because of
--no-orphans, a backgroundedbun run dev &dies the moment the shell that spawned it returns — run it in a real long-lived process, not a throwaway shell.
Reference
Commands
| Command | Wraps | Does |
|---|---|---|
dev | engine.dev() | dev server + client dev servers |
build | engine.build() | production build of server + clients |
generate | engine.generate() | write src/generated/point0 |
compile <file> | Compiler | print compiled output of one file |
trace <target> <source> | Compiler | print import chain source → target |
prune | engine.prune() | remove temp dirs + hot store |
points list / points get | analyzer meta.ts | inspect declared points (JSON) |
docs search / list / get | @point0/docs | search / read the docs offline |
Shared flags
Available across most commands (each command's full set is in its section above).
| Flag | On | Effect |
|---|---|---|
--engine <path> | dev, build, generate, compile, trace | engine file, absolute or relative to cwd |
--mode <mode> | dev, build, compile | production | development | test — picks the .env cascade |
-p / -d / -t | compile | shorthand for --mode production / development / test |
--env <name=value> | dev, build | define a var (repeatable); overrides .env files |
--side <side> | dev, build, compile, trace | server or client |
--scope <scope> | dev, build, compile, trace | one scope (inferred from side when single) |
point0 dev flags
| Flag | Effect |
|---|---|
-G, --no-generate | skip generation before serving |
-W, --no-watch | do not restart / regenerate on change |
-w, --watch [glob] | watch glob(s); no value = server config's devWatchGlob |
--side <side> / --scope <scope> | serve one side / one scope |
--entry <name|path> | server entry points (comma-separated or repeated) |
--hot | server hot reload (bun-native, experimental) |
--env / --mode / --engine | see shared flags |
-- <args> | forwarded to the spawned bun server process |
point0 build flags
| Flag | Effect |
|---|---|
-w, --watch [glob] | watch the entries' import graph; a glob adds to it |
--side <side> / --scope <scope> | build one side / one scope |
-C, --no-clean | do not clean before building |
-P, --no-publicdir | do not copy the public dir |
-k, --keep-alive | hold open after the build (for long-lived plugins) |
--env / --mode / --engine | see shared flags |
point0 compile flags
| Flag | Effect |
|---|---|
--side <side> / -c / -s | compile side (-c = client, -s = server) |
--scope <scope> | compile scope (inferred from side when omitted) |
-b, --built | treat the engine as built (else POINT0_BUILT === 'true') |
-B, --no-babel | strip babel plugins from compiler options |
-h, --hmr / -H, --no-hmr | force the HMR fix on / off (else engine config) |
-p / -d / -t / --mode / --engine | see shared flags |
Environment variables
| Var | Effect |
|---|---|
POINT0_ENGINE_FILE | engine file fallback when no --engine |
POINT0_DEV_SERVER_HOT='true' | enables dev server hot reload when --hot is omitted |
POINT0_BUILT='true' | compile / trace treat the engine as built |
POINT0_MODULE_PRELOAD='false' (also 0/off) | kill switch: disables per-page modulepreload (manifest emission at build + link injection at serve); any other / unset value keeps it on |
NODE_ENV | mode resolution (after flags and --env) |
LOG_MODE | build forces pretty |
Enjoying Point0?
Star Point0
Start0
YouTube
Discord
Telegram
of the Lord Jesus Christ ☦️
With love for developers
of all backgrounds around the world ❤️