Use case · Mobile
JSON or gRPC over the same contracts the web app uses. No separate mobile auth flow to maintain.
What's in the box
Twelve capabilities grouped by the buyer-side question they answer. Pick a cluster, read what you actually get, and ship it.
The same user table, the same session token, the same org boundary — phone, web, watch, tablet.
Better Auth issues a single session, validated by the same public key from the web app. Sign in on web, pick up on the device. The device's session isn't a separate identity to provision, rotate, or revoke — it lives next to the user's other sessions.
For apps that need it, App Attest and Play Integrity sit on top of the same session. Verified against the same auth middleware the rest of your app uses, with no second vendor to contract.
A device belongs to one org at a time, but switching works. The session carries the org boundary the same way the web session does — the device never sees cross-org data without an explicit org switch.
The client can lose the network and still ship work. The server reconciles on reconnect, not on tap.
The same Drizzle schema your server reads defines the offline cache on the device. Reads return from cache, writes queue locally, the reconciler replays them on reconnect — no separate ORM on the client.
When the network is there, Server-Sent Events push the same deltas your web client already gets. The bridge lives on your existing oRPC procedure, not a third pub/sub.
Conflicts resolve at the row, not the row+timestamp table. The same Drizzle migration runs offline; the server applies the migration on first reconnect; the client and the server converge on the same schema.
{
"id": "org_2nK9xR",
"name": "Acme Labs",
"plan": "pro",
"mrr": 1127,
"seats": 8,
"stripe_customer_id": "cus_R8x2Wq"
}Wake the app for what matters. Don't wake it for what doesn't.
Push notifications route through the same background-job contract the rest of your app uses. A delayed job is a delayed push; a failed push is a retryable job. The queue's dashboard is the push dashboard.
Push targets resolve from the same query layer web push uses — org, role, last-active, geo. The targeting rules live next to the notification, not in a separate vendor console.
An in-app inbox the user can scan when push misses (or when they've silenced notifications). The inbox is a query against the same notification table your transactional mail reads — one source of truth.
What happened on the phone, end to end. Same traces as the web app, in the same dashboard.
OpenTelemetry spans from the device (cold start, first paint, network roundtrip) land on the same pipeline your HTTP routes already use. A 5-second cold start on a Pixel 7 has a trace ID you can grep.
Crash and ANR reports reference the trace ID of the failing request. The support engineer can answer 'why did this user get stuck on the checkout screen?' from a single run, not three.
Per-device battery cost and per-session network budget surface in the same dashboard as your server costs. A backround-job pattern that burns the user's battery is a bug, not a feature.
Stack
Process
Better Auth issues session tokens your native client validates against the same public keys. No separate identity store.
Drizzle models the offline cache shape on the client and the source of truth on the server. No glue code.
Observability traces from the mobile client land in the same dashboard as your web traces. Push notifications route through your existing queue.
Built on this
Production-ready starter templates, each deployed at its own URL. Used as the reference set for what the registry can ship.
Explore
Two doors
Self-serve gives you the registry and the templates. Engagement gives you the team that built it. Pick the door that fits the timeline.