Introduction
onebase is a reactive backend you run yourself. You write your backend as TypeScript functions, store data in a typed document database, and clients subscribe to queries that update live when the data changes. It all ships as one executable file.
// onebase/messages.ts
export const list = query({
args: { channel: v.id("channels") },
handler: (ctx, { channel }) =>
ctx.db.query("messages").withIndex("by_channel", (q) => q.eq("channel", channel)).collect(),
});
export const send = mutation({
args: { channel: v.id("channels"), body: v.string() },
handler: (ctx, args) => ctx.db.insert("messages", args),
});// In your React app: re-renders whenever anyone sends a message.
const messages = useQuery(api.messages.list, { channel });#Why onebase
onebase follows Convex's programming model and API, and makes different trade-offs:
- Small. One Bun process with SQLite. It uses about 40 MB of memory at startup and needs no separate database server.
- Node and npm everywhere. Queries, mutations and actions all run in Bun, so any npm package works in any function. There is no
"use node"split. - One file to deploy. Copy the binary to a server and run it. The functions can sit next to it in a folder, or be compiled into it along with your frontend.
- Hard to misuse. Errors explain how to fix the problem,
.filter()picks indexes automatically, andonebase doctorcatches common mistakes. This matters when an LLM writes the code. - Grows with you. Start on SQLite. When you need several instances, switch to Postgres, MySQL or Turso with one flag.
#What's included
| Schema | Tables, validators, indexes, and checks on every write |
| Functions | Queries, mutations, actions and internal functions, with argument validation |
| Database | ctx.db, indexes, filters, ordering and pagination |
| Search | Full-text search indexes, live like any query |
| Live queries | WebSocket subscriptions that update only when relevant data changes, with offline support |
| Client protocol | The wire contract every client implements — JS, Swift, and yours |
| Swift client | iOS and macOS apps: live queries, auth, optimistic updates, offline |
| Scheduling | runAfter / runAt, plus cron jobs that survive restarts |
| File storage | Uploads and downloads, on local disk or in S3 / R2 / MinIO |
| Auth | Built-in password and OAuth sign-in with sessions, or tokens from Clerk, Auth0, WorkOS and any OIDC provider |
| HTTP actions | Webhooks and custom HTTP endpoints |
| Components | Reusable packages with their own tables, such as the built-in rate limiter and aggregate, called as ctx.components.<name> |
| Databases | SQLite, Postgres, MySQL or Turso, including multiple instances |
| Backups | SQLite snapshots to S3, with restore |
| Dashboard | Browse and edit data, run functions, and watch logs, jobs and files at /_admin |
#When to use something else
onebase is a young project. Use Convex if you want a managed service and a team supporting it. Use onebase if you want to own the whole stack, run it on a small VPS or your own hardware, or need full Node.js in every function.
Next: Quick start.