Browse docs
Your First Project

Connect Your Own Backend

Keep the included Hono and SQLite backend, or point the app at your existing Django, Rails, or Node API.

Updated Aug 2026
On this page

The app is backend-agnostic by design. You have two clean paths.

Path A, keep the bundled backend

apps/api is a Hono and Drizzle backend on SQLite, with auth, /me, devices, uploads, payments, and webhooks already implemented. It runs through tsx, so there is no build step, and it ships a Dockerfile for deployment.

pnpm --filter api db:migrate
pnpm --filter api dev

Outgrowing a single SQLite file? docs/swap-to-postgres.md in the repository documents the change.

Endpoints it already serves: /healthz, /auth/* (sign-up, sign-in, refresh, sign-out, forgot and reset password, Apple, Google), /me (read, update, delete), /devices, /uploads, /payments, /webhooks.

Path B, bring your own backend

Already running Django, Rails, FastAPI, or Node? Then:

  1. Delete apps/api.
  2. Set EXPO_PUBLIC_API_URL in apps/mobile/.env to your server.
  3. Implement the endpoints described in docs/backend-contract.md.

The contract is small. At minimum you need sign-up, sign-in, token refresh, and GET /me. Devices, uploads, and payments are only needed if you use those features.

Skip backend auth entirely

Use a hosted provider and your backend only has to verify their tokens. See Choosing an Auth Provider for what that actually involves.

How the app talks to either one

Every request goes through apiFetch in packages/api-client, which adds the auth header, validates the response against a zod schema, and turns failures into a normalised ApiError. TanStack Query sits on top for caching, retries, and refetching.

Swapping backends never touches your screens. It changes one env var and, if your shapes differ, the schemas in packages/api-client/src/schemas.

Writes that survive a bad connection

Mutations go through TanStack Query's onlineManager, bound to NetInfo. When the device goes offline, writes pause instead of failing, and flush when the connection returns. docs/recipes/offline-queue.md covers the details.

Try this one on a device, not in a browser

NetInfo's web build reports the connection as online regardless of what the browser is doing, so on the web target the banner never changes and a queued write just fails. Use airplane mode on a real device or a simulator to see the queue actually hold and flush.

Stop reinventing the app shell. Start shipping.

React Native and Expo boilerplate built for Claude Code, Cursor and Copilot. Auth, payments, push and offline sync already wired, with a 37-row map telling your agent where each one lives.

Get it for $59 →