OneBase

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, and onebase doctor catches 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

SchemaTables, validators, indexes, and checks on every write
FunctionsQueries, mutations, actions and internal functions, with argument validation
Databasectx.db, indexes, filters, ordering and pagination
SearchFull-text search indexes, live like any query
Live queriesWebSocket subscriptions that update only when relevant data changes, with offline support
Client protocolThe wire contract every client implements — JS, Swift, and yours
Swift clientiOS and macOS apps: live queries, auth, optimistic updates, offline
SchedulingrunAfter / runAt, plus cron jobs that survive restarts
File storageUploads and downloads, on local disk or in S3 / R2 / MinIO
AuthBuilt-in password and OAuth sign-in with sessions, or tokens from Clerk, Auth0, WorkOS and any OIDC provider
HTTP actionsWebhooks and custom HTTP endpoints
ComponentsReusable packages with their own tables, such as the built-in rate limiter and aggregate, called as ctx.components.<name>
DatabasesSQLite, Postgres, MySQL or Turso, including multiple instances
BackupsSQLite snapshots to S3, with restore
DashboardBrowse 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.