DEV Community

Russel Dsouza
Russel Dsouza

Posted on

Migrating a Supabase Local Dev Project to Tinbase in 10 Minutes

If you run Docker-based Supabase for local development and want to try the same stack on a single binary, this is the walkthrough. It takes about ten minutes for a typical project and nothing about it is destructive.

Tinbase is a Supabase-compatible runtime that ships as one executable. Your app code doesn't change, the SDK is the same, only the connection string and the way you boot the backend differ.

  • Install the binary, dump your schema, import it, swap the connection string
  • Your Docker Supabase state is never touched, so rollback is a git checkout away
  • Auth and realtime work through the same @supabase/supabase-js client
  • Edge functions and non-standard extensions are where the gaps are

Prerequisites

  • macOS, Linux, or Windows
  • A working Docker-based Supabase local environment you can currently run
  • A Node project using @supabase/supabase-js

This assumes your app connects through the standard SDK. Direct low-level Postgres connections work too, but aren't covered here.

Step 1: install the binary

curl -fsSL https://tinbase.dev/install.sh | sh
Enter fullscreen mode Exit fullscreen mode

If you'd rather not pipe a script into a shell, download and read it first. Same URL, no pipe.

Verify the install:

tinbase --version
Enter fullscreen mode Exit fullscreen mode

Step 2: dump your Supabase schema

With Docker Supabase running:

supabase db dump --file schema.sql --schema public
Enter fullscreen mode Exit fullscreen mode

That produces a schema.sql containing your tables, functions, RLS policies, and triggers.

The auth schema doesn't need exporting. Both platforms manage it themselves, and importing one over the other creates conflicts rather than continuity.

Step 3: import into Tinbase

Start in a fresh directory:

mkdir tinbase-dev && cd tinbase-dev
tinbase up
Enter fullscreen mode Exit fullscreen mode

In a second terminal, import:

tinbase psql -f ../schema.sql
Enter fullscreen mode Exit fullscreen mode

Confirm the tables landed:

tinbase psql -c '\dt public.*'
Enter fullscreen mode Exit fullscreen mode

If this errors, read the message rather than re-running. Import failures are almost always a missing extension, and the error names it.

Step 4: point your app at it

Docker Supabase serves on 54321. Tinbase uses a different default port, configurable through an environment variable.

- SUPABASE_URL=http://localhost:54321
- SUPABASE_ANON_KEY=eyJhbGciOiJI...
+ SUPABASE_URL=http://localhost:8080
+ SUPABASE_ANON_KEY=<from `tinbase config show`>
Enter fullscreen mode Exit fullscreen mode

Run tinbase config show to get the anon key for your local instance. It's different from your Docker Supabase key, which is the step people miss and then spend twenty minutes debugging a 401.

Step 5: verify

Three checks, in this order:

  1. Sign up a test user through your app's normal signup flow, then confirm the row exists:
tinbase psql -c 'SELECT id, email FROM auth.users'
Enter fullscreen mode Exit fullscreen mode
  1. Sign in as that user and confirm a protected route resolves. This exercises JWT issuing and verification, which is the part most likely to differ.

  2. Trigger a realtime change if your app subscribes to anything, and confirm the subscription fires.

If all three pass, you're done. If step two fails, it's the anon key from step four.

Rolling back

Your Docker Supabase state was never modified.

git checkout .env
supabase start
Enter fullscreen mode Exit fullscreen mode

That's the entire rollback. Worth knowing before you start, because it changes how much you need to think about this.

What doesn't migrate cleanly

Known gaps, worth checking against your project before you begin:

  • Edge functions written for Deno. Tinbase runs a v8 isolate rather than Deno, so Deno-specific APIs need adjusting.
  • Uncommon Postgres extensions. The widely used ones are preloaded; anything niche may not be.
  • Storage. Tinbase uses the local filesystem rather than S3-compatible object storage, which is usually what you want locally but differs from production.

For a standard project using Postgres, auth, realtime, and the JS client, none of these apply.

That third one is worth a thought regardless of which tool you use. If your local storage layer behaves differently from production storage, you have a category of bug that only appears after deploy, and no local setup will surface it.

Why bother

The honest version: if Docker Supabase boots fast enough on your machine and you never avoid running it, there's no problem to solve here.

The case for a single binary is about the days you'd otherwise skip local entirely. Boot time and memory footprint determine whether a local environment gets used, and an environment nobody runs is one that quietly stops working.

Full docs and source are at tinbase.dev. MIT licensed.


If you try this, I'm interested in what broke. Particularly edge functions, since that's the gap where "small syntax adjustments" covers a wide range of actual experiences.

Top comments (0)