# Frameworks

`npx scribase init` detects four project types from `package.json` and config
files, in this order:

| Detected as | When | Env file | Variables | Client file |
|---|---|---|---|---|
| `next` | `next` dependency or `next.config.*` | `.env.local` | `NEXT_PUBLIC_SUPABASE_URL`, `NEXT_PUBLIC_SUPABASE_ANON_KEY`, `SUPABASE_SERVICE_ROLE_KEY` | `lib/supabase.ts` (`src/lib/` with a `src/` folder) |
| `expo` | `expo` dependency, or `app.json` plus `react-native` | `.env` | `EXPO_PUBLIC_SUPABASE_URL`, `EXPO_PUBLIC_SUPABASE_ANON_KEY` | `lib/supabase.ts` (`src/lib/` with a `src/` folder) |
| `vite` | `vite` dependency or `vite.config.*` | `.env.local` | `VITE_SUPABASE_URL`, `VITE_SUPABASE_ANON_KEY` | `src/lib/supabase.ts` |
| `node` | anything else | `.env` | `SUPABASE_URL`, `SUPABASE_ANON_KEY`, `SUPABASE_SERVICE_ROLE_KEY` | `supabase.ts`, or `supabase.mjs` without `tsconfig.json` (under `src/` when it exists) |

Every run also writes `SCRIBASE_API_URL`, `SCRIBASE_ORG`, `SCRIBASE_PROJECT`
and `SCRIBASE_ENV`, adds the env file and `.scribase/` to `.gitignore`, and
installs `@supabase/supabase-js` with your package manager. Expo and Vite
projects never get the service role key, because their env values can end up
in the client bundle. The client file uses `.js` instead of `.ts` without a
`tsconfig.json`. An existing client file is kept.

## Per framework

| Framework | Detected as | Works as written? | The one edit |
|---|---|---|---|
| [Next.js](https://scribase.com/frameworks/nextjs) | `next` | Yes | None |
| [Expo](https://scribase.com/frameworks/expo) | `expo` | Yes | Optional: pass `AsyncStorage` as `auth.storage` to keep sessions |
| [React Native (bare CLI)](https://scribase.com/frameworks/react-native) | `expo` | Needs one edit | Metro without Expo does not inline `EXPO_PUBLIC_` values: put the URL and publishable key in `lib/supabase.ts` as constants |
| [Vite + React](https://scribase.com/frameworks/vite-react) | `vite` | Yes | None |
| [SvelteKit](https://scribase.com/frameworks/sveltekit) | `vite` | Yes | None; import as `$lib/supabase` |
| [Nuxt](https://scribase.com/frameworks/nuxt) | `node` | Needs one edit | Expose the pair through `runtimeConfig.public` and create the client in a composable |
| [Astro](https://scribase.com/frameworks/astro) | `node` | Needs one edit | Read `import.meta.env.SUPABASE_URL` instead of `process.env` |
| [Remix / React Router](https://scribase.com/frameworks/remix) | `vite` | Yes | Optional: move the client under `app/lib/` |
| [Node.js / Express](https://scribase.com/frameworks/express) | `node` | Yes | Start with `node --env-file=.env` |
| [Flutter](https://scribase.com/frameworks/flutter) | not supported | Manual | Use `supabase_flutter` with the URL and publishable key from the console, passed with `--dart-define` |

Each linked guide shows the real terminal output, the env file, a first
query and a prompt to paste into your coding agent.

## For coding agents

Run `npx scribase init --yes --json` in the project root. On success it prints
one JSON object with `framework`, `env_file`, `env_vars`, `client_file` and
`api_url`. If nobody is signed in it returns
`{"ok":false,"error":{"code":"authorization_pending",...}}` with a
`verification_uri_complete` and `user_code`: show those to the person, wait
for approval, and run the same command again. Never print the env file.

After init, create tables with the MCP server or migrations (see
[Connect your agent](https://docs.scribase.com/docs/agents/setup.md)), keep row-level security on for
every table the publishable key can reach, and use the service role key only
in server code.
