crates/bindings-cpp/README.md
The SpacetimeDB C++ Module Library provides a modern C++20 API for building SpacetimeDB modules that run inside the database as WebAssembly.
This library provides a production-ready C++ bindings for SpacetimeDB with complete type system support:
See ARCHITECTURE.md for detailed technical documentation.
FIELD_Index macros and optimized queriesrange_from(), range_to(), range_inclusive(), etc.SPACETIMEDB_CLIENT_VISIBILITY_FILTER macroSPACETIMEDB_SCHEDULE macro for time-based executionSPACETIMEDB_PROCEDURE macroSPACETIMEDB_VIEW macroctx.db[table_field]See the working examples in modules/*-cpp/src/lib.cpp for comprehensive feature usage.
# Create a new C++ project
spacetime init --lang cpp my-project
cd my-project
# Build and publish
spacetime build -p ./spacetimedb
spacetime publish -p ./spacetimedb my-database
For existing projects, add the following to your C++ module:
#include <spacetimedb.h>
using namespace SpacetimeDB;
// Define a table structure
struct User {
Identity identity;
std::string name;
std::string email;
};
// Register BSATN serialization
SPACETIMEDB_STRUCT(User, identity, name, email)
// Register as a table
SPACETIMEDB_TABLE(User, users, Public)
// Add constraints using FIELD_ macros
FIELD_PrimaryKey(users, identity);
FIELD_Unique(users, email);
// Define an enum with namespace qualification
SPACETIMEDB_ENUM(UserRole, Admin, Moderator, Member)
SPACETIMEDB_NAMESPACE(UserRole, "Auth") // Will be "Auth.UserRole" in client code
// User-defined reducer
SPACETIMEDB_REDUCER(add_user, ReducerContext ctx, std::string name, std::string email) {
User user{ctx.sender(), name, email}; // id will be auto-generated
ctx.db[users].insert(user);
LOG_INFO("Added user: " + name);
return Ok();
}
// Delete user by id (using primary key)
SPACETIMEDB_REDUCER(delete_user, ReducerContext ctx) {
ctx.db[users_identity].delete_by_key(ctx.sender());
return Ok();
}
// Lifecycle reducers (optional)
SPACETIMEDB_INIT(init, ReducerContext ctx) {
LOG_INFO("Module initialized");
return Ok();
}
SPACETIMEDB_CLIENT_CONNECTED(on_connect, ReducerContext ctx) {
LOG_INFO("Client connected: " + ctx.sender().to_hex_string());
return Ok();
}
SPACETIMEDB_CLIENT_DISCONNECTED(on_disconnect, ReducerContext ctx) {
LOG_INFO("Client disconnected: " + ctx.sender().to_hex_string());
return Ok();
}
// Define a view for querying data (finds the calling user)
SPACETIMEDB_VIEW(std::optional<User>, find_my_user, Public, ViewContext ctx) {
// Use indexed field to find user by their identity
return ctx.db[users_identity].find(ctx.sender());
}
// Define a procedure (pure function with return value)
SPACETIMEDB_PROCEDURE(uint32_t, add_numbers, ProcedureContext ctx, uint32_t a, uint32_t b) {
return a + b;
}
# Navigate to your module directory
cd modules/your-module
# Build the project
spacetime build -p ./spacetimedb
# Publish to SpacetimeDB
spacetime publish --bin-path ./spacetimedb/build/lib.wasm your-database-name
# Or use the directory (auto-detects build/lib.wasm)
spacetime publish ./spacetimedb your-database-name
To build a different source file:
# Build a specific test module
emcmake cmake -B build -DMODULE_SOURCE=src/test_module.cpp -DOUTPUT_NAME=test_module .
cmake --build build
# This creates build/test_module.wasm
SPACETIMEDB_TABLE(Type, table_name, Public/Private) - Register a tableSPACETIMEDB_STRUCT(Type, field1, field2, ...) - Register type for BSATN serializationSPACETIMEDB_ENUM(EnumName, Value1, Value2, ...) - Define a simple enumSPACETIMEDB_ENUM(EnumName, (Variant1, Type1), (Variant2, Type2), ...) - Define an enum with payloadsSPACETIMEDB_NAMESPACE(EnumName, "Namespace") - Add namespace qualification to an enumSPACETIMEDB_REDUCER(name, ReducerContext ctx, ...) - User-defined reducer
ReducerResult (alias for Outcome<void>)return Ok(); for success or return Err("message"); for errorsSPACETIMEDB_INIT(name, ReducerContext ctx) - Module initialization reducer (optional)SPACETIMEDB_CLIENT_CONNECTED(name, ReducerContext ctx) - Client connection reducer (optional)SPACETIMEDB_CLIENT_DISCONNECTED(name, ReducerContext ctx) - Client disconnection reducer (optional)SPACETIMEDB_VIEW(return_type, name, Public/Private, ViewContext ctx) - Read-only query functionSPACETIMEDB_VIEW(return_type, name, Public/Private, AnonymousViewContext ctx) - Anonymous view (no sender identity)SPACETIMEDB_PROCEDURE(return_type, name, ProcedureContext ctx, ...) - Pure function that returns a value
ctx.WithTx() or ctx.TryWithTx())FIELD_PrimaryKey(table_name, field) - Primary key constraintFIELD_PrimaryKeyAutoInc(table_name, field) - Auto-incrementing primary keyFIELD_Unique(table_name, field) - Unique constraintFIELD_UniqueAutoInc(table_name, field) - Auto-incrementing unique fieldFIELD_Index(table_name, field) - Index for faster queriesFIELD_IndexAutoInc(table_name, field) - Auto-incrementing indexed fieldFIELD_AutoInc(table_name, field) - Auto-increment without other constraintsLOG_DEBUG("Debug message");
LOG_INFO("Info message");
LOG_WARN("Warning message");
LOG_ERROR("Error message");
LOG_PANIC("Fatal error message");
// With timing
{
LogStopwatch timer("Operation name");
// ... code to time ...
} // Automatically logs duration
The library uses a sophisticated hybrid compile-time/runtime architecture:
table_with_constraints.h): C++20 concepts and static assertions for constraint validationinternal/module_type_registration.h): Unified type registration with error detection and circular reference preventioninternal/Module.cpp): preinit functions with numbered priorities ensure correct registration orderinternal/Module.cpp): Multi-layer validation with error module replacement for clear diagnosticsbsatn/): Binary serialization system with algebraic type support for all data typesdatabase.h, table_with_constraints.h): Type-safe table access with optimized field accessorsreducer_macros.h): Unified macro system for all reducer types with parameter type capturelogger.h): Comprehensive logging with source location trackingFor detailed technical documentation, see ARCHITECTURE.md.
Note on Architecture Documentation: ARCHITECTURE.md contains references to some legacy implementation details. The current implementation is streamlined and production-ready.
Type System
Database Operations
ctx.db[table_field].delete_by_key(value)Advanced Features
FIELD_Index creates btree indexes for efficient range queriesrange_from(), range_to(), range_inclusive(), etc.SPACETIMEDB_CLIENT_VISIBILITY_FILTERspacetime sql) but not within modulesSee the modules/*-cpp/src/ directory for example modules:
lib.cpp - Comprehensive working module with all primitive types, tables, and reducersThis library is part of the SpacetimeDB project. Please see the main repository for contribution guidelines.