CLI commands
Jx has two command-line surfaces:
bun create @jxsuite
, which scaffolds a new project once, and the
jx
CLI, which ships with
@jxsuite/compiler
(a devDependency of every scaffolded project) and operates on an existing project. Every
jx
command takes an optional project root as its first positional argument and defaults to the current directory.
bun create @jxsuite
Scaffold a new Jx project.
bun create @jxsuite <directory> [--template <id>]
| Flag | What it does |
|---|---|
--template <id> |
Skip the template prompt. Accepts a built-in template id (
blank
,
desktop-first
,
mobile-first
,
mobile-app
) or a starter id; built-in ids win over starter ids, and an unknown id falls back to
blank
. |
The scaffolder then prompts for a project name, description, production URL, a template (when
--template
wasn't given — the built-in variants plus the starter sites), and a deployment adapter:
static
(default),
cloudflare-pages
,
node
,
bun
, or
cloudflare-workers
.
A blank scaffold produces:
project.json— bound to./project.schema.json, with a viewport$head,$mediabreakpoints matching the template (desktop-firstmax-widthqueries or mobile-firstmin-widthqueries), abuildblock (outDir: "./dist",format: "directory",trailingSlash: "always", plusadapterwhen not static),extensions: ["@jxsuite/parser"], an emptycontentsection, basestyle, anddefaultspointing at./layouts/base.jsonpackage.json—@jxsuite/parseras a dependency,@jxsuite/compilerand@jxsuite/runtimeas devDependencies, andbuild/devscripts (plus adeployscript andwranglerfor the Cloudflare adapters)layouts/base.json,pages/index.md, emptycomponents/,content/, andpublic/directories, and a.gitignorewrangler.jsoncfor the Cloudflare adapters; themobile-apptemplate overlays an app-shell layout and home page
Choosing a starter instead copies the starter site verbatim (minus build artifacts), then re-stamps
project.json
with your name, URL, description, and adapter, and rebuilds
package.json
with current dependency ranges.
jx build
Build the site to the configured
outDir
(default
dist/
). See
How compilation works
for what happens inside.
jx build [root] [--verbose] [--no-clean]
| Flag | What it does |
|---|---|
--verbose |
Print detailed build progress. |
--no-clean |
Don't remove the output directory first. |
Prints a summary (
Done: 12 routes → 34 files
) on success; lists route errors and exits
1
if any page failed to compile.
jx dev
Start the dev server for a project: builds the site, serves the built pages with live reload (edits rebuild before the browser refreshes), and exposes the Studio backend API. Requires
Bun
and
@jxsuite/server
in the project's devDependencies — both part of every scaffolded project;
jx dev
prints an install hint when either is missing.
jx dev [root] [--port <n>]
| Flag | What it does |
|---|---|
--port <n> |
Port to listen on (default
3000
). |
See The dev server for what runs underneath.
jx preview
Serve an already-built
dist/
directory — a dependency-free static server for checking the production build locally. Run
jx build
first.
jx preview [root] [--port <n>]
| Flag | What it does |
|---|---|
--port <n> |
Port to listen on (default
4173
). |
Directory URLs map to their
index.html
(with or without a trailing slash) and
404.html
is served for missing routes when present.
jx schema
Generate the project's JSON Schema entry documents —
project.schema.json
and
document.schema.json
— by composing the core schemas with the fragments shipped by each extension in
project.json
's
extensions
. The outputs are written into the project root as committed,
self-contained
artifacts: the core and fragment resources are embedded under
$defs
keyed by their canonical
$id
s, so editors resolve them offline with no
node_modules
, network, or editor configuration. No flags.
jx schema [root]
Re-run it whenever you change the
extensions
list so editors and
jx validate
see the current schema.
jx validate
Validate the whole project tree (run
jx schema
first). No flags.
jx validate [root]
Checks, in order: that both committed entry documents are self-contained (every
$ref
a root-relative JSON Pointer that resolves in the same file — otherwise it asks you to regenerate with
jx schema
, and stops there, since the remaining checks compile those files);
project.json
against the generated
project.schema.json
; every document under
components/
,
pages/
, and
layouts/
against the bundled document schema; every project-local
*.class.json
against the class schema; and each enabled extension's schema fragments compile standalone.
Prints
Project is valid (N files checked)
on success; otherwise lists each file's violations with their instance paths and exits
1
.
The output shape is meant to be read by whatever wrote the file — a person or a generator: one line naming the file, then one
- <instance path>: <message>
line per violation. Paired with the non-zero exit it drops straight into a write-check-fix loop. Because
jx schema
embeds every core and fragment resource under
$defs
keyed by its canonical
$id
, the document checks resolve from the committed entry documents alone — no network fetch and no module resolution — so an editor's inline squiggles and this command are looking at exactly the same schema.
jx db push
Additively sync the tables declared in
project.json
's
data
section to their
connections
databases, through each connection's connector. Credentials come from the environment merged with the project's
.dev.vars
file. After a real (non-dry-run) apply, each connector's binding fragments are merged into
wrangler.jsonc
, preserving your keys.
jx db push [root] [--dry-run] [--connection <name>]
| Flag | What it does |
|---|---|
--dry-run |
Print the SQL statements without executing them. |
--connection <name> |
Restrict the push to one
connections
entry. |
The sync is additive-only — it creates missing tables and columns and never drops or rewrites existing ones. Per-connection output lists the tables, statements, and warnings; a missing
connections
section or an unknown connection name is an error.
The CLI talks to each connection exactly as declared: a
d1
connection reaches the real D1 database (through its binding, or the D1 HTTP API with
CLOUDFLARE_API_TOKEN
plus the account and database ids). Studio's
Push Schema
button runs through the dev server, which substitutes a local stand-in for any provider that declares one — so a D1 connection pushed from Studio lands in
.jx/data/<connection>.sqlite
, while the same connection pushed from a terminal lands in D1 itself.
jx db push
covers the
data
section only. The auth extension's account tables (
user
,
session
,
account
,
verification
) come from a separate push step that Studio's
Push Schema
button and the dev server run, and the dev server also creates them on its first request to
/_jx/auth
— the CLI push does not include them today. A database whose schema only ever came from
jx db push
has no account tables, and sign-in fails against it at runtime.
What the scaffolded scripts run
| Script | Runs |
|---|---|
bun run build |
jx build |
bun run dev |
jx dev |
bun run preview |
jx preview |
bun run deploy
(CF only) |
wrangler deploy
/
wrangler pages deploy dist |
Related
How compilation works — what
jx buildproduces and whyThe dev server — local development without a build
Site architecture — the project layout these commands operate on
Data tables — the tables and push plan behind
jx db push