The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Pracht dev MCP listing page.
One app graph, projected to browsers and to agents. (pracht /praxt/ — Dutch & German for splendor. Also: how you've always mispronounced Preact.)
Other frameworks render your app for humans and leave agents to scrape it. Pracht resolves your routes, loaders, API routes, and capabilities into one explicit graph, then projects that graph two ways: components for people, and typed, trust-gated tools for agents — over HTTP, WebMCP, remote MCP, and llms.txt. It is a Preact framework, so the human half is small; it is an explicit framework, so the agent half is something you declare rather than something that gets scraped off you.
Documentation · Why pracht · Getting started · Compare to other frameworks
defineApp() manifest wires routes, shells, middleware, and capabilities. What runs where is never a mystery, and because the graph is resolved rather than inferred, tooling can read it. Prefer file-based routing? Opt in to the pages router and skip the manifest entirely.defineCapability() contract becomes a server call, an HTTP endpoint, a WebMCP page tool, and a tool on your app's own remote MCP endpoint, listed for discovery in a generated llms.txt. Same validation, same middleware, same effect class on every transport.pracht eval to prove agent flows in CI.pnpm bench in this repo and gated in CI, not asserted.pracht build --analyze reports per-route client JS (gzip + raw), and per-route budgets fail the build when a route ships too much.serverEnv/publicEnv helpers with a PRACHT_PUBLIC_ prefix rule, and builds fail when client bundles reference non-public env vars.@pracht/content gives loaders and build plugins one server-only registry for routes, locales, source/compiled representations, caching, and emitted assets.@pracht/markdown compiles ordinary relative Markdown images through @pracht/image into cached responsive WebP variants for SSR, SSG, and hydration-disabled routes.Two routing styles, your choice:
Manifest routing — full control, explicit wiring:
One manifest. Four render strategies. No renaming folders to change behavior.
Pages router — file-based, zero manifest:
Same render modes, same adapters — just let the filesystem drive. Directory
_app.tsx files provide shells, a root _middleware.ts wraps every page, and
modules in src/capabilities/ plus agents / constraints from
src/pages/_app.config.ts provide the same agent surface as a manifest app.
Eject when you need per-route shell or middleware assignment, explicit route
ids, path-prefix groups, or webhook ISG policies. See
docs/ROUTING.md.
The prompts cover the target directory, hosting adapter (Node.js, Cloudflare Workers, Vercel, Netlify, or a pure static export), router (manifest or pages), and optional Tailwind CSS. For non-interactive runs pass flags instead — e.g. --template=tailwind (or --template=minimal), --adapter=node, --no-git, --yes. See packages/start/README.md for the full list.
The starter gives you:
pracht dev — local SSR + HMR, a /_pracht devtools page with the resolved route/API graph plus a live capability-traffic log with explicit agent attribution (JSON at /_pracht.json), and Server-Timing middleware/loader/render phase timings on every dev SSR responsepracht build — client/server output plus SSG/ISG prerendering, with --analyze for a per-route client JS report and budget enforcementpracht preview — build and serve the production build locallypracht inspect [routes|api|capabilities|agents|build] --json — resolved app graph metadata; agents summarizes the configured agent surface (transports, policies, MCP, llms.txt)pracht generate route|shell|middleware|api — framework-native scaffolding; generate route also emits a Playwright smoke test when the app has an e2e setuppracht verify — fast framework-aware checks with --changed and --json, including defineApp({ constraints }) enforcement and app-graph snapshot freshnesspracht plan — semantic app-graph diff against a base git ref (--write refreshes the committed .pracht/app-graph.json snapshot; --markdown for PR comments)pracht report — PR-ready markdown assembled from the graph diff, verify results, and bundle budgetspracht doctor — app wiring checks with optional JSON outputDockerfilePracht is built to be operated by coding agents as much as by humans — and for the humans reviewing what agents produce:
.pracht/app-graph.json) plus pracht plan gives reviewers an intent-level diff of routes, render modes, shells, middleware, and API endpoints; pracht report turns it into the factual half of a PR description. See docs/AGENT_WORKFLOW.md.defineApp({ constraints }) declares rules like requireMiddleware("/app/**", "auth") that pracht verify enforces deterministically, so no author (human or LLM) can merge a violation.pracht dev-mcp starts a stdio Model Context Protocol server so agents can natively inspect the resolved app graph, run doctor/verify diagnostics, diff and snapshot the graph (plan/report), read the authoring guide (get_docs), and scaffold routes, shells, middleware, and API handlers. See docs/MCP.md for registration and the tool reference.pracht llms --write drops the framework's conventions into llms.txt so any coding agent picks them up.@pracht/capabilities lets you define a typed application operation once (JSON Schema contract, effect class, middleware) and project it to server code, a generated HTTP endpoint, a WebMCP page tool for in-browser agents, an MCP tool at your app's own /mcp endpoint for agents that never open a browser, and the human UI via <Form capability> — private by default, with pracht verify enforcing the security defaults and effect-driven revalidation keeping the page consistent after mutations. The same pipeline can be mounted in non-Pracht applications with createCapabilityHost(). See docs/CAPABILITIES.md and docs/REMOTE_MCP.md.pracht eval for scripted agent-task checks in CI — over the capability HTTP projection or, with "transport": "mcp", over the app's own remote MCP endpoint. See docs/AGENT_TRUST.md.llmsTxt plugin option emits an llms.txt index of your pages, API routes, and HTTP-exposed capabilities at build time and serves it live in dev. See docs/LLMS_TXT.md.The skills are distributed three ways (see the catalog):
https://pracht.resynapse.dev/skills/<name>/SKILL.md, listed with SHA-256 digests in the manifest at /.well-known/agent-skills/index.json and advertised via a Link: rel="agent-skills" header.npm create pracht@latest seeds five core skills into new apps' .claude/skills/ and writes a .mcp.json registering pracht dev-mcp (yes-default prompt, --agent-tools=full for the whole catalog, --no-agent-tools to skip)..claude/skills symlinks to skills/, so Claude Code loads them automatically for contributors.apiFetch()pracht eval<Image>, runtime loaders, and static variants@pracht/i18n: locale-detection middleware, typed dictionaries, hreflang helpers@pracht/query: TanStack Query with server-fetched queries hydrated into the browser cache@pracht/session: encrypted cookie or store-backed sessions, middleware, and password hashingpracht plan/reportPRACHT_PUBLIC_ prefix rule, leak detection@pracht/test unit-testing utilities for loaders, API routes, middleware, and formsUse the GitHub issue templates for bug reports and feature requests. When opening a pull request, follow .github/PULL_REQUEST_TEMPLATE.md.