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

@akirilyuk/supabase-in-memory-server

v1.0.1

Published

In-memory HTTP server mimicking Supabase REST (PostgREST) and Auth (GoTrue) for supabase-js: local testing, e2e, anon/service-role keys, optional CLI, Winston logs

Readme

supabase-in-memory-server

npm package supabase-in-memory-server (formerly supabase-jest-mock).

In-memory HTTP server that mimics the parts of Supabase that @supabase/supabase-js talks to: PostgREST-style REST (/rest/v1/...) and GoTrue-style auth (/auth/v1/...). Use it in tests or local tooling without a real Supabase project—similar in spirit to an embedded mock, not a separate binary.

The server is implemented as MemorySupabaseHttpServer (request pipeline, shared MemoryStore + AuthMemory). createMemorySupabaseServer starts Node’s http.Server, resolves listen address and keys, wires Winston logging, and returns a handle you can close().

Requirements

  • Node.js 20.9+ or 22+
  • Peer dependency: @supabase/supabase-js ^2

Install

npm install supabase-in-memory-server @supabase/supabase-js

Quick start (programmatic)

import { createClient } from '@supabase/supabase-js';
import {
  createMemorySupabaseServer,
  applyMemorySupabaseEnvToProcess,
} from 'supabase-in-memory-server';

const srv = await createMemorySupabaseServer({ useEnv: false });

// Optional: expose the same values Supabase apps expect in process.env
applyMemorySupabaseEnvToProcess(srv);

const anon = createClient(srv.url, srv.anonKey, {
  auth: { persistSession: false, autoRefreshToken: false },
});

const { error } = await anon.from('todos').insert({ id: 1, title: 'Buy milk' }).select();
// ...

await srv.close();

Convenience: server + anon client

import { createTestSupabaseClient } from 'supabase-in-memory-server';

const { client, url, anonKey, serviceRoleKey, store, logger, close } =
  await createTestSupabaseClient();
// `client` is already createClient(url, anonKey, { auth: { persistSession: false, ... } })

await close();

Service role (admin) client

Use the service role key for auth.admin (e.g. listUsers). Never expose this key in browser bundles.

import { createClient } from '@supabase/supabase-js';
import { createMemorySupabaseServer } from 'supabase-in-memory-server';

const srv = await createMemorySupabaseServer({ useEnv: false });
const admin = createClient(srv.url, srv.serviceRoleKey, {
  auth: { persistSession: false, autoRefreshToken: false },
});

const { data, error } = await admin.auth.admin.listUsers({ perPage: 50 });
await srv.close();

What you get back from the server

createMemorySupabaseServer / startInMemorySupabaseServer resolve to an object with:

| Field | Description | | -------------------- | ------------------------------------------------------------------------------------------------------ | | url | Base URL, e.g. http://127.0.0.1:<port> | | anonKey | Anon API key (maps to SUPABASE_ANON_KEY) | | serviceRoleKey | Service role / admin key (maps to SUPABASE_SERVICE_ROLE_KEY) | | supabaseKey | Same as anonKey (legacy name) | | store | MemoryStore — in-memory tables for REST | | auth | AuthMemory — in-memory users and sessions | | server | Node http.Server | | logger | Winston Logger — lifecycle + per-request logs (see Logging below) | | close() | Stops the server and clears auth state (tables are not cleared unless you call store.clearAll()) |

Logging and debug mode

Logging uses Winston. Each HTTP request gets a 10-character hex requestId. In debug mode you will see:

  • Incoming request{ requestId, method, path, query } when the request enters the pipeline (including OPTIONS).
  • Request finished{ requestId, method, path } in a finally block when handling completes (success, early return, or error).
  • Handler-level debug lines for auth and REST (correlated via a child logger that carries requestId on every line).

Options

| Setting | Effect | | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | debug: true in server options | Root log level debug: full request/handler detail. | | debug: false (default) | Level info: listen/close and error / warn; routine traffic stays at debug (hidden unless you enable debug). | | SUPABASE_JEST_MOCK_DEBUG | If 1, true, or yes, sets debug when useEnv is not false. |

await createMemorySupabaseServer({ useEnv: false, debug: true });

To silence logs in noisy tests: srv.logger.silent = true.

You can also build a matching logger with createMemorySupabaseLogger(debug) if you construct MemorySupabaseHttpServer yourself (advanced).

Environment variables

By default (useEnv is not false), options are merged with the environment: env first, then explicit options override.

| Variable | Purpose | | ------------------------------- | ---------------------------------------------------------------------------------------------------- | | SUPABASE_URL | If set, host and port for listening are taken from this URL (e.g. http://127.0.0.1:54321). | | SUPABASE_JEST_MOCK_HOST | Overrides listen hostname after URL parsing. | | SUPABASE_JEST_MOCK_PORT | Overrides listen port after URL parsing. Use 0 for an ephemeral port. | | SUPABASE_ANON_KEY | Anon key used as the apikey header for the public client. | | SUPABASE_SERVICE_ROLE_KEY | Service role key for admin operations. | | SUPABASE_JEST_MOCK_DEBUG | Enables verbose debug logging (1, true, or yes). |

After the server is running, you can sync process.env to the actual URL and keys (recommended for apps that only read env):

import {
  createMemorySupabaseServer,
  applyMemorySupabaseEnvToProcess,
} from 'supabase-in-memory-server';

const srv = await createMemorySupabaseServer();
applyMemorySupabaseEnvToProcess(srv);
// process.env.SUPABASE_URL, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY

CLI

From the package install:

npx supabase-in-memory-server
  • Starts the in-memory server (honors the same env vars as above).
  • Writes SUPABASE_URL, SUPABASE_ANON_KEY, and SUPABASE_SERVICE_ROLE_KEY into process.env.
  • Prints a JSON object with those three keys to stdout.
  • Logs the listen URL to stderr (and Winston lifecycle lines unless silenced).
  • Exit with Ctrl+C (SIGINT) or SIGTERM.

Authentication and API keys

  • Every request must include header apikey equal to either anonKey or serviceRoleKey. Missing or wrong key → 401.
  • GET /auth/v1/admin/users requires the service role key (or Authorization: Bearer <serviceRoleKey>).

Implemented auth routes include: signup (email or phone), token (grant_type=password and refresh_token), logout, get user (GET /auth/v1/user), and admin list users (paginated). JWTs used by the mock are unsigned test tokens—do not use for real security.

REST (PostgREST-shaped)

Supported on /rest/v1/:table: insert, upsert (via Prefer: resolution=merge-duplicates / ignore-duplicates), select with common filters (eq, neq, gt, gte, lt, lte, is, in), order, limit / offset, update, delete, Prefer: return=representation, Prefer: count=…, and Accept: application/vnd.pgrst.object+json for .single() / .maybeSingle()-style behavior.

With Prefer: return=representation, PATCH returns the updated rows in the body: one row as a single JSON object, multiple rows as a JSON array (same convention as POST insert).

There is no RLS, no Realtime WebSocket, no Storage, no Edge Functions, no /rest/v1/rpc/..., and no full PostgREST operator set (see TODO below).

Publishing (maintainers)

GitHub Actions Release workflow (.github/workflows/release.yml) runs when you push a version tag:

  1. Set version in package.json to the release you want (e.g. 1.2.3).
  2. Commit that change on the default branch (e.g. main).
  3. Create and push a tag v + the same version: git tag v1.2.3 && git push origin v1.2.3.

The tag must be vMAJOR.MINOR.PATCH and match package.json exactly (e.g. tag v1.2.3"version": "1.2.3"). The workflow runs typecheck, lint, format check, build, and tests, then npm publish --access public (needed for scoped package names) and creates a GitHub Release with generated notes.

Repository secret: add NPM_TOKEN in the repo’s Settings → Secrets and variables → Actions. Use an npm access token with permission to publish this package (granular token for @scope/package, or a user token with publish rights).

API reference (exports)

The main entry is supabase-in-memory-server (dist/index.js). Notable exports:

  • createMemorySupabaseServer, startInMemorySupabaseServer — start the HTTP server.
  • createTestSupabaseClient — server + SupabaseClient with anon key.
  • applyMemorySupabaseEnvToProcess — set SUPABASE_* env from a running server.
  • MemorySupabaseHttpServer — HTTP app class (advanced: custom lifecycle, tests).
  • createMemorySupabaseLogger — Winston factory aligned with the server’s log format.
  • readMemorySupabaseServerEnv, resolveMemorySupabaseServerOptions, generateDefaultProjectKeys, MemorySupabaseServerInputOptions — configuration helpers.
  • MemorySupabaseServer, MemorySupabaseServerOptions, MemoryStore, AuthMemory, JsonRecord, etc.

See TSDoc on those symbols in the source for details.

TODO (toward a fuller in-memory Supabase mock)

This package intentionally covers a small, test-friendly slice of Supabase. A full in-memory mock would still need (non-exhaustive):

Auth (GoTrue)

  • [ ] OAuth / SSO providers, magic links, OTP, and phone SMS flows.
  • [ ] Additional auth.admin APIs: deleteUser, updateUserById, inviteUserByEmail, generateLink, etc.
  • [ ] MFA (TOTP, WebAuthn) and step-up semantics.
  • [ ] Session management: list/revoke sessions, refresh rotation edge cases matching production.
  • [ ] Password recovery / email change / user verification flows.
  • [ ] Stricter alignment with GoTrue error payloads, status codes, and headers.
  • [ ] Optional JWT signing/verification matching real projects (currently test-oriented tokens).

REST / PostgREST

  • [ ] RPC: POST /rest/v1/rpc/:function (and client .rpc()).
  • [ ] Embedded resources / foreign-table select shapes (profiles(*)).
  • [ ] More filter operators (like, ilike, fts, cs, cd, @>, range, or, and, not, etc.).
  • [ ] columns=, default values, generated columns behavior (as far as in-memory JSON allows).
  • [ ] Schemas / multiple schemas, views, and table exposure rules.
  • [ ] Row Level Security simulation (policies per role / JWT claims).
  • [ ] Transactions or batch semantics if clients rely on them.
  • [ ] Closer error codes and Prefer / Content-Range behavior vs real PostgREST.

Realtime

  • [ ] WebSocket server and postgres_changes (and channel/auth parity with Supabase Realtime).

Storage

  • [ ] S3-compatible or Supabase Storage REST: buckets, objects, signed URLs, MIME limits.

Edge Functions & platform

  • [ ] Edge Functions invoke path or local stub.
  • [ ] Database webhooks, pg_cron, and other backend-only features (usually out of scope for a pure HTTP mock).

Developer experience

  • [ ] Optional OpenAPI / schema endpoint mimicking PostgREST.
  • [ ] Snapshot / fixture helpers for common test scenarios.

Contributions that close items above are welcome; keep the default footprint small so Jest/CI stays fast.

Development

npm install
npm run build      # emit dist/
npm run typecheck
npm run lint
npm run format:check
npm test           # integration + e2e tests

License

MIT