supabase-rb-rb
Hotwire starter

Getting started

Clone the Hotwire starter, install dependencies, point it at a Supabase project, and sign in for the first time.

This guide takes you from a clean machine to a signed-in dashboard. Budget 15 minutes if you already have Ruby and Docker installed; 30 if you don't. No Node.js, no npm install — Importmap serves JavaScript directly.

Prerequisites

ToolVersionWhy
Rubymatches .ruby-version (currently 3.3+)App runtime. Install with rbenv, asdf, or mise.
Bundlerany recentgem install bundler after Ruby is installed.
SQLite3.8.0+Rails app data, Solid Cache, Solid Queue, and Solid Cable all run on SQLite. The sqlite3 CLI must be on PATH.
DockerrecentRequired by supabase start (local stack) and by the Kamal deploy. Optional if you point the kit at Supabase Cloud.
Supabase CLI2.xbrew install supabase/tap/supabase, or official install docs. Only needed for a fully local Supabase stack.
GitanyFor cloning.

Node.js is not required. JavaScript is served via Importmap; Tailwind is built by tailwindcss-rails from a precompiled binary.

1. Get the code

The starter is published as a standalone repo, not a generator — copy it, don't render it:

git clone https://github.com/supabase-ruby/starter-kit-hotwire my-app
cd my-app

Commit it into a fresh repo of your own, or keep the upstream remote if you want to pull future starter updates.

2. Run bin/setup

bin/setup --skip-server

bin/setup is idempotent — re-run it any time. It runs bundle install, runs bin/rails db:prepare (which creates the four SQLite databases — primary, cache, queue, cable), and clears log/ and tmp/. Pass --skip-server to skip the auto-launch of bin/dev (useful in CI or while you're still filling in .env), or --reset to drop and recreate the SQLite files.

3. Set environment variables

Copy the template:

cp .env.example .env

Rails does not auto-load .env — the file is read by your shell (via direnv, dotenv, or your process manager) before bin/dev runs. The supplied .env.example documents this at the top.

You need three Supabase values. Pick A or B depending on whether you want a fully local Supabase or a Cloud project.

A. Local Supabase via the CLI

From the project root:

supabase start    # boots Auth + Postgres + Studio in Docker

The CLI prints something like:

         API URL: http://127.0.0.1:54321
        anon key: eyJhbGciOi...
service_role key: eyJhbGciOi...

Copy each into .env:

CLI key.env variable
API URLSUPABASE_URL
anon keySUPABASE_ANON_KEY
service_role keySUPABASE_SERVICE_ROLE_KEY

The supabase/ directory is checked in — supabase start automatically applies the migrations under supabase/migrations/, including the public.notes table and its RLS policies.

B. Supabase Cloud

If you already have a project at supabase.com:

.env variableDashboard location
SUPABASE_URLProject Settings → API → Project URL
SUPABASE_ANON_KEYProject Settings → API → anon / public key
SUPABASE_SERVICE_ROLE_KEYProject Settings → API → service_role secret key

For the Notes view to render any rows, you'll need to apply the supabase/migrations/ files to the Cloud project — either link the project (supabase link --project-ref <ref>) and run supabase db push, or paste the SQL into the dashboard's SQL editor.

The service_role key is server-only. It's used by the gem for admin-side calls (account deletion, admin user lookups). Never expose it to browsers.

4. Boot the dev server

bin/dev

bin/dev runs Procfile.dev, which starts bin/rails server on port 3000 and bin/rails tailwindcss:watch on a second process. Tailwind's watcher rebuilds app/assets/builds/application.css on every app/assets/tailwind/application.css change.

Then open http://127.0.0.1:3000.

5. Sign up your first user

The public landing page at /welcome has Log in and Register CTAs. Click Register and fill in an email + a password of 12 or more characters.

What happens behind the scenes:

  1. The form POSTs to RegistrationsController#create (subclassed from Supabase::Rails::RegistrationsController).
  2. The gem calls Supabase Auth's sign-up endpoint with the anon key.
  3. Supabase emails a confirmation link. In development, the kit ships letter_opener_web — open http://127.0.0.1:3000/letter_opener to read it without a real inbox.
  4. Click the confirmation link in the email. Supabase confirms the account, sets the session, and redirects back to the kit.
  5. The gem's middleware unwraps the redirect, sets the encrypted sb-session cookie, and you land on / authenticated.

If you don't see the dashboard chrome (sidebar + user menu), the cookie wasn't set — see Troubleshooting → Cookie isn't being set.

6. Visit the notes page

open http://127.0.0.1:3000/notes

The view at /notes lists rows from public.notes scoped to the signed-in user. The list will be empty on a fresh project — insert a row through the Supabase Studio at http://127.0.0.1:54323 (Table Editor → notes → "Insert row", with user_id = <your user UUID>) and the row appears on refresh. The full pattern is covered in Architecture → Per-request Supabase client.

7. Run the tests

bin/rails test            # Minitest controllers + models
bin/rails test:system     # Capybara + headless Chrome system tests

To run the end-to-end suite against your local Supabase stack:

bin/e2e                   # boots/reuses `supabase start`, runs test/e2e/

bin/e2e is idempotent — if supabase start is already running it reuses it. First boot pulls Docker images and can take a few minutes. The full quality gate (bin/ci) chains everything together — see Deployment → CI.

Next

On this page