Quickstart
Three ways in, depending on what you have. Pick one.
| You want | Start at |
|---|---|
| A backend on your machine, no database, no account | Local first |
| To run the whole thing yourself with Docker | Self-hosted |
| To build against a project that already exists | Link an existing project |
Local first
Section titled “Local first”mkdir my-app && cd my-app && npm init -ynpm i -D @groveback/cli @groveback/servernpx grove dev --seed --persistThat is the whole setup — no grove init, no URL, no key. It starts an empty project in
memory and prints a dashboard link with the key already in it:
http://localhost:8099/dashboard?key=gb_sk_proj_dev.…#/The CLI is plain Node with zero runtime dependencies. @groveback/server is the emulator
grove dev spawns — a standalone binary per platform, so it needs neither Bun nor a
database.
Next: create a collection, then read the local loop.
Self-hosted
Section titled “Self-hosted”git clone https://github.com/ideascoldigital/grovebackcd grovebackcp .env.example .env # set JWT_SECRET (openssl rand -base64 32)docker compose up -dcurl localhost:8080/api/v1/healthThis brings up the app plus a single-node MongoDB replica set — a replica set specifically, because realtime needs Change Streams. Full details in self-hosting.
To hack on the source instead, with Bun:
bun installbun run dev # in-memory backend on :8080 — data is lost on restartLink an existing project
Section titled “Link an existing project”You need the project id (proj_…) and an admin API key (gb_sk_…), which you create in the
dashboard under API Keys.
npm i -D @groveback/clinpx grove init --url https://api.example.com --project proj_abc123export GROVE_ADMIN_KEY=gb_sk_proj_abc123.…npx grove pull # mirror the project's shape into groveback/grove init writes grove.json. Commit it — it holds no secrets. The admin key is read
from the environment at the moment you run a command and is never written to disk.
Your first requests
Section titled “Your first requests”With the server running, register a user and create a document:
curl -X POST localhost:8080/api/v1/auth/register \ -H 'content-type: application/json' \ -d '{"email":"a@example.com","password":"correct-horse"}'curl -X POST localhost:8080/api/v1/auth/login \ -H 'content-type: application/json' \ -d '{"email":"a@example.com","password":"correct-horse"}'That returns an accessToken. Use it:
curl -X POST localhost:8080/api/v1/posts \ -H "authorization: Bearer $TOKEN" \ -H 'content-type: application/json' \ -d '{"title":"hola"}'With the SDK
Section titled “With the SDK”npm i @groveback/sdkimport { createClient } from '@groveback/sdk';
const client = createClient({ baseUrl: 'http://localhost:8080' });await client.auth.register('a@example.com', 'correct-horse');await client.auth.login('a@example.com', 'correct-horse');
const posts = client.collection('posts');const doc = await posts.create({ title: 'Hola' });const stop = posts.subscribe('insert', (event) => console.log('new post', event));Better still, generate a typed client from your live schema:
npx grove genimport { createGrove } from './src/grove/grove';
const grove = createGrove();await grove.auth.login('a@example.com', 'correct-horse');
const posts = await grove.collections.posts.find(); // Post[]await grove.collections.posts.create({ title: 'Hello' }); // PostInputSee the SDK reference and the CLI reference.
Build it by conversation
Section titled “Build it by conversation”Groveback ships an MCP server, so Claude Code, Claude Desktop or Cursor can create collections, schemas, policies, roles and functions for you:
claude mcp add groveback \ -e GROVEBACK_URL=http://localhost:8080 \ -e GROVEBACK_API_KEY=gb_sk_proj_abc123.… \ -- npx -y @groveback/mcpWhere next
Section titled “Where next”- Core concepts — the vocabulary, in one page.
- Collections and schemas — define your data.
- Authorization policies — decide who reads what.
- The local loop — pull, dev, push.