Skip to contentAcme Inc.

One Worker. Every client.

A full-stack starter for web and mobile. TanStack Start, Expo and one typed API, running on Cloudflare.

The request machine
The request machineTwo input trays, one travelling carriage. Web and mobile use the same session check, router and database path. Illustrative sequence, not live traffic.
Select a stage to inspect
Automatic illustration. Select a stage to pause and inspect.
Two input trays, one travelling carriage. Web and mobile use the same session check, router and database path. Illustrative sequence, not live traffic.

Already running.

The todo app with five example tasks, priorities and workflow states.
Todo example
The R2 file manager with uploads, a library and trash.
Files
Account security settings for passwords, passkeys and two-factor authentication.
Authentication
The integrations page for connected agents, webhooks and agent activity.
MCP server

Todos, files, security and agent connections. Actual screens from the template with example data.

The working parts.

Keep what your product needs. Every integration below is included; optional services stay off until you configure them.

Product

AuthenticationReady

Email and password, passkeys, two-factor codes, email verification and session management.

OrganizationsReady

Members, invitations and roles. Todos and files belong to the active organization.

FilesReady

Multipart uploads to R2, previews, share links and a trash.

AdminReady

User management, impersonation, feature flags and an audit log.

Todo exampleReady

Grid, board and calendar views, with leased import queues and drafts proposed by AI agents.

PaymentsOff by default

Stripe and Polar on the web, RevenueCat on mobile. Off until providers and billing flags are configured.

Platform

DatabaseReady

Drizzle on Neon Postgres, reached through Hyperdrive.

EmailReady

Transactional email through Cloudflare Email, printed to the console in development.

i18n and SEOReady

English, German and French, hreflang, a sitemap and OG images generated with Takumi.

In-app assistantOff by default

Streaming chat with TanStack AI and shared MCP tools. Off until a provider is configured and the assistant flag is enabled.

Scheduled jobsReady

Effect at the edges: cron jobs and outbound delivery, with Postgres leases for queued work.

Cookie consentReady

A consent banner that holds back analytics and marketing scripts.

Mobile

Expo appReady

iOS and Android with the same API client, session and passkeys.

Push notificationsIn progress

Expo push registration and a delivery queue. Off until credentials are set.

Home-screen widgetsOff by default

Todo widgets for iOS and Android behind a native build option.

AdsOff by default

AdMob helpers kept as a standalone library, not imported by the app.

The stack

One TypeScript monorepo. Each package has one job and an enumerated public surface.

  • The one Worker
  • Clients
  • Managed services
  • Tooling, not at runtime
One Worker between the clients and the dataArchitecture diagram: the web and mobile apps call one Cloudflare Worker that serves TanStack Start, oRPC, Better Auth and Effect jobs, reaches Neon Postgres through Hyperdrive and stores files in R2; GitHub Actions, Turborepo and pnpm deploy it.ClientsCloudflareDataSSR + ORPCORPCDRIZZLE ORMFILESDEPLOYAPPWeb appTanStack Start · ReactTailwind CSS · shadcn/uiAPPMobile appExpo · Expo RouterReact NativeWORKEROne WorkerCloudflare WorkersTanStack Start · SSRoRPC · ZodBetter AuthEffect · jobsPOOLHyperdriveDrizzle ORMDBNeon PostgresPostgresR2R2 filesS3 APICIDeliveryGitHub Actions · Turborepo · pnpmOne Worker between the clients and the dataArchitecture diagram: the web and mobile apps call one Cloudflare Worker that serves TanStack Start, oRPC, Better Auth and Effect jobs, reaches Neon Postgres through Hyperdrive and stores files in R2; GitHub Actions, Turborepo and pnpm deploy it.ClientsCloudflareDataSSR + ORPCORPCDRIZZLE ORMFILESAPPWeb appTanStack Start · ReactTailwind CSS · shadcn/uiAPPMobile appExpo · Expo RouterReact NativeWORKEROne WorkerCloudflare WorkersTanStack Start · SSRoRPC · ZodBetter AuthEffect · jobsPOOLHyperdriveDrizzle ORMDBNeon PostgresPostgresR2R2 filesS3 APICIDeliveryGitHub Actions · Turborepo · pnpm
Every request from either client takes the same path. The Worker is the only piece that talks to the database and the bucket.

One shared contract.

The browser and Expo call the same oRPC router. The Worker checks the session before accessing Postgres or R2.

apps/web/src/routes/index.tsx
import { useQuery } from "@tanstack/react-query";import { orpc } from "@/utils/orpc";const { data: apiOk, isLoading: apiLoading } =  useQuery(orpc.healthCheck.queryOptions());

Excerpt from the landing route. The generated client keeps the query typed.

Session first
Protected procedures reject missing sessions with 401 before reaching your data.
Types across the boundary
Clients import the router type and leaf contracts. Server implementations stay in the Worker.

Server stays server.

Share contracts with your clients. Keep database connections, secrets and server code behind three independent checks.

oxlint
Value imports of server modules fail lint in apps/web, apps/mobile and packages/ui. Type imports are allowed.
Explicit exports
Each package lists its public entry points. No wildcards, so a new cross-package import is a deliberate change.
Client bundle scan
The web build reads the client assets and fails on strings that only exist in server code.

A preview for every PR.

Each pull request gets a preview Worker and a Neon branch. Review the real URL, then merge when it is ready.

  1. Open a pull request
  2. Worker + Neon branch
  3. Close and clean up

.github/workflows/pr-preview.yml

Merging ships production
A push to main runs the separate production workflow with production secrets and database.
Cleanup is exact
It checks the project, the pull request and the parent branch, deletes the Worker first and accepts resources that are already gone.

One tool catalog.

TanStack AI and the MCP server use the same authorized tools. Coding agents get the repo instructions and architecture decisions.

What the agent reads first

AGENTS.md
Rules every coding agent reads first: the client and server boundary, Effect on the server, i18n.
docs/adr
Architecture decisions with their context, so an agent does not undo them.
.agents/skills
Setup, startup, deploy and browser checks as step-by-step skills.
/api/mcp
Agents read your data and propose drafts over OAuth. Drafts wait until you apply them.
/llms.txt
Public Markdown at /index.md and a /llms.txt directory for agents to read before connecting.
Give your coding agent a starting point

Read AGENTS.md and CONTEXT.md. Follow the setup-envs skill to configure this project, preserving existing credentials. Then run pnpm install, pnpm setup and pnpm run dev. Verify the app with the agent-browser skill.

Tool calls over MCP

todo_listCompleted5 results
todo_createApproval neededWaits for your approvalApproveDecline

Connect Claude Code

claude mcp add --transport http my-app https://your-domain.example/api/mcp

In ChatGPT or claude.ai, add the same /api/mcp URL as a custom connector.

Make it yours.

Clone your copy of the repository. Install, configure, and run web and mobile together.

Node.js 22+ and pnpm. Setup asks for your project and service configuration.

Read the docs
  1. Clone

    git clone <your-repo-url> my-app

    Start from your copy of the template repository.

  2. Install

    pnpm install

    Installs every workspace in the monorepo.

  3. Configure

    pnpm setup

    Names the project and writes env files, Wrangler, database, email and storage settings.

  4. Run

    pnpm run dev

    Web on localhost:3005, plus the Expo dev server for mobile.

Before you clone.

What can I try in the demo?

Create an account and use the real app: todos, files, organizations, passkeys, two-factor and settings. It runs on the same Worker as this page.

Why Cloudflare Workers?

One deploy serves pages, the API, auth and scheduled jobs. Every pull request gets its own Worker, so review happens on a real URL.

Why Neon Postgres instead of D1?

Auth, organizations and the job queues rely on Postgres transactions and locks. Hyperdrive pools the connection, and each pull request gets its own Neon branch.

Can I remove mobile, payments or ads?

Yes. optional-features.json lists each optional package and its entry points, and docs/optional-features.md explains how to remove them.

How do I rebrand it?

Colors, radius and fonts live in one token file. Names and copy live in the locale files. Screens only use tokens, so a palette swap changes every page.

Do I need to know Effect?

Only to change server jobs. Effect coordinates execution in the Worker; contracts use Zod, requests use oRPC, auth uses Better Auth and queries use Drizzle.

How do I connect an AI agent?

Point any MCP client at /api/mcp. You approve access over OAuth, read and write are separate scopes, and writes only create drafts you confirm in the app.

Does the template include an AI assistant?

Yes. The assistant and MCP share one tool catalog, scoped to your organization. Writes require approval. Configure Anthropic, OpenAI or Gemini and enable the assistant flag to show the chat. It is off by default.