About

An open-source project, not a product with a sales team.

Baselyra exists because Supabase and Appwrite are the right idea at the wrong size for a lot of projects. You want row-level-security-backed APIs over your own Postgres, an admin console and file storage. You do not want to operate fifteen containers to get them, and on a 1 GB VPS you cannot.

The premise

Most of a BaaS is not the product

A gateway, an auth service, a REST service, a realtime service, a storage service, an image proxy, a metadata service, a log pipeline, a function runtime, a pooler, a cache and a dashboard. Every one is a real engineering decision made by people solving problems at a scale most projects will never reach — and every one is a process, an image, a config file and an upgrade that lands on the person self-hosting.

Baselyra takes the parts small projects actually use and puts them in one process, so a single person can run it and read it. That is the entire thesis, and it is also the entire limitation: the things a fleet buys you are the things Baselyra does not have.

A TYPICAL SELF-HOSTED BaaS15 containersBASELYRA2 containerstraefikkonggotruepostgrestrealtimestorage-apiimgproxypostgres-metastudiovectoranalyticsfunctionssupavisorredispostgresone process each, one image each, one upgrade eachroughly 2–4 GB at idleNames taken from the compose files Supabase andAppwrite publish for self-hosting.baselyra-app-1node:22-alpineone Fastify process/auth/v1/rest/v1/storage/v1/realtime/v1/admin/v1/ai/v1/ (Studio)baselyra-db-1postgres:17-alpinetwo databases on one serverbaselyrapublic, auth, storagebaselyra_controlStudio accounts, auditone image, one `docker compose pull`, one log streamroughly 400–600 MB at idle
Names taken from the compose files Supabase and Appwrite publish.

Principles

The rules the code is actually held to

These are not aspirations on a page — they are in SPEC.md and CONTRIBUTING.md, and a pull request that breaks one does not land.

Eight runtime dependencies

fastify, five Fastify plugins, pg and nodemailer. No ORM, no query builder library, no Redis, no broker, no sidecar. Adding a ninth is a conversation, not a commit.

Postgres enforces authorisation

Rows are never filtered in JavaScript for security. Every user-facing query goes through the same transaction that sets the role and publishes the claims, and RLS decides. There is no second place to get it wrong.

No placeholders

No TODO, no stubbed handler, no mock data. Every endpoint on this site is implemented and works against a real database, which is why the roadmap page is a separate, honest list rather than a set of greyed-out buttons.

Comments say why, not what

The interesting comments in this codebase explain the DST rule in the cron parser, why AWS signing needs its own encoder, and why the control database exists. Nothing narrates a for loop.

Documentation ships with the change

A behaviour change with stale docs is an incomplete change. New behaviour a self-hoster can misconfigure gets a line in the relevant docs/ page, not just a code comment.

Say what is missing

The README has a section called “What is not built”, stated plainly, because finding out on day two is worse. This site keeps that habit.

How it is built

The whole thing, in one screen

repository layout
src/
  index.ts       Fastify bootstrap; mounts every prefix, serves the Studio
  config.ts      all configuration, read from the environment
  db.ts          two pools; query(), tx(), asRole() ← user data goes here
  jwt.ts         signJwt / verifyJwt / mintProjectKeys
  context.ts     the Caller behind a request
  errors.ts      ApiError and the SQLSTATE → HTTP map
  auth/          /auth/v1 — routes, service, password hashing, OAuth, SMS
  rest/          /rest/v1 — catalog introspection and the query compiler
  storage/       /storage/v1 — buckets, objects, signed URLs
  realtime/      ws /realtime/v1 — change feeds, broadcast, presence
  admin/         /admin/v1 — the Studio's API, schema tooling
  platform/      Studio accounts, tokens, roles
  import/        Supabase, Postgres, Appwrite, Firebase, SQL dumps
  ai/            /ai/v1 — the DeepSeek relay
  mail/          SMTP and template rendering
  metrics/       request metering, flushed to the control database
db/project/      *.sql for the project database
db/control/      *.sql for the control database
studio/          React 19 + Vite + Tailwind v4 admin console
sdk/js/          @baselyra/client — zero-dependency JS/TS client
scripts/         setup, migrate, smoke, backup, restore
deploy/          nginx and Apache vhosts
test/            node:test, one file per area

259

tests, node:test, no framework

21

test files, one per area

Node 22

TypeScript, ESM, strict

Postgres 17

the only datastore

Most tests need no database. Filter parsing, JWT handling, password hashing, template rendering, path safety, cron arithmetic, AWS signing and webhook signatures are all pure logic, deliberately, so they run anywhere in seconds: npm test.
Two databases on one server. The project database holds your tables, auth and storage. The control database holds Studio accounts, the audit log, import history and metering. The thing that grants access to the console does not live inside the thing the console administers.

Open source

Apache-2.0, and what that means here

One edition

There is no enterprise build, no licence key, no feature gate. Everything described anywhere on this site is in the repository, under the same licence.

LICENSE

No telemetry

Nothing phones home. There is no analytics code in the source to disable and no endpoint it reports to — the only outbound calls are the ones you configure.

What free does and does not mean

Contributions welcome

One logical change per pull request, a present-tense subject, and say what you ran. Docs updated in the same change. The layout, the conventions and the non-negotiables are all written down.

CONTRIBUTING.md

Especially welcome. A sign-in provider you needed that is not there. An SMS back end for a country the current six serve badly. A framework guide. A PostgREST corner the query compiler does not cover yet. And security reports — privately, never as a public issue.

Direction

Where this is going, and where it is not

Being built now

Edge functions. A second project on one instance, on top of the project registry, per-project pools and per-project JWT secrets that already exist. An S3 storage back end. Image transformations. Database webhooks and scheduled jobs, both working and under test but not yet part of the documented, released surface.

The detail, item by item

Deliberately out of scope

A hosted tier. Replication, failover and branching. A pooler of its own. An ORM. Telemetry. A ninth runtime dependency for something a hundred lines of the standard library already does. Each of these would be a real feature, and each would cost the one property that makes this project worth having.

Read it

The best argument for this project is its source.

One process, eight dependencies, and comments that explain the decisions. An afternoon is enough to know whether you trust it.