start

Quickstart

Build an app with sign-in and stored data: one command, one install, about a dozen lines of code.

With your coding agent

Paste this one prompt into your coding agent (Claude Code, Cursor, Codex, or any agent that can read a URL). It reads the docs and builds against a local backend, free with no account or card.

Read https://docs.gemmein.com/llms.txt and take my app to its first paying customer.

The rest of this page is the same build by hand.

By hand

import { gemmein } from "@gemmein/sdk"

const g = gemmein("pk_test_...")

// Sign in with an emailed sign-in code, no passwords
await g.auth.sendEmailCode("user@example.com")
await g.auth.verifyEmailCode({ email: "user@example.com", code: "12345678" })

// Store data. The server enforces the collection's safety rule.
// Create the "tasks" collection first (see Collections below).
await g.collection("tasks").create({ title: "Buy milk", done: false })
const { records } = await g.collection("tasks").list()

Replace pk_test_... with your app key. On the local backend it is the pk_local_... key the backend prints, passed with { apiUrl: "http://127.0.0.1:4545" } as the second argument to gemmein(). In the cloud, every call needs an app key (pk_...), shown on the Your app page.

This guide starts from an idea, with nothing built yet. If you already have an app, read the fit assessment at the top of llms.txt first. It compares what you have with what Gemmein refuses and gives a verdict before you install anything.

Run it locally

Building locally is free and needs no account. You run no server and write no security rules: you choose each collection's rule once, and Gemmein enforces it. Start the local backend in your project folder:

npx -y gemmein dev

This starts a local backend on http://127.0.0.1:4545, with no signup, account or card. It prints sign-in codes in the terminal instead of emailing them and simulates checkout, so nothing leaves your machine. Its boot card prints the local app key.

Then install the SDK:

npm i @gemmein/sdk

The SDK is dependency-free pure ESM. With no bundler, copy dist/index.js from the package next to your HTML and import it from a <script type="module">. It works on any static host.

Move to the cloud

When the app works locally, run npx gemmein check to see what going live still needs. Then run npx gemmein sync. It signs you in at app.gemmein.com with a sign-in code, free and with no card. A card is needed only when you go live.

Building with an AI tool: the Your app page gives you a ready-made prompt that covers the whole SDK. Paste it into your AI tool. The machine-readable package guide, which covers what your code calls, is also included in the package.

Collections

You create collections. The SDK never does, and a new app has none. Locally, the first write to a collection that does not exist yet asks you in the dev terminal which of the seven safety rules it follows, or you run npx gemmein collection add <name> from a second terminal. In the cloud, add it on the dashboard's Collections page (one click) or carry it there with npx gemmein sync. There, a 404 unknown_collection means the collection doesn't exist yet.

Names use lowercase letters, numbers and underscores only: saved_games works and savedGames does not. A bad name throws the moment collection() is called.

Record shape

Records come back wrapped, with your fields under .data:

const task = await tasks.create({ title: "Buy milk", done: false })

// { id, data: { title, done }, createdAt, updatedAt, ... }
task.data.title   // ✓ "Buy milk"
task.title        // ✗ undefined, and if your UI shows blanks this is why

Sessions

Sessions persist across page reloads. Each person has one session: verifying a new code revokes that email's older sessions. A stale token throws auth_expired once and the SDK clears it; a retry (or signing in again) recovers.

Where next