Getting Started
Get a pracht app running in under a minute. This guide covers project creation, development, and your first production build.
Create a Project
The fastest way to start is with create-pracht. It scaffolds a working app with routing, a shell, an API route, and your choice of deployment adapter.
# pnpm
pnpm create pracht my-app
# npm
npm create pracht@latest my-app
# yarn
yarn create pracht my-app
# bun
bunx create-pracht my-appThe CLI will ask you to choose an adapter (Node.js, Cloudflare Workers, Netlify, Vercel, or a pure static export), whether to use the explicit manifest router or the file-system pages router, whether to add Tailwind CSS, and whether to seed the agent tooling. Adapters can be changed later in vite.config.ts. Moving from pages routing to manifest routing is an explicit ejection step when you need per-route shell or middleware assignment, explicit route ids, path-prefix groups, or webhook ISG policies; see Pages Router.
For reproducible setup in CI, demos, or agents, pass the same choices as flags:
pnpm create pracht my-app --adapter=node --router=manifest --template=tailwind --yes
pnpm create pracht my-app --adapter=cf --router=pages --no-tailwind --no-agent-tools --yes
pnpm create pracht my-app --adapter=vercel --skip-install --yesUseful creation flags:
--adapter=node|cf|vercelchooses the deployment target.--router=manifest|pageschooses explicitsrc/routes.tsrouting or file-systemsrc/pages/routing.--template=minimal|tailwind,--tailwind, and--no-tailwindcontrol styling setup.--agent-tools[=core|full]and--no-agent-toolscontrol.claude/skills/,.mcp.json, andAGENTS.md/CLAUDE.mdsetup.--skip-install,--no-git,--json, and--dry-runare handy for automation.
Project Structure
A manifest-router scaffold looks like this:
my-app/
src/
routes.ts # Route manifest (the central wiring file)
routes/home.tsx # First page component + loader
routes/not-found.tsx # Not-found page, wired from the manifest
shells/public.tsx # Layout wrapper
api/health.ts # Sample API endpoint
vite.config.ts # Vite + pracht plugin config
package.jsonA pages-router scaffold uses src/pages/ instead:
my-app/
src/
pages/_app.tsx # App shell
pages/index.tsx # First page component + loader
pages/404.tsx # Not-found page, wired automatically
api/health.ts # Sample API endpoint
vite.config.ts # Vite + pracht plugin config
package.jsonDepending on your choices, the starter can also include Tailwind's src/styles/global.css, adapter files such as wrangler.jsonc or Dockerfile, and agent files under .claude/skills/ plus .mcp.json.
Development
Start the dev server with HMR. Changes to routes, shells, and loaders are reflected instantly.
pnpm devOpen http://localhost:3000 to see your app. Edit src/routes/home.tsx and watch it update.
Build Output
# Production build (client + server bundles, SSG prerendering)
pnpm buildThe build writes dist/client/ (static assets and prerendered SSG pages) and
dist/server/ (the server bundle in whatever shape the adapter needs). For a
Node.js target you can run it straight away:
node dist/server/server.jsDeploy
The scaffold already contains the platform config and a deploy script for the
adapter you chose, so getting a public URL is one command.
Cloudflare Workers — the shortest path
Scaffold with the Cloudflare adapter and you get a wrangler.jsonc and
wrangler as a dev dependency, already installed. Nothing else to write:
pnpm create pracht my-app --adapter=cf --yes
cd my-app
pnpm run deployThat script is pracht build && wrangler deploy. The first run opens a browser
to authorize Wrangler against your Cloudflare account (or set
CLOUDFLARE_API_TOKEN in CI instead), then prints the live URL —
https://my-app.<your-subdomain>.workers.dev. Redeploy with the same command.
Use pnpm run deploy, not pnpm deploy: pnpm has a built-in deploy
command of its own that would run instead of the script.
Static assets are served from dist/client through the Worker's ASSETS
binding, and the Worker itself handles SSR, API routes, and ISG. Add KV, D1, R2,
or cron triggers by editing wrangler.jsonc; bindings arrive as context.env
in loaders and API routes.
For a production-shaped local run first, pracht preview delegates to Wrangler
and serves the built app on localhost.
Vercel
Equally short, with one extra interaction — the first deploy asks which Vercel project to link the directory to:
pnpm create pracht my-app --adapter=vercel --yes
cd my-app
pnpm run deployThat script is pracht build && vercel deploy --prebuilt. pracht build
already emits Vercel's Build Output API structure, which is what --prebuilt
consumes — SSG pages as static files, SSR and API routes on an Edge Function,
ISG routes on Vercel's native ISR.
Everything else
Node.js (including Docker), Netlify, and pure static hosts are each one adapter
swap in vite.config.ts. See Deployment for the per-platform
commands, ISG behaviour, and deploy-base handling, and
Adapters for what each adapter emits.
Key Concepts
- Route manifest —
src/routes.tsdeclares all routes, their shells, middleware, and render modes. See Routing. - Render modes — each route can be SSR, SSG, ISG, or SPA. See Rendering Modes.
- Loaders & API routes — server-side data fetching and mutations. See Data Loading.
- Adapters — deploy to Node.js, Cloudflare Workers, Netlify, Vercel, or a static host. See Adapters.
- Capabilities — typed operations your app exposes to agents as well as to its own UI. See The Agentic Web.