Skip to main content

Quickstart

Get EdgeBase running in under 5 minutes.

1. Create and Start

npx edgebase init my-app

That's it — one command. init scaffolds the project, starts the dev server, and opens the Admin Dashboard in your browser automatically. If you only want the files without starting a persistent session, use npx edgebase init my-app --no-dev.

The scaffolded project structure:

my-app/
├── edgebase.config.ts ← DB blocks, access rules, auth settings
├── config/
│ └── rate-limits.ts
├── functions/ ← App functions (DB/HTTP/schedule triggers)
│ └── health.ts
├── .env.development ← Local dev secrets (JWT keys auto-generated, git-ignored)
├── .env.development.example ← Template for dev env vars (committed)
├── .env.release.example ← Template for production env vars (committed)
├── .gitignore
├── package.json
└── wrangler.toml

The starter includes auth, storage, and a sample GET /api/functions/health endpoint, but it does not create a default app table for you.

The Admin Dashboard opens at http://localhost:8787/admin.

Restart Later

To restart the dev server after closing it:

cd my-app
npx edgebase dev

The dashboard opens automatically. Use --no-open to disable: npx edgebase dev --no-open

2. Install an SDK

npm install @edgebase/web

3. Define Your First Table

Add your first DB block to edgebase.config.ts:

import { defineConfig } from '@edgebase/shared';
import { rateLimiting } from './config/rate-limits';

export default defineConfig({
databases: {
app: {
tables: {
posts: {
schema: {
title: { type: 'string', required: true },
content: { type: 'text' },
},
},
},
},
},

auth: {
emailAuth: true,
},

storage: {
buckets: {
uploads: {},
},
},

serviceKeys: {
keys: [
{
kid: 'root',
tier: 'root',
scopes: ['*'],
secretSource: 'dashboard',
secretRef: 'SERVICE_KEY',
},
],
},

rateLimiting,

cors: {
origin: '*',
},
});

The local dev server reloads automatically. Once the config updates, the app.posts table appears in the dashboard and SDK calls below will work as-is.

If you prefer, you can do the same thing from the local Admin Dashboard in dev mode: create a database block first, then add the first table from the schema editor. Both flows write back to edgebase.config.ts.

4. Connect and Use

Localhost on mobile

http://localhost:8787 works from the browser on your dev machine. For mobile runtimes, use a device-reachable address instead:

  • Android emulator: http://10.0.2.2:8787
  • iOS simulator: http://127.0.0.1:8787
  • Physical device: http://<your-lan-ip>:8787
import { createClient } from '@edgebase/web';

const client = createClient('http://localhost:8787');

// Sign up
await client.auth.signUp({ email: 'user@example.com', password: 'password123' });

// Create a record
await client.db('app').table('posts').insert({
title: 'Hello EdgeBase!',
content: 'My first post.',
});

// Query records
const posts = await client.db('app').table('posts')
.where('title', 'contains', 'Hello')
.orderBy('createdAt', 'desc')
.limit(10)
.getList();
DB Blocks — Two Types, Any Name

EdgeBase databases are organized into DB blocks. There are only two types:

  • Single-instance — one database, no instance ID needed (D1 by default). Example: client.db('app')
  • Dynamic (instance: true) — one database per ID, physically isolated. Example: client.db('notes', userId)

The block name (app, notes, team, store — anything you want) is just a config key, not a reserved keyword. The quickstart uses a single-instance block; when you need per-user or per-team isolation, add a dynamic block in your config:

// Single-instance block — one DB for everyone
const posts = await client.db('app').table('posts').getList();

// Dynamic block — one DB per instance ID (isolated)
const notes = await client.db('notes', userId).table('notes').getList();

See Isolation & Multi-tenancy for details.

5. Deploy

# Cloudflare Edge (global serverless)
npx edgebase deploy

# Docker self-hosting
npx edgebase docker build
npx edgebase docker run

# Direct run (any Node.js server)
npx edgebase dev

Next Steps