Conventions & Critical Rules
These are the bright lines. An agent violating any of them is wrong, regardless of how reasonable the change looks.
File conventions (user app/ folder)
| Path | Becomes |
|---|---|
app/routes/index.tsx | / |
app/routes/about.tsx | /about |
app/routes/hotels/[city].tsx | /hotels/:city |
app/routes/api/revenue.ts | /api/revenue |
app/islands/counter.tsx | interactive island Counter |
app/agents/booking.ts | agent booking |
app/tools/search.ts | MCP tool search |
app/middleware.ts | global middleware |
patties.config.ts | framework config |
Reserved prefixes
- Files starting with
_are private and never routed. - The URL prefix
/__patties_*is reserved (dev HMR, internal endpoints). - The output directory prefix
/_patties/*is reserved (client bundle URLs).
Critical rules for agents working on this codebase
These are the bright lines. An agent violating any of them is wrong, regardless of how reasonable the change looks.
- Never import from
"next". This is not Next.js. - Never use Node.js
httpmodule. UseBun.serve. - Never use webpack or vite. Use
Bun.build. - Never use
fs.watchorchokidar. Usebun --watch. - Use React for rendering. Server:
react-dom/server.renderToReadableStream. Client:react-dom/client.hydrateRoot. Never import fromhono/jsxorhono/jsx/dom. Never userenderToPipeableStream(Node-only) orrenderToString(no streaming). tsconfig.jsonmust set"jsx": "react-jsx"and"jsxImportSource": "react". JSX is resolved throughreact/jsx-runtime; no manualimport Reactin user code.- All routes are plain handlers
(req: Request, ctx: PattiesContext) => Response | Promise<Response>. No HTTP framework —Bun.serve({ routes })dispatches; the framework owns a ~50-line middleware composer and thectxshape. Never import from"hono". - Islands must live in
app/islands/. No exceptions. - API routes export
GET,POST,PUT,DELETEnamed functions. Default exports are reserved for page components. - Middleware exports a default function typed as
Middleware = (req, ctx, next) => Promise<Response>. NeverMiddlewareHandlerfrom Hono. - No
getServerSidePropsor Next-style data loaders. Use middleware or route handlers. - Use Bun primitives for I/O, not
node:fs/node:child_process. File reads →Bun.file(path).text()/.json()/.bytes(). File writes →Bun.write(path, data). Subprocess →Bun.spawnorBun.$(Bun Shell). Hashing →Bun.CryptoHasher. Env reads →Bun.env(Bun target) or the adapter'sgetEnv()(edge). Password hashing →Bun.password. SQLite →bun:sqlite. Postgres →Bun.sql. Redis →Bun.RedisClient. S3-compatible storage →Bun.S3Client.node:fsis only acceptable when a Bun built-in does not exist for the task.
Naming
- Module file names: kebab-case (
booking-flow.ts). - Exported components: PascalCase.
- Agent and tool
namefields: kebab-case, must match their filename basename. Mismatches and duplicatenames are boot errors — see 10-agents-and-tools.
Commit format
feat(router): add dynamic segment support — conventional commits drive CHANGELOG.md.