Installing the Expo app | Expo Supabase SaaS Kit

Start a new project from the Expo kit, or add the Expo app to a Makerkit Next.js + Supabase project you already have, using the CLI plugin.

There are two ways to get the Expo app. Which one you want depends on whether you are starting a project or adding mobile to one that already exists.

Start from this kitAdd as a plugin
You haveNothing yetA Makerkit Next.js + Supabase project
You getapps/web and apps/native together, already wiredThe same apps/native, copied into your repo and wired to it
Howgit clonenpx @makerkit/cli@latest plugins add expo
Your existing workN/AUntouched — the plugin only adds files and edits config
Kit variantsThis kit onlynext-supabase only — see below

Both end at the same place: an Expo app in apps/native, sharing a Supabase project and the @kit/* packages with the web app. If you are starting fresh, take the first path — it is a clone, with nothing to go wrong.

Option 1 — start from the Expo kit

This repository is a complete Makerkit kit. It contains the full Next.js web app and the Expo app, already wired together. Cloning it gives you both.

git clone https://github.com/makerkit/expo-supabase-turbo-saas-kit.git my-app
cd my-app
pnpm install

Point origin at your own repository:

git remote set-url origin https://github.com/<you>/<your-repo>.git
git push -u origin main

Then start the web stack and the app. docs/native/running-locally.mdoc covers this in full — including which URL each device class needs — but the short version is:

pnpm run supabase:web:start # local Supabase
pnpm run dev # the Next.js app on :3000
pnpm run ios:native # or: pnpm run android:native

The committed apps/native/.env.development already points at the local Supabase stack and the local web app, so there is nothing to configure before the first run.

Option 2 — add the Expo app to an existing project

If you already have a Makerkit project, the CLI installs the Expo app as a plugin. It copies apps/native, packages/mobile-ui and the /api/v1 routes into your repo, then edits your config files to wire them up.

Before you start

RequirementWhy
Makerkit 4.xThe plugin targets the v4 line. Earlier kits will not take the wiring cleanly.
The next-supabase variantThe plugin declares no configuration for the Drizzle, Prisma, React Router or TanStack variants, and the CLI refuses to install it on them.
GitHub access to makerkit/expo-supabase-turbo-saas-kitThe files are fetched from that repository over HTTPS or SSH.
A committed working treeThe install edits many files at once. Commit first so you can read the result as a single diff.

Install

npx @makerkit/cli@latest plugins add expo

The CLI detects your kit variant, then hands off to the codemod that does the work. You can also run that codemod directly, without the CLI:

npx codemod @makerkit/next-supabase-expo

Run either from the root of your repository.

To install from a specific branch, tag or commit of the Expo kit rather than main:

EXPO_KIT_REF=v1.2.3 npx codemod @makerkit/next-supabase-expo

What it adds

PathWhat it is
apps/nativeThe Expo app
packages/mobile-uiReact Native UI components (@kit/mobile-ui)
apps/web/app/api/v1The REST API the app calls, authenticated with a Supabase bearer token
packages/features/accounts/src/schema/update-personal-account.schema.tsShared by PATCH /api/v1/accounts/personal and the native update hook
tooling/scripts/src/i18n-native.mjsGenerates the app's message catalogue from the web app's
docs/nativeThis documentation

What it changes

These are edits to files you already own. Each one is an AST transform rather than a text replacement, and each is idempotent.

FileChange
pnpm-workspace.yamlAdds catalogs.expo (React Native and Expo SDK versions), overrides, and aes-js, use-intl, @formatjs/intl-pluralrules, @types/aes-js to the root catalog
package.jsonThe ten *:native scripts
apps/web/package.jsonAdds @kit/otp, used by /api/v1/otp/send
apps/web/supabase/config.tomlAllows the mkkit:// OAuth callback
.oxlintrc.jsonBans web's password schemas inside apps/native; ignores .expo, the generated catalogue and the generated mobile UI components
.oxfmtrc.jsoncStops the formatter fighting the generated catalogue
tooling/scripts/package.jsoni18n:native and i18n:native:check
packages/features/team-accounts/package.jsonExports the per-seat billing service, which /api/v1 needs
packages/features/team-accounts/src/server/api.tsAdds getInvitationById and getPendingInvitationsForEmail
packages/features/team-accounts/src/shared/types.tsAdds the PendingInvitation shape
packages/features/accounts/src/shared/index.tsRe-exports the personal account schema

The repo-wide build, typecheck and test turbo tasks are deliberately left alone — the native workspaces join as ordinary workspace members, so the existing tasks already cover them.

What it runs

After the file copy and the config edits, the workflow runs pnpm install, regenerates the message catalogue, then typechecks and formats. The catalogue step matters: apps/native ships a messages.generated.ts built from this kit's web strings, so it is rebuilt against yours. Otherwise your app would render the kit author's copy — a different product name, different wording, and none of your locales. See docs/native/i18n.mdoc.

After installing

The .env.development that ships with the app points at the standard local ports, so it usually needs no change. Confirm these three match your setup:

EXPO_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321
EXPO_PUBLIC_SUPABASE_PUBLIC_KEY=<your local publishable key>
EXPO_PUBLIC_API_BASE_URL=http://localhost:3000

Then restart Supabase so it picks up the new redirect URL, and start the app:

pnpm run supabase:web:reset
pnpm run start:native

Sign in with Apple is off by default — it needs a paid Apple Developer account, and enabling it changes what your iOS builds require. See docs/native/config-requirements.mdoc.

Keeping it updated

The Expo plugin is self-distributing: it brings its own files rather than receiving them from the plugin registry, because the registry stores file contents as strings and cannot carry the app's binary assets. One consequence is that makerkit plugins update, plugins outdated and plugins diff do not track it — it is reported as up to date rather than failing. To take a newer version of the app, pull it yourself with EXPO_KIT_REF set to the ref you want, and review the diff.

Which files are yours now

However you installed it, everything under apps/native and packages/mobile-ui is your code to edit. docs/native/project-structure.mdoc explains where your own screens, components and hooks belong, and the one-way import rule that keeps the layers apart.

Read docs/native/running-locally.mdoc next.