Native apps
Expo in 5 minutes
Install the SDK and native session storage:
bun add @aussieljk/auth @better-auth/expo
npx expo install expo-secure-store expo-web-browser
Scaffold the client, layout provider, sign-in route, and app scheme:
bunx aussieauth init expo --scheme myapp
Set environment variables:
EXPO_PUBLIC_AUSSIEAUTH_URL=https://your-deployment.convex.site
EXPO_PUBLIC_CONVEX_URL=https://your-deployment.convex.cloud
Register the native origins with the AussieAuth deployment:
bunx aussieauth apps register \
--auth-url "$EXPO_PUBLIC_AUSSIEAUTH_URL" \
--secret "$AUSSIEAUTH_SECRET" \
--slug myapp \
--name "My App" \
--scheme myapp \
--dev-exp
Use the native card in app/sign-in.tsx:
import { AussieAuthNativeSignIn } from "@aussieljk/auth/native";
import { router } from "expo-router";
import { authClient } from "../lib/auth-client";
export default function SignIn() {
return <AussieAuthNativeSignIn authClient={authClient} onSignedIn={() => router.replace("/")} />;
}
Protect routes with the Expo helpers:
import { RequireAuth } from "@aussieljk/auth/expo";
import { authClient } from "../lib/auth-client";
export default function Home() {
return <RequireAuth authClient={authClient}>{/* app */}</RequireAuth>;
}
See examples/expo-router for a complete Expo Router app.
What the SDK provides
createAussieAuthExpoClientbuilds the Better Auth client with AussieAuth's methods, the Expo cookie/session bridge, cross-domain auth, and Convex token support.AussieAuthProviderwraps the usual Expo app setup: native auth client plusConvexBetterAuthProvider.AussieAuthNativeSignInis a React Native sign-in surface usingScrollView,TextInput, andPressablerather than DOM/CSS.RequireAuth,RedirectIfSignedIn,useAussieUser, andsignOutAndRedirectcover the common route flows.aussieauth apps registerregistersmyapp://and optionallyexp://with the existing/apps/registerendpoint.
No Origin header
A native app has no Origin header, so @better-auth/expo sends its deep-link
scheme as expo-origin and the server-side expo() plugin rewrites it back
onto the request.
Everything downstream — CSRF, trustedOrigins, appMethods, the session's
appId — then works unchanged.
The plugin has a second job on OAuth callbacks: it appends the session cookie to
the myapp:// redirect, because a native app has no cookie jar the browser can
write to.
Scheme origins
Native apps register scheme origins rather than URLs:
{
"slug": "myapp",
"name": "My App",
"origins": ["myapp://", "exp://"]
}
Only the bare scheme is accepted, because these match by prefix.
That's what makes Expo Go work: its origin is exp://<lan-ip>:8081/--/, which
changes with the network and so can never be registered exactly.
Prefix matching is confined to non-http origins. Doing it for web origins would
mean https://myapp.com claiming https://myapp.com.evil, and registration
refuses a bare https:// for the same reason.
Production notes
Trusting exp:// means any Expo Go project can reach the deployment. Use it for
development deployments, not production.
Passkeys shared with the website need APPLE_APP_SITE_ASSOCIATION set and a
real bundle id. Expo Go runs as Expo's bundle id, so associated-domain behavior
only applies to development or production builds.