Skip to Content
Introduction

Manh

Manh is a file-based, convention-over-configuration framework. You drop files into an app/ directory, and Manh gives you back two things:

  • a React SPA compiled in the browser (antd + antd-pro, rendered inside a preview iframe),
  • a backend running as a Cloudflare Worker (Hono v3 + @hono/zod-openapi + Drizzle + SQLite in a Durable Object).

Both sides read from the same tree. The same folder that holds page.tsx can hold get.ts next to it — one becomes /orders, the other becomes GET /orders. No separate pages/ or api/ directory, no route registration, no glue code.

How files become routes

The rule is simple: look at the extension.

  • .tsx files run in the browser. page.tsx is a page, layout.tsx wraps everything below it.
  • .ts files run on the server. get.ts / post.ts / … are API handlers, middleware.ts is a folder-scoped middleware, *.cron.ts is a scheduled job.
  • app/<resource>/<resource>.table.ts holds that resource’s Drizzle table; repository.ts next to it holds the business rules and every DB call.

Every frontend file must end in .tsx, even helpers with no JSX — otherwise Manh thinks it’s backend code and bundles it into the Worker instead of the browser.

What you get for free

When you stay inside the conventions, Manh hands you back:

  • A typed client useApiClient() at app/api, generated from your handlers, plus useRequest at app/hooks — no axios setup, no base URL to configure.
  • A Drizzle db client at app/db — generated on every deploy; tables come from your *.table.ts files.
  • An OpenAPI document at /openapi.json and an interactive reference at /docs, both auto-generated from the schema you export next to each handler.
  • Folder-scoped layouts (frontend) and middleware (backend) that cascade from root to leaf, so you never wire them up manually.

Everything else in this guide is just the details of those conventions. Start with Filesystem grammar.

Last updated on