cli
SpacetimeDB CLI reference for initializing projects, building modules, publishing databases, querying data, and managing servers
SpacetimeDB C++ server module SDK reference. Use when writing tables, reducers, or module logic in C++.
Claude Code
$ npx -y skills add clockworklabs/spacetimedb --skill cpp-server --agent claude-code
Codex
$ npx skills add clockworklabs/spacetimedb --skill cpp-server -a codex -y
Cursor
$ npx skills add clockworklabs/spacetimedb --skill cpp-server -a cursor -y
Gemini CLI
$ npx skills add clockworklabs/spacetimedb --skill cpp-server -a gemini-cli -y
GitHub Copilot
$ npx skills add clockworklabs/spacetimedb --skill cpp-server -a github-copilot -y
OpenCode
$ npx skills add clockworklabs/spacetimedb --skill cpp-server -a opencode -y
Windsurf
$ npx skills add clockworklabs/spacetimedb --skill cpp-server -a windsurf -y
name: cpp-server description: SpacetimeDB C++ server module SDK reference. Use when writing tables, reducers, or module logic in C++. license: Apache-2.0 metadata: author: clockworklabs version: "2.0" role: server language: cpp cursor_globs: "**/*.cpp,**/*.h,**/*.hpp" cursor_always_apply: true
#include <spacetimedb.h> using namespace SpacetimeDB;
Register structs with macros, then declare as tables:
struct Entity {
uint64_t id;
Identity owner;
std::string name;
bool active;
};
SPACETIMEDB_STRUCT(Entity, id, owner, name, active)
SPACETIMEDB_TABLE(Entity, entity, Public)
FIELD_PrimaryKeyAutoInc(entity, id)
FIELD_Index(entity, name)Options:
Field constraints:
| C++ type | Notes | |----------|-------| | `uint8_t` / `uint16_t` / `uint32_t` / `uint64_t` | unsigned integers | | `SpacetimeDB::u128` / `SpacetimeDB::u256` | large unsigned integers | | `int8_t` / `int16_t` / `int32_t` / `int64_t` | signed integers | | `SpacetimeDB::i128` / `SpacetimeDB::i256` | large signed integers | | `float` / `double` | floats | | `bool` | boolean | | `std::string` | text | | `std::vector<T>` | list/array | | `std::optional<T>` | nullable column | | `Identity` | user identity | | `ConnectionId` | connection handle | | `Timestamp` | server timestamp (microseconds since epoch) | | `TimeDuration` | duration in microseconds | | `ScheduleAt` | for scheduled tables |
// Single-column:
FIELD_Index(entity, name)
// Access: ctx.db[entity_name].filter("Alice")
// Multi-column:
FIELD_NamedMultiColumnIndex(score, by_player_and_level, player_id, level)Range queries (included by `spacetimedb.h`; include `<spacetimedb/range_queries.h>` directly only when not using the umbrella header):
ctx.db[user_age].filter(range_inclusive(uint8_t(18), uint8_t(65))); ctx.db[user_age].filter(range_from(uint8_t(18)));
All reducers return `ReducerResult`. Use `Ok()` or `Err(message)`:
SPACETIMEDB_REDUCER(create_entity, ReducerContext ctx, std::string name) {
if (name.empty()) {
return Err("Name cannot be empty");
}
ctx.db[entity].insert(Entity{0, ctx.sender(), name, true});
return Ok();
}ctx.db[entity].insert(Entity{0, owner, "Sample", true}); // Insert (0 for autoInc)
ctx.db[entity_id].find(entityId); // Find by PK → std::optional
ctx.db[entity_identity].find(ctx.sender()); // Find by unique column
ctx.db[entity_name].filter("Alice"); // Filter by index → iterable
ctx.db[entity]; // All rows → iterable (range-for)
ctx.db[entity].count(); // Count rows
// Update: find, mutate, update
if (auto e = ctx.db[entity_id].find(entityId)) {
e->name = "New Name";
ctx.db[entity_id].update(*e);
}
// Delete by primary key
ctx.db[entity_id].delete_by_key(entityId);Note: Bracket notation `ctx.db[accessor]` is used for all table access. The accessor name comes from `SPACETIMEDB_TABLE` and `FIELD_*` macros.
SPACETIMEDB_INIT(init, ReducerContext ctx) {
LOG_INFO("Database initializing...");
return Ok();
}
SPACETIMEDB_CLIENT_CONNECTED(on_connect, ReducerContext ctx) {
LOG_INFO("Connected: " + ctx.sender().to_string());
return Ok();
}
SPACETIMEDB_CLIENT_DISCONNECTED(on_disconnect, ReducerContext ctx) {
LOG_INFO("Disconnected: " + ctx.sender().to_string());
return Ok();
}// Auth: ctx.sender() is the caller's Identity
if (row.owner != ctx.sender()) {
return Err("unauthorized");
}
// Server timestamps
ctx.db[item].insert(Item{0, ctx.sender(), ctx.timestamp});
// Timestamp arithmetic
Timestamp later = ctx.timestamp + TimeDuration::from_seconds(10);`ReducerContext` is the single source of sender identity, deterministic time, and deterministic randomness inside a reducer. Always go through `ctx` for these. Standard library clocks and random sources are not available in modules.
ctx.db[table] // Table access (bracket notation) ctx.sender() // Caller's Identity ctx.timestamp // Invocation timestamp ctx.connection_id // std::optional<ConnectionId> ctx.identity() // Module's own identity ctx.rng() // Deterministic RNG ctx.sender_auth() // AuthCtx with JWT claims
Declare the environment in a dedicated `environment.h`:
#pragma once
#include <spacetimedb/environment_declaration.h>
SPACETIMEDB_ENV(
(API_KEY, std::string),
(MODE, std::string, ("development", "production")),
(LOG_LEVEL, std::optional<std::string>)
)
// In a root entry point: ctx.env.API_KEY(), ctx.env.LOG_LEVEL()
// String-key lookup: ctx.env.get("LOG_LEVEL")Set `SPACETIMEDB_ENV_HEADER` to this header's full path in CMake **before** adding the SpacetimeDB module library directory, so the library and module see the same context declaration. Including it manually in only one source file is insufficient. `std::string` is required; `std::optional<std::string>` permits absence. The optional third tuple element restricts allowed strings.
See the concepts skill for shared environment and secret-handling rules.
struct Reminder {
uint64_t scheduled_id;
ScheduleAt scheduled_at;
std::string message;
};
SPACETISpacetimeDB CLI reference for initializing projects, building modules, publishing databases, querying data, and managing servers
Understand SpacetimeDB architecture and core concepts. Use when learning SpacetimeDB or making architectural decisions.
SpacetimeDB C#/.NET client SDK reference. Use when building C# clients that connect to SpacetimeDB (console, desktop, or any .NET…
SpacetimeDB C# server module SDK reference. Use when writing tables, reducers, or module logic in C#.
Operate a running SpacetimeDB database through MCP tools rather than the CLI - list databases, read schemas, run SQL, and call…
SpacetimeDB Rust server module SDK reference. Use when writing tables, reducers, or module logic in Rust.
Best practices for implementing JWT, API Keys, OAuth 2.1, and RBAC in a NitroStack application.