pracht

mcp
Security Audit
Fail
Health Pass
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Community trust — 99 GitHub stars
Code Fail
  • process.env — Environment variable access in .github/scripts/has-unpublished-packages.mjs
  • network request — Outbound network request in .github/scripts/has-unpublished-packages.mjs
  • network request — Outbound network request in .github/scripts/publish-mcp-registry.mjs
  • spawnSync — Synchronous process spawning in .github/scripts/stage-packages.mjs
Permissions Pass
  • Permissions — No dangerous permissions requested

No AI report is available for this listing yet.

SUMMARY

A framework for Preact that deploys anywhere

README.md

pracht — One app graph, for browsers and for agents.

npm version CI status

pracht

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.

npm create pracht@latest my-app

Documentation · Why pracht · Getting started · Compare to other frameworks

Why pracht

  • One explicit app graph — a typed 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.
  • The graph is projected to agents, not scraped from them — one 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.
  • Trust ships with the surface — Web Bot Auth (RFC 9421) verified agent identity, per-capability policies, a prepare/commit confirmation gate for destructive effects, one structured audit event per dispatch, and pracht eval to prove agent flows in CI.
  • Preact-first — 0 KB of client JavaScript on a static route, 8.0 KB gzip with islands, 17.4 KB fully hydrated with the router. Measured by pnpm bench in this repo and gated in CI, not asserted.
  • Per-route render and hydration modes — SPA, SSR, SSG, and ISG, and full, islands, or no hydration, chosen per route. No global default fighting you.
  • Vite-native — instant HMR, fast builds, multi-environment output out of the box.
  • Performance budgets built in — pracht build --analyze reports per-route client JS (gzip + raw), and per-route budgets fail the build when a route ships too much.
  • Env safety built in — typed serverEnv/publicEnv helpers with a PRACHT_PUBLIC_ prefix rule, and builds fail when client bundles reference non-public env vars.
  • Optional content collections — @pracht/content gives loaders and build plugins one server-only registry for routes, locales, source/compiled representations, caching, and emitted assets.
  • Markdown images without runtime JavaScript — @pracht/markdown compiles ordinary relative Markdown images through @pracht/image into cached responsive WebP variants for SSR, SSG, and hydration-disabled routes.
  • Deploy anywhere — one codebase, one build, five production-ready adapters (Node, Cloudflare Workers, Netlify, Vercel, and pure static export).

At a glance

Two routing styles, your choice:

Manifest routing — full control, explicit wiring:

// src/routes.ts
import { defineApp, group, route, timeRevalidate } from "@pracht/core";

export const app = defineApp({
  shells: {
    app: () => import("./shells/app.tsx"),
    public: () => import("./shells/public.tsx"),
  },
  middleware: {
    auth: () => import("./middleware/auth.ts"),
  },
  routes: [
    group({ shell: "public" }, [
      route("/", () => import("./routes/home.tsx"), { render: "ssg" }),
      route("/pricing", () => import("./routes/pricing.tsx"), {
        render: "isg",
        revalidate: timeRevalidate(3600),
      }),
    ]),
    group({ shell: "app", middleware: ["auth"] }, [
      route("/dashboard", () => import("./routes/dashboard.tsx"), { render: "ssr" }),
      route("/settings", () => import("./routes/settings.tsx"), { render: "spa" }),
    ]),
  ],
});

One manifest. Four render strategies. No renaming folders to change behavior.

Pages router — file-based, zero manifest:

// vite.config.ts
export default defineConfig({
  plugins: [pracht({ pagesDir: "/src/pages", adapter: nodeAdapter() })],
});
src/pages/
  index.tsx        → /
  blog/[slug].tsx  → /blog/:slug

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.

Create an app

npm create pracht@latest my-app

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 response
  • pracht build — client/server output plus SSG/ISG prerendering, with --analyze for a per-route client JS report and budget enforcement
  • pracht preview — build and serve the production build locally
  • pracht 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 setup
  • pracht verify — fast framework-aware checks with --changed and --json, including defineApp({ constraints }) enforcement and app-graph snapshot freshness
  • pracht 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 budgets
  • pracht doctor — app wiring checks with optional JSON output
  • Optional Tailwind CSS wiring, a git repo with an initial commit, and (for the Node adapter) a multi-stage Dockerfile

AI-assisted development

Pracht is built to be operated by coding agents as much as by humans — and for the humans reviewing what agents produce:

  • Provable changes — a committed app-graph snapshot (.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.
  • Machine-enforced invariants — defineApp({ constraints }) declares rules like requireMiddleware("/app/**", "auth") that pracht verify enforces deterministically, so no author (human or LLM) can merge a violation.
  • MCP server — 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.
  • Authoring guide for agents — pracht llms --write drops the framework's conventions into llms.txt so any coding agent picks them up.
  • Capabilities, WebMCP & remote MCP — @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.
  • Agent trust layer — Web Bot Auth (RFC 9421) verified agent identity on the request context with observe/require policies, a prepare/commit confirmation flow for destructive capabilities, capability audit events, and 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.
  • llms.txt — the opt-in 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.
  • Claude Code skills — 33 skills for scaffolding, auditing, testing, debugging, and deploying pracht apps live in skills/. See the agent skills section below.

Agent skills

The skills are distributed three ways (see the catalog):

  • Discovery endpoint — every skill is published at 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.
  • create-pracht — 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).
  • In this repo — .claude/skills symlinks to skills/, so Claude Code loads them automatically for contributors.

Repo map

Contributing

Use the GitHub issue templates for bug reports and feature requests. When opening a pull request, follow .github/PULL_REQUEST_TEMPLATE.md.

Reviews (0)

No results found