Prerequisite

Bun >= 1.3. patties uses Bun as the runtime, not Node — reach for bun / bunx rather than node / npx throughout.

Scaffold with create-patties

create-patties is the official scaffolder. It generates a minimal app and, optionally, layers an agent-platform overlay on top.

bunx create-patties@latest my-app

Creates my-app/ from the base template, runs bun install, and initializes a git repo with an initial commit.

Common options:

bunx create-patties@latest my-app \
  --template claude|codex|none \
  --target   bun|edge \
  --deploy   cloudflare|vercel|deno|netlify|bun|none \
  --no-install \
  --no-git

What the flags do

  • --template — agent overlay: claude adds CLAUDE.md, codex adds AGENTS.md, none skips it. Default claude.
  • --target — runtime target written into patties.config.ts (bun or edge). Default bun.
  • --deploy — records the intended deploy target. Default none.
  • --no-install / --no-git — skip bun install / git init.

What you get

  • app/routes/ — filesystem routes
  • app/islands/ — interactive client components
  • app/server.ts — the server entry
  • patties.config.ts — framework config
  • tsconfig.json, .gitignore

Build with the framework

A patties app is a folder convention plus a small runtime. You write modules into the convention; the framework discovers and wires them at build time.

① Write a route

Add a module under app/routes/. Handlers take a standard Request and return a standard Response; patties adds a thin ctx (params, cookies, env, vars, json() / html() / redirect()).

② Render UI

Pages render with React on the server via renderToReadableStream. Put interactive components in app/islands/ so only those hydrate on the client.

③ Compose middleware

Request flow is the compose() middleware in app/middleware.ts — no guards / pipes / interceptors.

④ Build & deploy

The build inlines the route table into the production bundle (no filesystem scanning at runtime), targeting bun or edge via adapters.

Discover at build, serve frozen

Route and island discovery happens during build; the production server runs Bun.serve({ routes }) and scans nothing. Dev mode is the exception — it re-scans on change to drive HMR.

The CLI

Once installed, patties <command> drives the project lifecycle.

patties dev      # start the dev server (bun --hot by default)
patties build    # produce a production bundle for the configured target
patties deploy   # build, then dispatch to an installed deploy plugin
patties secret   # manage dev-time secrets in the OS keychain
patties upgrade  # update the project's patties dependency

Global flags apply consistently across commands:

patties <command> --cwd <path> --config <path> --verbose
                  --version  --help

Add UI with the Patties UI catalog

Patties UI is a shadcn-compatible, copy-in catalog. Components are never imported from a versioned package — patties add stamps the source into your project, so you own and can edit it. The catalog commands require patties-ui as a dev dependency.

bun add -D patties-ui          # required once

patties ui init                # tokens, the cn helper, Tailwind wiring
patties add button card dialog # stamp one or more components
patties add --all              # stamp every completed component
patties add --list             # list components with phase / island / status
patties view button            # print source before stamping (read-only)
patties update --all           # re-stamp after showing the diff

Where files land

  • components → app/components/ui/
  • helpers → _internal/
  • tokens → app/styles/tokens.css
  • override per-run with --path <dir>, or via the optional ui config block

Useful add flags

  • --dry-run — print the file/dep diff without writing
  • --diff / --check — show (and CI-gate) drift from the catalog
  • --theme <name> — merge a preset's tokens (neutral|slate|stone|zinc)
  • --force — overwrite existing files

Sources beyond the built-in catalog — all schema-validated, previewed, written verbatim, and never executed:

patties add ./path/to/component.tsx              # a local file or built payload
patties add @namespace/component                 # a namespaced registry (config.ui.registries)
patties add https://registry.example/button.json # an https payload (http rejected w/o --allow-insecure)

Migrate and publish:

patties migrate radix [<glob>]   # codemod radix imports to the unified import
patties migrate rtl   [<glob>]   # codemod to RTL logical properties
patties ui build --out <dir>     # emit a fetchable registry.json + per-component payloads

patties add is CI-safe and Bun-native

It refuses to run under NODE_ENV=production and never runs an install — it edits package.json and tells you to run bun install. Migrations refuse a dirty git tree without --force. Components are SSR-first and React 19 style (no forwardRef; refs are plain props), themed with Tailwind v4 + CSS variables, dark mode via .dark on <html>.

The daily flow

From an empty folder to a running app in four steps.

flowchart LR
    A["bunx create-patties\nmy-app"] --> B["patties ui init\n+ patties add ..."]
    B --> C["write routes\n+ islands"]
    C --> D["patties dev\n(bun --hot, HMR)"]
    D --> E["patties build\n→ bun | edge"]
    E --> F["patties deploy"]
    classDef hot fill:#1d4ed8,color:#fff,stroke:#1e3a8a,stroke-width:2px;
    class D hot;
Discovery happens once at build; dev re-scans on change for HMR. The deployed artifact serves a frozen route table.
Patties design specifications · a design exploration · User docs