A minimal Backend-as-a-Service you own. Auth, database, REST API — all managed from your terminal. Self-hosted on any VPS.
Bun + Hono + SQLite. One command to deploy, one CLI to manage everything.
curl -fsSL https://based.weirdscience.dev/install.sh | shOr from source:
git clone https://github.com/WeirdScience-dev/based.git
cd based && bun install && bun run setup# Set up Based on any VPS
based init 51.83.44.93 --domain based.yourdomain.com
# Create a project
based new my-app
# Log in (auto-creates account)
based login my-app -e you@email.com
# Create tables — CRUD endpoints are instant
based table create posts title:text:required content:text status:text:default=draft
# Generate TypeScript types
based typegenThat's it. Your API is live at https://my-app.based.yourdomain.com.
bun add @weirdscience/based-clientimport { createClient, BasedProvider, useQuery, useMutation } from "@weirdscience/based-client";
import type { Tables } from "./based.d.ts";
const based = createClient({
url: process.env.NEXT_PUBLIC_BASED_URL!,
anonKey: process.env.NEXT_PUBLIC_BASED_ANON_KEY!,
});
function App({ children }) {
return <BasedProvider client={based}>{children}</BasedProvider>;
}
function Posts() {
const { data } = useQuery<Tables, "posts">("posts");
const { mutate } = useMutation<Tables, "posts">("posts", "create");
return (
<>
{data?.map(post => <div key={post.id}>{post.title}</div>)}
<button onClick={() => mutate({ title: "Hello" })}>New post</button>
</>
);
}| Command | Description |
|---|---|
based init <host> -d <domain> |
Set up Based on a VPS |
based deploy |
Push code updates to the server |
based new <name> |
Create a project |
based list |
List all projects |
based delete <name> |
Delete a project |
based login <project> -e <email> |
Log in to a project |
based logout |
Clear credentials |
based table create <name> <cols...> |
Create a table |
based table add-column <table> <cols...> |
Add columns |
based table drop-column <table> <cols...> |
Drop columns |
based table drop <name> |
Drop a table |
based table list |
List tables and columns |
based env <name> |
Print .env.local vars |
based typegen |
Generate TypeScript types |
name:type[:required][:unique][:default=value][:ref=table.column]
Types: text, integer, real, blob
Every project gets auth and auto-generated CRUD:
POST /auth/signup # { email, password } → tokens
POST /auth/signin # { email, password } → tokens
POST /auth/refresh # { refreshToken } → new tokens
POST /auth/signout # invalidate session
GET /api/:table # list (paginated, filterable)
GET /api/:table/:id # get one
POST /api/:table # create (auth required)
PUT /api/:table/:id # update (auth required)
DELETE /api/:table/:id # delete (auth required)
Anonymous read access via apikey header. Write requires a JWT.
packages/
server/ Hono API server (Bun + SQLite)
cli/ CLI tool (compiles to standalone binary)
client/ React SDK (useQuery, useMutation, useUser)
web/ Landing page + docs (Next.js)
- One server process handles all projects via subdomain routing
- Each project gets its own SQLite database in
/srv/based/projects/<name>/ - Tables are created via API — no schema files, no migrations
based typegenpulls types from the server for end-to-end type safety- Deployed as Docker container with Nginx reverse proxy
MIT