npm packages
Groveback publishes nine packages under the @groveback scope: five you install and four
platform binaries npm resolves for you. They are packaging shells around one repository —
nothing here is a separate project, and the versions move independently.
| Package | Install as | Runs | What it is |
|---|---|---|---|
@groveback/server |
dev dependency | your machine | The whole backend as a standalone binary. No database needed. |
@groveback/cli |
dev dependency | your machine | grove — links an app to a project, generates a typed client, runs the local server. |
@groveback/sdk |
dependency | browser & server | The end-user client: auth, collections, storage, realtime, vector, GraphQL. |
@groveback/testkit |
dev dependency | your test runner | Invokes function handlers in-process with the platform’s semantics. |
@groveback/mcp |
via npx |
your MCP client | Exposes the admin API to an LLM as tools. |
All five are Apache-2.0, ESM-only, and require Node ≥ 18. None of them needs Bun installed — the server binary carries its own runtime.
The other four — @groveback/grove-darwin-arm64, -darwin-x64, -linux-x64, -linux-arm64 —
are the compiled server, one per platform. Never install them directly.
@groveback/server declares them as optionalDependencies pinned to its own version, and npm
downloads only the one matching your host. They exist on the registry because npm resolution
requires it, not because they are a separate product.
Which ones do I need?
Section titled “Which ones do I need?”Most apps end up with three:
npm i -D @groveback/cli @groveback/server # the local loopnpm i @groveback/sdk # what your app talks toAdd @groveback/testkit once you write functions, and wire up @groveback/mcp if you want to
build the backend by conversation. Building against a hosted project rather than a local one?
Drop @groveback/server — the CLI talks to a remote server without it.
@groveback/server
Section titled “@groveback/server”The backend itself, compiled. grove dev spawns it, and you can also run it directly:
npx grovebackThe package you install is a thin Node wrapper. The actual executable comes from one of the
four @groveback/grove-<os>-<cpu> packages, declared as optionalDependencies with os/cpu
constraints — so an install downloads a single ~60-100 MB binary rather than all four. This is
the same pattern esbuild and rollup use. Baked into each binary: the function worker, the
built dashboard, and the version.
If the wrapper cannot find its binary, the install skipped optional dependencies — reinstall
without --no-optional.
There is no API surface to import; the package is a groveback executable and nothing else.
→ The local loop · Self-hosting
@groveback/cli
Section titled “@groveback/cli”Plain Node, zero runtime dependencies, so it is CI-safe. Two jobs: generating a typed client from a project’s live collections, and running the local development loop.
The package installs a bin named grove — that is why the docs say npx grove … rather
than npx @groveback/cli …. Both work once it is a dependency, and both run the same pinned
local copy.
npx grove init # link the app to a project (writes grove.json)npx grove gen # write a typed client from the live schemanpx grove dev # start a local server, no databasenpx grove pull/push # move config between local and remoteWith nothing installed, name the package and pin the tag —
npx -y @groveback/cli@latest dev — otherwise npx has no grove bin to resolve, and reuses
its cache rather than fetching the newest release.
The admin key comes from $GROVE_ADMIN_KEY or --key, and is never written to grove.json
or into the generated client.
→ grove CLI reference — every command and flag
@groveback/sdk
Section titled “@groveback/sdk”What your application code imports. One factory returns everything, and it talks only to the public REST and WebSocket API — the same surface any HTTP client would use.
import { createClient } from '@groveback/sdk';
const client = createClient({ baseUrl: 'https://api.example.com' });Browser-targeted, side-effect free, so it tree-shakes. It covers auth (including MFA and OAuth), collection CRUD, storage, realtime subscriptions, vector search and GraphQL.
Not the same thing as the client grove gen writes: that generated file is typed against
your collections and uses the SDK underneath.
@groveback/testkit
Section titled “@groveback/testkit”Unit-tests your function handlers in your own runner — bun test, Vitest or Jest — so your
tooling instruments them for coverage. It mirrors the sandbox worker’s semantics in-process
and hands the handler an in-memory ctx.db.
import { invokeHttp } from '@groveback/testkit';
const res = await invokeHttp(handler, { body: { title: 'hi' } });Plain Node on purpose, no Bun dependency. A parity suite in the repo pins it to the real runner, so a passing testkit test means the same thing in production.
@groveback/mcp
Section titled “@groveback/mcp”An MCP server exposing the admin API as tools, so Claude Code, Claude Desktop, Cursor, Codex and other MCP clients can create collections, schemas, policies, roles, functions, users and seed data by conversation.
claude mcp add groveback_<projectSlug> \ -e GROVEBACK_URL=http://localhost:8080 \ -e GROVEBACK_API_KEY=gb_sk_proj_abc123.… \ -- npx -y @groveback/mcp@latestIt talks to a running server over REST and never imports server internals or touches the database — so it can only do what an admin API key could do anyway.
Versioning
Section titled “Versioning”Each package versions independently and follows semver from 0.x, where minor bumps may
break. Two couplings are exact rather than independent: the platform binaries are pinned to
@groveback/server’s version, and @groveback/cli spawns @groveback/server — so install
those two from the same release when you upgrade.
Source for all five lives under packages/ in the repository, which holds packaging shells
only — the code itself never leaves src/. See the
codebase map.