Baselyra Docs

FAQ

Short answers, with a link to the page that goes into it properly. If your question is a symptom rather than a question, Troubleshooting is the other page.

What it is

Is Baselyra a Supabase fork?

No. It shares the idea — Postgres with row level security behind an auto-generated REST API — and the REST dialect is a PostgREST-compatible subset so client patterns transfer. None of the code is shared. Baselyra is one Node process next to one Postgres container, with eight runtime npm dependencies and no Kong, GoTrue, PostgREST, Realtime, Storage, imgproxy or Vector.

How does it compare to Supabase and Appwrite?

BaselyraSupabase (self-hosted)Appwrite (self-hosted)
Containers2~12–15~10–20
Idle memory~400–600 MB~2–4 GB~2–3 GB
Fits a 1 GB VPSYesNoNo
DatabasePostgres 17PostgresMariaDB (+ Redis)
Authorisation modelPostgres RLSPostgres RLSPer-document permission strings
Upgradedocker compose pull && up -dCoordinated across servicesCoordinated across services

Where they win, plainly: Supabase has edge functions, read replicas, connection pooling at scale, branching and a hosted tier. Appwrite has server-side functions in many runtimes, messaging and a mature mobile SDK story. Baselyra has none of that. It has the parts most small projects actually use, in a footprint one person can run and reason about, and the source of one process to read when something goes wrong. If you need what they have, they are the honest recommendation.

Is it production ready?

It runs in production, it has an end-to-end smoke test, and the failure modes are documented rather than hidden — including the ones that are not fixed. What it does not have is replication, failover, or an S3 backend: one Postgres, one disk, and backups. Decide with that in front of you.

What licence?

Apache-2.0, with no contributor licence agreement, no open-core split and no paid tier. The whole thing is in the repository.

Is there telemetry?

No. Baselyra makes no outbound request you did not configure. Request metering is counted into the control database on your own machine and never leaves it. The only outbound calls the code can make at all are to your SMTP relay, your SMS provider, an OAuth provider you configured, a webhook target you created, and DeepSeek if you set a key.

Features

Does Baselyra support Google or GitHub sign-in?

Yes. Google, GitHub, LinkedIn, Facebook, Instagram, TikTok and Envato are built in; a provider appears only when both its client id and client secret are configured. There is no Apple sign-in. Phone one-time codes over SMS are also built in, with Twilio, Vonage, MessageBird, Amazon SNS, Plivo or a generic webhook sender. See Third-party sign-in and Phone codes.

Does Baselyra have edge functions?

No. Postgres functions called over POST /rest/v1/rpc/:fn are what there is, and they run as the caller so row level security still applies. Edge functions are in progress and not shipped In progress.

Are webhooks and scheduled jobs built?

Yes — database webhooks fired by a row change, signed with an HMAC and retried with backoff, and cron-scheduled jobs, both running in-process with their queue in the project database under /admin/v1/hooks/*. The Studio has no page for either yet, so they are configured through the API.

Can I store files on S3?

No In progress. Files live on the local disk of the host running the app, under STORAGE_ROOT, with their metadata in storage.objects so the same policies guard them as guard a table. Back that volume up alongside the database. There is also no image transformation: files come back exactly as they were uploaded.

Can I run more than one project on one instance?

Not today. control.projects holds a single row that every project lookup resolves through, so adding a switcher later is a change to one resolver, but nothing creates a second project and the Studio has no switcher In progress. Running two projects means running two stacks.

Does it do read replicas?

No. Configuration exists for listing standbys and the registry will probe their lag, but no request path routes reads to a replica today In progress — every query goes to the primary. Baselyra does not set up, monitor or fail over replication in any case.

How much memory does Baselyra need?

A 1 GB VPS is enough to start, and 2 GB is comfortable for production. At idle expect roughly 250 to 400 MB for Postgres with the shipped shared_buffers of 256 MB, and 80 to 150 MB for the Node process. Under load the Node side grows with concurrent uploads and open WebSockets.

Security and keys

Is the anon key a secret?

No. It is public and meant to ship in your frontend. It only names which Postgres role a request runs as; the policies decide what that role may read and write. The service key is the opposite — it bypasses every policy and belongs on a server only, never in a bundle, a mobile app or a NEXT_PUBLIC_* variable.

Why does my query return an empty array?

Almost always row level security, and it is working correctly. A policy denial is a 200 with an empty array, never a 403, because whether a row exists is itself information a policy can withhold. A table with RLS enabled and no policies denies everything to anon and authenticated, which is the safe default. The three checks settle it in a minute.

What happens if I forget to turn RLS on?

How do I give a user an admin role?

Put it in their app_metadata, which only the service key can write, and read it in a policy. There is no is_admin column and no auth.is_admin() function — both were removed, because they conflated your customers with your operators.

using ((auth.jwt() -> 'app_metadata' ->> 'role') = 'admin')

Can a user of my app get into the Studio?

No, and there is no configuration that would let them. Studio accounts live in control.platform_users, in a different database, and their tokens carry a typ: "platform" claim inside the signature that exactly one endpoint mints. Postgres has no cross-database queries without FDW, so a project connection cannot even read a Studio password hash while holding the service key.

What happens if I rotate JWT_SECRET?

Every access token, every refresh token, both project keys and every Studio session become invalid at once. Everyone signs in again and every client needs the new anon key. It is also the only way to revoke a leaked service key, because there is no per-key revocation list — so it is a deliberate act, not a routine one.

Using it

Can I move an existing project onto Baselyra?

Yes, from Supabase, plain Postgres, Appwrite, Firebase or a pg_dump file. Supabase and Postgres bcrypt password hashes come across intact, so those users never have to reset a password. Appwrite hashes with argon2 and Firebase uses a keyed scrypt, so accounts from those two arrive with an unusable password and must go through recovery. See Importing.

Can I just use psql?

Yes, and you should when it is the right tool. It is your Postgres: the tables are ordinary tables, the policies are ordinary policies, and nothing in Baselyra requires you to go through its API. Two things to remember — DDL run outside /admin/v1 is invisible to the REST catalog for up to a minute, and the baselyra and control schemas are Baselyra's own bookkeeping rather than yours.

Do I need the JavaScript client?

No. It is a convenience over an API that is plain HTTP with JSON and three headers. There are complete hand-rolled clients for Dart, PHP and Python in these docs, and anything that can make an HTTP request can talk to Baselyra.

Why do bigint and numeric come back as strings?

Because a JavaScript number cannot hold either exactly. Baselyra installs identity parsers for those two Postgres oids so the JSON is exact — a numeric(12,2) of 1250.00 stays "1250.00" rather than becoming a float that might not. Parse it where you need arithmetic.

Why is an unfiltered DELETE refused?

Because one forgotten query parameter in client code otherwise empties the table, and row level security does not save you — the policy allows those rows, the client simply asked for all of them. If you really mean every row, send Prefer: unsafe-mutation, or call .unsafeMutation() in the client.

How do I do a join?

Embed one level of related resource through a foreign key, or write a Postgres function and call it over RPC when you need more:

?select=id,title,author:users(id,name),comments(id,body)

Only one level is supported, deliberately — the second is where the query plan stops being predictable. Embedded resources.

Can I use my own Postgres?

Yes. Point DATABASE_URL at it. The role needs to be able to CREATE DATABASE (Baselyra creates the control database), CREATE ROLE — two of them with BYPASSRLS — and CREATE EXTENSION for pgcrypto, citext and pg_trgm. Ideally it is not a superuser; see the hardening checklist.

How do I get help?

Read the error's code first — it is stable and every page here lists the ones it can produce. Then Troubleshooting. Then the repository's issues. Redact before you paste: a log line can carry a connection string, and the audit log carries the text of every statement run in the SQL editor.

Edit this page Report a problem

Esc
navigate open Esc close