Quickstart: your first project in 5 minutes

Create a SupaHost project, copy its URL and keys, make a table with Row Level Security in Studio, then read and write it from JavaScript and sign up your first user.

This guide takes you from an empty instance to a working table you can query from code. It uses a small recipe app as the example. You need a SupaHost account with an instance; if you don't have one yet, start the 7-day trial at supahost.app and choose a region close to your users (it can't be changed later).

1. Create a project

  1. In the dashboard, open Projects and click New project.
  2. Enter a name. Names are 2 to 30 characters of lowercase letters, digits and hyphens, for example app-one. The name becomes your project URL: https://app-one.acme.supahost.space if your instance is called acme.
  3. Create the project. It uses the Blank template, an empty Supabase project.

The project shows as provisioning for a short while, and you get an email when it is ready. During the trial you can have up to 3 projects.

2. Copy the URL and keys

Open the project and go to the Connect tab, then App. You'll see three values:

Value Label Where it goes
Project URL Every client
anon key public Browser and mobile apps. Safe to ship, because Row Level Security decides what it can do.
service_role key secret (click Reveal) Servers only. It bypasses Row Level Security.

Put them in environment variables rather than in your code:

SUPABASE_URL=https://app-one.acme.supahost.space
SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIs...

The Overview tab also has a ready-made .env block you can copy.

3. Create a table

Click Studio in the project header to open Supabase Studio. The first open takes about 20 seconds while Studio starts. Go to the SQL editor and run:

create table public.recipes (
  id bigint generated always as identity primary key,
  title text not null,
  minutes int,
  user_id uuid references auth.users (id) default auth.uid(),
  created_at timestamptz not null default now()
);

alter table public.recipes enable row level security;

grant select on public.recipes to anon, authenticated;
grant insert on public.recipes to authenticated;

create policy "Anyone can read recipes"
  on public.recipes for select
  to anon, authenticated
  using (true);

create policy "Signed-in users add their own recipes"
  on public.recipes for insert
  to authenticated
  with check ((select auth.uid()) = user_id);

insert into public.recipes (title, minutes)
values ('Tomato soup', 25), ('Flatbread', 40);

Row Level Security is what makes the public anon key safe. With RLS on and no policy, nobody can read the table through the API. The two policies above let anyone read recipes and let signed-in users add recipes that belong to them. Read Row Level Security before you put real data in a table.

4. Read the data

From a terminal, with your variables exported:

curl "$SUPABASE_URL/rest/v1/recipes?select=id,title,minutes" \
  -H "apikey: $SUPABASE_ANON_KEY"

From JavaScript, install the client:

npm install @supabase/supabase-js
// recipes.ts
import { createClient } from '@supabase/supabase-js'

const supabase = createClient(process.env.SUPABASE_URL!, process.env.SUPABASE_ANON_KEY!)

const { data, error } = await supabase
  .from('recipes')
  .select('id, title, minutes')
  .order('minutes')

if (error) throw error
console.log(data)
// [ { id: 1, title: 'Tomato soup', minutes: 25 }, { id: 2, title: 'Flatbread', minutes: 40 } ]

5. Sign up a user and write a row

Auth works out of the box with email and password. By default new users must confirm their email first. To try things quickly, go to the Auth tab, open Sign-in & security, turn on Skip email confirmation, and click Save sign-in settings. Changes apply within about a minute. Turn it back off before you launch.

const { error: signUpError } = await supabase.auth.signUp({
  email: '[email protected]',
  password: 'a-long-test-password',
})
if (signUpError) throw signUpError

const { data: recipe, error } = await supabase
  .from('recipes')
  .insert({ title: 'Lemon rice', minutes: 30 })
  .select()
  .single()

console.log(recipe, error)

The insert works because the client now sends the user's access token, and the column default fills user_id with auth.uid(). Try the same insert without signing in and you get a Row Level Security error instead.

When you keep email confirmation on, set the Site URL and Redirect URLs on the Auth tab so confirmation links send people back to your app. See Site URL and redirect URLs.

6. Connect an AI agent (optional)

If you use Claude Code, Cursor or another MCP client, the AI agents (MCP) page in the dashboard creates a token and a config snippet so the agent can list tables, run SQL and apply migrations in your project. See The SupaHost MCP server.

Next steps

Updated 11 November 2026 · View as Markdown · Something wrong or missing? Tell us