npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@specific.dev/replacebase

v0.3.1

Published

Drop-in replacement for Supabase's backend as a Typescript library

Downloads

243

Readme

Replacebase

Replacebase is a library to help you migrate away from Supabase over to backend infrastructure that you control. It's a simple Typescript library that wraps your Postgres database and S3 storage, and exposes a Supabase-compatible API. This means you don't have to change any frontend logic and can unify all your backend code for a simpler architecture.

There are many reason to use Replacebase:

  • Host your backend where you like, for example on AWS or Specific
  • Reduce your dependency on Supabase services and their uptime
  • Use a better database and storage provider, like Planetscale or Specific
  • Gradually migrate away from using Supabase SDKs to a more flexible backend architecture that you control
  • Replace inflexible Supabase services with better alternatives, like Better Auth

Replacebase implements many parts of Supabase (with more to come):

  • [x] REST API (can connect to any Postgres database)
  • [x] Auth (built on Better Auth)
  • [x] Storage (can connect to any S3-compatible service)
  • [x] Realtime (broadcast and presence)
  • [x] RPC
  • [ ] Edge functions
  • [ ] Vectors

This is an early-stage project, use it with care and test thoroughly before using in production

Installation

npm install @specific.dev/replacebase

Getting started

For this guide, we will use your existing Postgres database and Supabase-provided S3-storage and connect Replacebase.

We also offer a skill to let your coding agent help with the migration: npx skills add specific-dev/replacebase

1. Get your Supabase details

Sign in to your Supabase account and retrieve the following:

  1. Your Postgres connection string (click "Connect" in the top bar)

  2. Your JWT Signing Key URL (go to "Settings" -> "JWT Keys" -> "View key details" -> "Discovery URL")

  3. Your legacy JWT secret (go to "Settings" -> "JWT Keys" -> "Legacy JWT Secret")

  4. If using storage, your S3 connection details and access key (go to "Storage" -> "S3")

2. Serve up Replacebase

On your backend, initialise Replacebase with the details from step 1.

If you don't have anywhere to host your backend yet, we recommend Specific

// server.ts
import { createReplacebase } from "replacebase";

const replacebase = await createReplacebase({
  databaseUrl: process.env.DATABASE_URL!, // Supabase Postgres connection string
  jwksUrl: process.env.JWKS_URL!, // Supabase JWT Signing Key URL
  jwtSecret: process.env.JWT_SECRET!, // Supabase JWT secret
  // If using storage, pass Supabase S3 details
  storage: {
    s3: {
      endpoint: process.env.S3_ENDPOINT!,
      region: process.env.S3_REGION!,
      accessKeyId: process.env.S3_ACCESS_KEY_ID!,
      secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
    },
  },
});

Next you need to serve up the APIs that Replacebase exposes. Replacebase is framework-agnostic and works with any web server. Pick whichever fits your stack:

Since Next.js catch-all routes are mounted under a subpath, use the basePath option so Replacebase matches routes correctly:

// app/api/[...path]/route.ts
const replacebase = await createReplacebase({
  // ...
  basePath: "/api",
});

export const GET = replacebase.fetch;
export const POST = replacebase.fetch;
export const PUT = replacebase.fetch;
export const PATCH = replacebase.fetch;
export const DELETE = replacebase.fetch;

Note: Next.js API routes don't support WebSockets, so Realtime won't work with this setup. If you need Realtime, run Replacebase as a separate backend service.

import express from "express";

const app = express();
app.all("/*", replacebase.toNodeHandler());
const server = app.listen(3000);
replacebase.injectWebSocket(server); // Enables Realtime (broadcast + presence)
export default { fetch: replacebase.fetch };

For Realtime support on Node.js, use @hono/node-server to get an HTTP server you can inject WebSockets into:

import { serve } from "@hono/node-server";

const server = serve({ fetch: replacebase.fetch, port: 3000 });
replacebase.injectWebSocket(server);

3. Update your client config

The only change you need to make on your frontend is to connect to your own backend with Replacebase instead of Supabase.

import { createClient } from "@supabase/supabase-js";

const supabase = createClient(
  -"https://xyz.supabase.co",
  +"http://replacebase-api.spcf.app", // Insert wherever your Replacebase is served from
  // ...
);

That's it, test it out!

Next steps for migration

Replacebase is designed to be a stepping stone to a larger migration away from Supabase. Depending on your goals, you probably want to continue your migration by doing the following:

Change Postgres provider

Since Replacebase connects to any standard Postgres database, you can move off Supabase's hosted Postgres whenever you're ready. Spin up a database on AWS RDS, Specific, or any other provider, migrate your data with pg_dump/pg_restore, and update your DATABASE_URL. Your frontend code will keep working without changes.

Change storage provider

Replacebase works with any S3-compatible storage service. You can switch from Supabase's built-in storage to AWS S3, Cloudflare R2, Specific, or any other provider simply by updating your credentials. Migrate existing files with a tool like rclone or the AWS CLI.

Migrate away from the Supabase SDK

Once Replacebase is running, you can start building regular backend API endpoints alongside it. For example, replace a Supabase client query like supabase.from("posts").select() with a call to your own /api/posts endpoint. With Replacebase, you can do this gradually to move towards a more flexible backend design that better fits your product. Eventually, you can drop @supabase/supabase-js and Replacebase from your stack entirely!

License

MIT