# Description of Changes Adds `tools/templates/` scripts to derive template metadata from manifests and generate READMEs from quickstart docs. Replaces slug-based `builtWith` with manifest-derived data and hardcoded quickstart mappings with discovery from docs. **Manifest-based `builtWith`** (`update-template-jsons.ts`) - Reads `package.json`, `Cargo.toml`, and `.csproj` to populate `builtWith` in `.template.json`. - Scoped npm packages normalize to scope (`@angular/core` → `angular`). Excludes `@types/*`. Adds `nodejs` only for nodejs-ts when `@types/node` is present. - Root manifests processed before subdirs; primary framework first (e.g. `react` before `spacetimedb` in react-ts). Dependencies reordered in package.json where needed. **Dynamic quickstart discovery** (`generate-template-readmes.ts`) - Discovers template → quickstart by parsing `--template X` from files in `docs/docs/00100-intro/00200-quickstarts/`. - Optional `quickstart` override in `.template.json`; must resolve under quickstarts dir. - chat-react-ts has no quickstart; uses manual README. **New:** `tools/templates/` (update-template-jsons.ts, generate-template-readmes.ts, README, package.json, pnpm-lock). **Modified:** all `templates/*/.template.json` (added `builtWith`), new/generated `templates/*/README.md`. # API and ABI breaking changes None. # Expected complexity level and risk **1** – Dev tooling only. No runtime or API changes. Scripts are isolated; failures only affect generated metadata and READMEs. # Testing - [ ] `cd tools/templates && pnpm run generate` completes without errors - [ ] Spot-check `builtWith` and generated READMEs for a few templates
5.0 KiB
Get a SpacetimeDB Node.js app running in under 5 minutes.
Prerequisites
- Node.js 18+ installed
- SpacetimeDB CLI installed
Install the SpacetimeDB CLI before continuing.
Create your project
Run the spacetime dev command to create a new project with a SpacetimeDB module and Node.js client.
This starts the local SpacetimeDB server, publishes your module, generates TypeScript bindings, and runs the Node.js client.
spacetime dev --template nodejs-ts
Explore the project structure
Your project contains both server and client code.
Edit spacetimedb/src/index.ts to add tables and reducers. Edit src/main.ts to build your Node.js client.
my-spacetime-app/
├── spacetimedb/ # Your SpacetimeDB module
│ └── src/
│ └── index.ts # Server-side logic
├── src/
│ ├── main.ts # Node.js client script
│ └── module_bindings/ # Auto-generated types
└── package.json
Understand tables and reducers
Open spacetimedb/src/index.ts to see the module code. The template includes a person table and two reducers: add to insert a person, and sayHello to greet everyone.
Tables store your data. Reducers are functions that modify data — they're the only way to write to the database.
import { schema, table, t } from 'spacetimedb/server';
const spacetimedb = schema({
person: table(
{ public: true },
{
name: t.string(),
}
),
});
export default spacetimedb;
export const add = spacetimedb.reducer(
{ name: t.string() },
(ctx, { name }) => {
ctx.db.person.insert({ name });
}
);
export const sayHello = spacetimedb.reducer(ctx => {
for (const person of ctx.db.person.iter()) {
console.info(`Hello, ${person.name}!`);
}
console.info('Hello, World!');
});
Run the client
spacetime dev starts both the server and the Node.js client. The client connects to SpacetimeDB, subscribes to tables, and displays people as they are added or removed. Press Ctrl+C to exit.
spacetime dev --template nodejs-ts
Call reducers from the SpacetimeDB CLI
Use the SpacetimeDB CLI to add people and invoke reducers. Changes appear in your Node.js client in real time.
# Add a person
spacetime call add Alice
spacetime call add Bob
# Greet everyone (check server logs)
spacetime call say_hello
# Query the database
spacetime sql "SELECT * FROM person"
Understand the client code
Open src/main.ts to see the Node.js client. It uses DbConnection.builder() to connect to SpacetimeDB, subscribes to tables, and registers callbacks for insert/delete events. Unlike browser apps, Node.js stores the authentication token in a file instead of localStorage.
import { DbConnection } from './module_bindings/index.js';
DbConnection.builder()
.withUri(HOST)
.withDatabaseName(DB_NAME)
.withToken(loadToken()) // Load saved token from file
.onConnect((conn, identity, token) => {
console.log('Connected! Identity:', identity.toHexString());
saveToken(token); // Save token for future connections
// Subscribe to all tables
conn.subscriptionBuilder()
.onApplied((ctx) => {
// Show current people
const people = [...ctx.db.person.iter()];
console.log('Current people:', people.length);
})
.subscribeToAllTables();
// Listen for table changes
conn.db.person.onInsert((ctx, person) => {
console.log(`[Added] ${person.name}`);
});
})
.build();
More CLI examples
The SpacetimeDB CLI can call reducers and query your data. Changes appear in your Node.js client in real time.
# Call the add reducer to insert a person
spacetime call add Charlie
# Query the person table
spacetime sql "SELECT * FROM person"
name
---
"Alice"
"Bob"
"Charlie"
# Call sayHello to greet everyone
spacetime call say_hello
# View the module logs
spacetime logs
2025-01-13T12:00:00.000000Z INFO: Hello, Alice!
2025-01-13T12:00:00.000000Z INFO: Hello, Bob!
2025-01-13T12:00:00.000000Z INFO: Hello, Charlie!
2025-01-13T12:00:00.000000Z INFO: Hello, World!
Node.js considerations
WebSocket support: Node.js 22+ has native WebSocket support. For Node.js 18-21, the SDK automatically uses the undici package (included in devDependencies).
Environment variables: Configure the connection using SPACETIMEDB_HOST and SPACETIMEDB_DB_NAME environment variables.
Exiting: Press Ctrl+C to stop the client.
# Configure via environment variables
SPACETIMEDB_HOST=ws://localhost:3000 \
SPACETIMEDB_DB_NAME=my-app \
npm run start
# Or use a .env file with dotenv
Next steps
- See the Chat App Tutorial for a complete example
- Read the TypeScript SDK Reference for detailed API docs