Your first site
Scaffold, run, and build a zfb project in about five minutes.
The shortest workflow
With the CLI installed, select the node-free template explicitly. Stop dev with Ctrl+C before continuing.
zfb new my-site --template node-free
cd my-site
zfb dev
# Stop with Ctrl+C
zfb check --skip-tsc
zfb build
zfb preview--skip-tsc runs only the non-TypeScript checks. For full type checking, install Node.js and TypeScript and use zfb check. The npm distribution runs these same commands through pnpm exec zfb or npx zfb.
Choose Basic blog for a package-based blog, or Node-free for a starter that runs without Node or a package install. Use either tab below to create, run, build, and preview your site after Installation.
Scaffold a new project
pnpm create zfb@latest my-site
# or
npm create zfb@latest my-siteSee the output before you run it
create-zfb.takazudomodular.com serves exactly what this command produces — the basic-blog template, built and deployed straight from main on every push. Nothing about the site is hand-written: it is generated in CI by the same clean-room run that gates every pull request, so it cannot drift from the template you are about to get.
pnpm 11 note
pnpm 11's minimumReleaseAge may install a previous release of create-zfbwithin ~48h of any new release. If create-zfb warns about a stale install at startup, re-run with pnpm create zfb@latest --config.minimumReleaseAge=0or use npm create zfb@latest instead.
This runs the create-zfb initializer, which calls zfb new under the hood and copies the bundled basic-blog template into my-site/. If pnpm is on your PATH, zfb runs pnpm install automatically right after copying the template; otherwise it prints a short note telling you to run it yourself.
cd my-siteIf you already have the zfb CLI installed globally (see Installation), you can invoke zfb new directly with the same result:
zfb new my-site --template basic-blog--template basic-blog is the default, so you can omit it. A node-free template is also available for projects that need no Node.js dependency — it ships no package.json and relies on .md/.html page entries alongside .tsx; see Markdown and HTML Pages for the authoring surface it uses.
basic-blog scaffolds a zfb.config.ts (not JSON), a blog content collection with three seed posts, four routes, and one client island. Its README.md is a tour of the tree; Project structure covers the same ground in more depth.
Import specifiers
The bare zfb family — zfb, zfb/content, zfb/paginate, zfb/zudo-react, and the other supported subpaths — aliases to the matching @takazudo/zfb exports in SSR, the island scanner, client bundles, JSX pragma classification, and zudo-wind class extraction. For package-backed entries, either spelling resolves to the same package identity; these docs use the shorter zfb form. The config loader handles zfb/config by aliasing it to an internal runtime stub.
These build aliases do not configure TypeScript. zfb check is unchanged: it runs TypeScript with your project configuration and does not inject compilerOptions.paths. TypeScript and editors use the ambient declarations in components/. See Typing bare zfb imports for the full shim and guidance for extending an existing one.
Start the dev server
pnpm zfb dev
# or
npx zfb devYou'll see a "ready" banner with the host and port (defaults: http:). zfb watches a fixed set of project roots — pages/, content/, components/, layouts/, styles/, data/, src/, and the two config files (zfb.config.json, zfb.config.ts) — plus any additional paths declared as collection path values or absolute extraWatchPaths entries in your config. The default public/ directory is not watched; those files are served directly from disk. Saving any tracked file triggers a live-reload broadcast to connected browsers.
You can override host and port from the CLI — they always win over zfb.config.ts:
pnpm zfb dev --port 4000 --host 0.0.0.0
# or
npx zfb dev --port 4000 --host 0.0.0.0Build and preview
To produce a static build of the site:
pnpm zfb build
pnpm zfb preview
# or
npx zfb build
npx zfb previewzfb build writes to the directory selected by CLI --outdir → config outDir → the built-in dist/ default, then enumerates routes via the file-system router and writes one HTML file per static route. The build command has no --port flag because it does not start a server.
zfb preview uses the same output-directory precedence and serves the selected directory over HTTP. Preview's --port flag wins over config port; if neither is set, preview uses the built-in 4321 default.
All three commands honor outDir in zfb.config.*. For build and preview, an explicit --outdir always overrides the configured value.
Type-check the project
pnpm typecheck
# or
npx zfb checkzfb check does two things in one pass: it type-checks the project with TypeScript, and it validates every collection entry's frontmatter against the JSON Schema declared for that collection in zfb.config.ts. The build itself does not validate frontmatter, so this is where a post missing title or date gets caught. See CLI reference.
A working example
zfb-example-blog is a standalone example site you can read and deploy, with a live build. It is maintained as its own repository rather than as a copy of the bundled template, so its file layout differs from what zfb new scaffolds — read it as a worked example, not as a mirror of your new project. Blog walks through it in full, and Examples lists the rest.
Create a Node-free site
Install the standalone binary and add zfb to your PATH, then run:
zfb new my-site --template node-free
cd my-site
zfb devThe node-free starter has no package.json and needs no pnpm install or npm install. It uses zfb.config.json, Markdown / HTML / TSX pages, and an explicit Wind stylesheet. See Markdown and HTML Pages for its page authoring surface.
Open http:, the default dev-server address. Changes to pages and styles trigger live reload. To choose another address, use zfb dev --port 4000 --host 0.0.0.0.
Build and preview without Node
Stop the dev server with Ctrl+C, then run in the same project:
zfb build
zfb previewThe build writes static files to dist/ by default. Preview serves them at http: by default. Both commands honor config outDir, with CLI --outdir taking precedence. Change preview's port with zfb preview --port 4000; build has no --port flag.
Check without Node
zfb check --skip-tscThis runs the non-TypeScript checks without Node. Full TypeScript checking requires Node and tsc; deploying with the Cloudflare adapter also requires Node. See When Node is still needed.
Own the starting design
Both bundled starters begin with the Everyday design: semantic colour roles, independent horizontal and vertical spacing, readable type and one corner rule. These are editable project choices, not zudo-wind engine defaults.
Edit
styles/for colours, spacing, type, measure and radius.design- system. css Read
DESIGN-NOTES.mdfor when to use the roles;components/supplies the same short rules displayed on the home page. Update those explanations when changing the design.design- rules. ts In Basic blog,
zfb.config.tsmergesdesign-tokens.jsonwith the existing Markdown showcase tokens. Local dark values instyles/follow the theme toggle. The existing How this site is styled post explains the chain.global. css In Node-free, keep renamed tokens in
zfb.config.jsonanddesign-tokens.jsonin sync. Its explicit Wind stylesheet builds inside the binary, with no Node, package install or client island required.
Try the Design system playground, change its rules, and export editable files. Merge token maps by category and name so existing pages keep their values. The initializer currently selects a site template; it has no design-seed selector or seed flag.
What to read next
Project structure — what every directory the template created actually does.
Routing — how
pages/becomes URLs, including dynamic and catchall routes.Islands — how to opt individual components into client-side hydration.
Build engine — how the Rust crates fit together under the hood.