个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗A lightweight, Convex-style reactive backend: TypeScript functions, a typed document database and live queries. It runs as one Bun process on SQLite and ships as a single executable.
"use node" split.query, mutation, action, v.*, ctx.db, api.module.fn, useQuery. Code and LLM knowledge carry over.onebase doctor checks your project.ctx.components.limiter.limit({ ... }), in your transaction. Components can follow your tables through table hooks, with no triggers to wire up./_admin: browse and edit data, run functions, live logs, jobs and files.bun install
bun run example # runs example/ (a chat app) in dev mode on http://localhost:8090
In your own project:
my-app/
onebase/schema.ts
onebase/messages.ts
public/index.html optional frontend, served at /
onebase dev # codegen + restart on change
onebase doctor # check for mistakes
onebase serve # production
onebase deploy # push your code to a running server, no restart
Website and docs: https://abdullah-bl.github.io/onebase/ (source in docs/). The LLM guide is a one-page summary of the API to give an AI assistant.
1. Push with onebase deploy (like npx convex deploy): run onebase serve on the server once, then ship each change from your machine:
# .env.local (git ignores it)
ONEBASE_DEPLOY_URL=https://api.example.com
ONEBASE_DEPLOY_KEY=… # the server's admin key
onebase deploy # also: --dry-run, --rollback
The server checks the new schema against its data, updates indexes, and swaps the code in without a restart. Connected clients' live queries re-run on the new code. If a check fails, nothing changes.
2. Generic binary + functions folder (like PocketBase + pb_hooks):
bun run build:binary # → dist/onebase
sudo install dist/onebase /usr/local/bin/onebase # the binary goes on your PATH
server/
onebase/ # your .ts functions, loaded at startup
public/ # optional frontend
onebase_data/ # created automatically: db.sqlite, files/, admin.key
cd server && onebase serve --port 8090
Every flag has an environment variable, and onebase reads .env, .env.local, .env.production and .env.production.local (.env.development* for onebase dev).
Functions can import npm packages from a node_modules folder next to them.
3. Everything in one executable (functions + frontend embedded):
onebase build --out ./app # cross-compile with --target bun-linux-arm64 etc.
./app --port 8090 --data ./onebase_data
| Setup | Flags | Good for |
|---|---|---|
| SQLite (default) | none; data in ./onebase_data | one server, lowest latency and memory |
| SQLite + S3 backups | --backup s3://bucket/backups | one server, with a durable copy of the data |
| Postgres | --db postgres://user:pass@host/db | several instances behind a load balancer |
| MySQL 8 | --db mysql://user:pass@host/db | several instances, on an existing MySQL server (schema indexes aren't used) |
| Turso / libSQL | --db libsql://my-db.turso.io (+ $TURSO_AUTH_TOKEN) | managed SQLite, several instances |
| Files in S3 | --files s3://bucket/files | any of the above; works with AWS S3, Cloudflare R2, MinIO, etc. |
S3 credentials come from S3_ACCESS_KEY_ID / S3_SECRET_ACCESS_KEY / S3_ENDPOINT / S3_REGION (or the AWS_* equivalents). Postgres, MySQL and S3 support are built into Bun, so they don't make the binary bigger.
Multiple instances (Postgres / MySQL / Turso):
LISTEN/NOTIFY; for MySQL and Turso, a small commit log that each instance polls).Backups (SQLite):
VACUUM INTO) is gzipped and uploaded every --backup-every (default 1h). The newest --backup-keep (default 24) are kept.onebase backup, onebase backups and onebase restore [--at 20261022T03] [--force] handle one-off backups, listing and restores.| Endpoint | |
|---|---|
POST /api/query / mutation / action | { "path": "messages:list", "args": {} } → { status, value } |
WS /api/sync | live subscriptions, mutations and actions (used by the clients; protocol spec) |
GET /api/health | status |
GET /_onebase/client.js | browser client as an ES module (no build step needed) |
POST /api/storage/upload?token=… / GET /api/storage/<id> | file upload (via generateUploadUrl) and download |
your http.ts routes | webhooks etc. |
Send Authorization: Bearer <token> for auth: a built-in session token, or a token checked by the providers or authenticate() in onebase/auth.config.ts. Built-in sign-in lives under /api/auth/* (see docs/auth.md).
Clients: the JS/TS client (browser, React, Bun) ships with the package, with optimistic updates and offline support (docs/client.md). A Swift package for iOS and macOS lives in clients/swift (docs/swift.md), and the client protocol is the documented contract for any other platform.
documents table (JSON in SQLite, jsonb in Postgres). Each schema index becomes a partial expression index, so the database's planner chooses indexes for both withIndex and filter.read, write, publish, subscribe) with SQLite (bun:sqlite), Postgres and MySQL (Bun.SQL), and libSQL implementations. The same tests run against all four.REPEATABLE READ on Postgres).messages where channel = X, the latest 50). After a commit, only subscriptions whose reads overlap the writes re-run. Identical subscriptions share one execution, and results are pushed only when they change.<mount>.<table> in the same documents table; every database handle is scoped to the app's tables or one component's, and component calls reuse the nested query and mutation paths (one snapshot, or a savepoint in the caller's transaction).tsvector index on the documents table; MySQL a FULLTEXT side table.vector_distance_cos; Postgres uses a pgvector HNSW index; MySQL ranks in the server.<data>/files, with metadata in SQLite. Deletes inside a mutation only take effect if it commits.users table; password hashes (argon2id), OAuth links, sessions and one-time codes live in system tables, with tokens stored as SHA-256 hashes. External JWTs are verified with WebCrypto (RS256/384/512, PS256, ES256/384, EdDSA). Keys come from OIDC discovery or a JWKS URL, are cached, and are refetched when they rotate.bun test # engine + end-to-end tests (SQLite, local files)
# Also against Postgres (with pgvector), MySQL, libSQL and S3:
TEST_POSTGRES_URL=postgres://… TEST_MYSQL_URL="mysql://…?allowPublicKeyRetrieval=true" TEST_LIBSQL_URL=http://127.0.0.1:8080 \
TEST_S3_URL="s3://bucket/prefix?endpoint=http://127.0.0.1:9000" S3_ACCESS_KEY_ID=… S3_SECRET_ACCESS_KEY=… bun test
bun run typecheck # includes type-level tests in tests/types.ts
bun run build:assets # rebuild the embedded browser client and dashboard (src/client, src/dashboard)
bun run site # build the website into site/dist