scribase
One command + one edit

Add a backend to Nuxt with one command

init does not have Nuxt-specific conventions yet, so it treats a Nuxt app as a Node project: SUPABASE_URL and SUPABASE_ANON_KEY in .env and a client at the root. Nuxt code in the browser cannot read process.env, so move the client into a composable that reads runtimeConfig. That is the one edit.

What you see (your project URL will differ)terminal
$ npx scribase init
Backend ready: https://acme-my-app-production-c2b0ea0a.scribase.com
  framework   node
  project     acme/my-app (production)
  env file    .env (SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY, SCRIBASE_API_URL, SCRIBASE_ORG, SCRIBASE_PROJECT, SCRIBASE_ENV)
  client      supabase.ts

Next:
  - import { supabase } from './supabase' and query: await supabase.from('todos').select()
  - create tables with SQL migrations (supabase/migrations/*.sql) and `scribase db push`, or the MCP server

1.Run init

Run it in the project root. If you are not signed in, it prints a link and a code: approve it in the browser (sign up takes one click plus the $1 card check, credited back), and init carries on. No key is ever pasted. It creates the project, writes the env file, adds the env file to .gitignore, installs @supabase/supabase-js and writes a small client module.

bash
npx scribase init

2.Expose the public values through runtimeConfig

Nuxt loads .env in development and reads process.env when it builds the config. Only the public pair goes under public; the service role key stays server-only.

nuxt.config.tsts
export default defineNuxtConfig({
  runtimeConfig: {
    supabaseServiceRoleKey: process.env.SUPABASE_SERVICE_ROLE_KEY,
    public: {
      supabaseUrl: process.env.SUPABASE_URL,
      supabaseAnonKey: process.env.SUPABASE_ANON_KEY,
    },
  },
});

3.Replace the generated client with a composable

Delete supabase.ts at the root and add this. Nuxt auto-imports it everywhere.

composables/useSupabase.tsts
import { createClient, type SupabaseClient } from '@supabase/supabase-js';

let client: SupabaseClient | undefined;

export function useSupabase(): SupabaseClient {
  const { supabaseUrl, supabaseAnonKey } = useRuntimeConfig().public;
  client ??= createClient(supabaseUrl as string, supabaseAnonKey as string);
  return client;
}

4.Create your first table

Open your project in the console, go to Editor, then SQL, and run this. Or ask your coding agent: with the Scribase MCP server connected it applies the same SQL as a migration. Row-level security is on, so the public key can only read what the policy allows.

sql
create table public.todos (
  id bigint generated always as identity primary key,
  title text not null,
  done boolean not null default false,
  created_at timestamptz not null default now()
);

alter table public.todos enable row level security;

create policy "todos are readable" on public.todos
  for select to anon, authenticated using (true);

insert into public.todos (title) values ('Ship the backend'), ('Tell a friend');

5.Use it in a page

useAsyncData fetches on the server for the first render and hydrates on the client.

pages/index.vuevue
<script setup lang="ts">
const { data: todos } = await useAsyncData('todos', async () => {
  const { data, error } = await useSupabase().from('todos').select('id, title');
  if (error) throw error;
  return data;
});
</script>

<template>
  <ul><li v-for="todo in todos" :key="todo.id">{{ todo.title }}</li></ul>
</template>
Let your agent do it

Paste this into Claude Code, Cursor or Codex

The agent runs init, asks you to approve once in the browser, creates the table and wires up the first screen.

Nuxt setup promptprompt
Add a Scribase backend to this Nuxt app.
1. Run `npx scribase init --yes --json` in the project root. If it returns authorization_pending, show me the link and code, wait for me to approve, then run it again.
2. Create a `todos` table (id, title, done, created_at) with row-level security on and a policy that lets anyone read it; use the Scribase MCP server or a SQL migration, not the service-role key in app code.
3. Expose SUPABASE_URL and SUPABASE_ANON_KEY through runtimeConfig.public in nuxt.config.ts (service role key server-only), replace the generated root supabase.ts with composables/useSupabase.ts, and list the todos on pages/index.vue with useAsyncData.
4. Never print, log or commit the env file; it is already in .gitignore.

Connect the MCP server first so the agent can run SQL safely: connect your agent.

FAQ

Common questions

In production the values are empty. Why?

Nuxt reads .env only in development. In production set NUXT_PUBLIC_SUPABASE_URL and NUXT_PUBLIC_SUPABASE_ANON_KEY (Nuxt maps them onto runtimeConfig.public), or set the SUPABASE_ variables at build time.

Can I use a Nuxt module instead?

Any module built on supabase-js works, because Scribase speaks the same API. Point it at the same URL and publishable key.

Your Nuxt backend, live in a minute

$9 a month per project, flat. Sign up with one click; the $1 card check is credited to your first invoice.

Start now