Skip to content

Commit dd99be6

Browse files
authored
Quickstart bun (#4154)
# Description of Changes Adds a Bun quickstart template and documentation for SpacetimeDB. ## Template (`templates/bun-ts/`) - SpacetimeDB module with TypeScript (`spacetimedb/src/index.ts`) - Bun client with interactive CLI (`src/main.ts`) - Uses Bun-native APIs (`Bun.file()`, `Bun.write()`) for token persistence - Uses Bun's native WebSocket and TypeScript support - Pre-generated module bindings in `src/module_bindings/` ## Documentation (`docs/docs/00100-intro/00200-quickstarts/00250-bun.md`) - Step-by-step quickstart guide following existing pattern - Covers project creation with `spacetime dev --template bun-ts` - Explains project structure and Bun-specific client code - Documents environment variable configuration (`SPACETIMEDB_HOST`, `SPACETIMEDB_DB_NAME`) - Highlights Bun-specific features (native WebSocket, built-in TypeScript, `.env` support) ## Consistency - Environment variables follow the same `HOST`/`DB_NAME` naming convention as other quickstarts - Documentation structure mirrors Node.js quickstart - Interactive CLI mirrors Node.js template behavior # API and ABI breaking changes None. # Expected complexity level and risk 1 - Additive change only. New template and documentation, no modifications to existing functionality. # Testing - [ ] Run `spacetime dev --template bun-ts my-bun-app` and verify app starts - [ ] Verify SpacetimeDB connection works via WebSocket - [ ] Test adding a person via the interactive CLI - [ ] Verify real-time subscription updates appear in client - [ ] Check documentation renders correctly in Docusaurus
1 parent 87d8759 commit dd99be6

21 files changed

Lines changed: 862 additions & 0 deletions
Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
---
2+
title: Bun Quickstart
3+
sidebar_label: Bun
4+
slug: /quickstarts/bun
5+
hide_table_of_contents: true
6+
---
7+
8+
import { InstallCardLink } from "@site/src/components/InstallCardLink";
9+
import { StepByStep, Step, StepText, StepCode } from "@site/src/components/Steps";
10+
11+
Get a SpacetimeDB Bun app running in under 5 minutes.
12+
13+
## Prerequisites
14+
15+
- [Bun](https://bun.sh/) installed
16+
- [SpacetimeDB CLI](https://spacetimedb.com/install) installed
17+
18+
<InstallCardLink />
19+
20+
---
21+
22+
<StepByStep>
23+
<Step title="Create your project">
24+
<StepText>
25+
Run the `spacetime dev` command to create a new project with a SpacetimeDB module and Bun client.
26+
27+
This will start the local SpacetimeDB server, publish your module, and generate TypeScript bindings.
28+
</StepText>
29+
<StepCode>
30+
31+
```bash
32+
spacetime dev --template bun-ts
33+
```
34+
35+
</StepCode>
36+
37+
</Step>
38+
39+
<Step title="Explore the project structure">
40+
<StepText>
41+
Your project contains both server and client code.
42+
43+
Edit `spacetimedb/src/index.ts` to add tables and reducers. Edit `src/main.ts` to build your Bun client.
44+
</StepText>
45+
<StepCode>
46+
47+
```
48+
my-spacetime-app/
49+
├── spacetimedb/ # Your SpacetimeDB module
50+
│ └── src/
51+
│ └── index.ts # Server-side logic
52+
├── src/
53+
│ ├── main.ts # Bun client script
54+
│ └── module_bindings/ # Auto-generated types
55+
└── package.json
56+
```
57+
58+
</StepCode>
59+
60+
</Step>
61+
62+
<Step title="Understand tables and reducers">
63+
<StepText>
64+
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 `say_hello` to greet everyone.
65+
66+
Tables store your data. Reducers are functions that modify data — they're the only way to write to the database.
67+
</StepText>
68+
<StepCode>
69+
70+
```typescript
71+
import { schema, table, t } from 'spacetimedb/server';
72+
73+
export const spacetimedb = schema(
74+
table(
75+
{ name: 'person', public: true },
76+
{
77+
name: t.string(),
78+
}
79+
)
80+
);
81+
82+
spacetimedb.reducer('add', { name: t.string() }, (ctx, { name }) => {
83+
ctx.db.person.insert({ name });
84+
});
85+
86+
spacetimedb.reducer('say_hello', ctx => {
87+
for (const person of ctx.db.person.iter()) {
88+
console.info(`Hello, ${person.name}!`);
89+
}
90+
console.info('Hello, World!');
91+
});
92+
```
93+
94+
</StepCode>
95+
96+
</Step>
97+
98+
<Step title="Run the client">
99+
<StepText>
100+
In a new terminal, run the Bun client. It will connect to SpacetimeDB and start an interactive CLI where you can add people and query the database.
101+
</StepText>
102+
<StepCode>
103+
```bash
104+
# Run with auto-reload during development
105+
bun run dev
106+
107+
# Or run once
108+
109+
bun run start
110+
111+
```
112+
</StepCode>
113+
</Step>
114+
115+
<Step title="Use the interactive CLI">
116+
<StepText>
117+
The client provides a command-line interface to interact with your SpacetimeDB module. Type a name to add a person, or use the built-in commands.
118+
</StepText>
119+
<StepCode>
120+
```
121+
122+
Connecting to SpacetimeDB...
123+
URI: ws://localhost:3000
124+
Module: bun-ts
125+
126+
Connected to SpacetimeDB!
127+
Identity: abc123def456...
128+
129+
Current people (0):
130+
(none yet)
131+
132+
Commands:
133+
<name> - Add a person with that name
134+
list - Show all people
135+
hello - Greet everyone (check server logs)
136+
Ctrl+C - Quit
137+
138+
> Alice
139+
> [Added] Alice
140+
141+
> Bob
142+
> [Added] Bob
143+
144+
> list
145+
> People in database:
146+
147+
- Alice
148+
- Bob
149+
150+
> hello
151+
> Called say_hello reducer (check server logs)
152+
153+
````
154+
</StepCode>
155+
</Step>
156+
157+
<Step title="Understand the client code">
158+
<StepText>
159+
Open `src/main.ts` to see the Bun client. It uses `DbConnection.builder()` to connect to SpacetimeDB, subscribes to tables, and sets up the interactive CLI using Bun's native APIs.
160+
161+
Unlike browser apps, Bun stores the authentication token in a file using `Bun.file()` and `Bun.write()`.
162+
</StepText>
163+
<StepCode>
164+
```typescript
165+
import { DbConnection } from './module_bindings/index.js';
166+
167+
// Build and establish connection
168+
DbConnection.builder()
169+
.withUri(HOST)
170+
.withModuleName(DB_NAME)
171+
.withToken(await loadToken()) // Load saved token from file
172+
.onConnect((conn, identity, token) => {
173+
console.log('Connected! Identity:', identity.toHexString());
174+
saveToken(token); // Save token for future connections
175+
176+
// Subscribe to all tables
177+
conn.subscriptionBuilder()
178+
.onApplied((ctx) => {
179+
// Show current data, start CLI
180+
setupCLI(conn);
181+
})
182+
.subscribeToAllTables();
183+
184+
// Listen for table changes
185+
conn.db.person.onInsert((ctx, person) => {
186+
console.log(`[Added] ${person.name}`);
187+
});
188+
})
189+
.build();
190+
````
191+
192+
</StepCode>
193+
194+
</Step>
195+
196+
<Step title="Test with the SpacetimeDB CLI">
197+
<StepText>
198+
You can also use the SpacetimeDB CLI to call reducers and query your data directly. Changes made via the CLI will appear in your Bun client in real-time.
199+
</StepText>
200+
<StepCode>
201+
```bash
202+
# Call the add reducer to insert a person
203+
spacetime call <database-name> add Charlie
204+
205+
# Query the person table
206+
207+
spacetime sql <database-name> "SELECT \* FROM person"
208+
name
209+
210+
---
211+
212+
"Alice"
213+
"Bob"
214+
"Charlie"
215+
216+
# Call say_hello to greet everyone
217+
218+
spacetime call <database-name> say_hello
219+
220+
# View the module logs
221+
222+
spacetime logs <database-name>
223+
2025-01-13T12:00:00.000000Z INFO: Hello, Alice!
224+
2025-01-13T12:00:00.000000Z INFO: Hello, Bob!
225+
2025-01-13T12:00:00.000000Z INFO: Hello, Charlie!
226+
2025-01-13T12:00:00.000000Z INFO: Hello, World!
227+
228+
````
229+
</StepCode>
230+
</Step>
231+
232+
<Step title="Bun-specific features">
233+
<StepText>
234+
**Native WebSocket:** Bun has built-in WebSocket support, so no additional packages like `undici` are needed.
235+
236+
**Built-in TypeScript:** Bun runs TypeScript directly without transpilation, making startup faster and eliminating the need for `tsx` or `ts-node`.
237+
238+
**Environment variables:** Bun automatically loads `.env` files. Configure the connection using `SPACETIMEDB_HOST` and `SPACETIMEDB_DB_NAME` environment variables.
239+
240+
**File APIs:** The template uses `Bun.file()` and `Bun.write()` for token persistence, which are faster than Node.js `fs` operations.
241+
</StepText>
242+
<StepCode>
243+
```bash
244+
# Configure via environment variables
245+
SPACETIMEDB_HOST=ws://localhost:3000 \
246+
SPACETIMEDB_DB_NAME=my-app \
247+
bun run start
248+
249+
# Or create a .env file (Bun loads it automatically)
250+
echo "SPACETIMEDB_HOST=ws://localhost:3000" > .env
251+
echo "SPACETIMEDB_DB_NAME=my-app" >> .env
252+
bun run start
253+
````
254+
255+
</StepCode>
256+
257+
</Step>
258+
</StepByStep>
259+
260+
## Next steps
261+
262+
- See the [Chat App Tutorial](/tutorials/chat-app) for a complete example
263+
- Read the [TypeScript SDK Reference](/sdks/typescript) for detailed API docs

templates/bun-ts/.template.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"description": "Bun TypeScript client and server template",
3+
"client_lang": "typescript",
4+
"server_lang": "typescript"
5+
}

templates/bun-ts/LICENSE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../licenses/apache2.txt

templates/bun-ts/package.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "@clockworklabs/bun-ts",
3+
"private": true,
4+
"version": "0.0.1",
5+
"type": "module",
6+
"scripts": {
7+
"dev": "bun --watch src/main.ts",
8+
"start": "bun src/main.ts",
9+
"build": "bun build src/main.ts --outdir dist",
10+
"spacetime:generate": "spacetime generate --lang typescript --out-dir src/module_bindings --project-path spacetimedb"
11+
},
12+
"dependencies": {
13+
"spacetimedb": "workspace:*"
14+
},
15+
"devDependencies": {
16+
"@types/bun": "latest",
17+
"typescript": "~5.6.2"
18+
}
19+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "spacetime-module",
3+
"version": "1.0.0",
4+
"description": "",
5+
"scripts": {
6+
"build": "spacetime build",
7+
"publish": "spacetime publish"
8+
},
9+
"keywords": [],
10+
"author": "",
11+
"license": "ISC",
12+
"dependencies": {
13+
"spacetimedb": "1.*"
14+
}
15+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { schema, table, t } from 'spacetimedb/server';
2+
3+
export const spacetimedb = schema(
4+
table(
5+
{ name: 'person', public: true },
6+
{
7+
name: t.string(),
8+
}
9+
)
10+
);
11+
12+
spacetimedb.init(_ctx => {
13+
// Called when the module is initially published
14+
});
15+
16+
spacetimedb.clientConnected(_ctx => {
17+
// Called every time a new client connects
18+
});
19+
20+
spacetimedb.clientDisconnected(_ctx => {
21+
// Called every time a client disconnects
22+
});
23+
24+
spacetimedb.reducer('add', { name: t.string() }, (ctx, { name }) => {
25+
ctx.db.person.insert({ name });
26+
});
27+
28+
spacetimedb.reducer('say_hello', ctx => {
29+
for (const person of ctx.db.person.iter()) {
30+
console.info(`Hello, ${person.name}!`);
31+
}
32+
console.info('Hello, World!');
33+
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* This tsconfig is used for TypeScript projects created with `spacetimedb init
3+
* --lang typescript`. You can modify it as needed for your project, although
4+
* some options are required by SpacetimeDB.
5+
*/
6+
{
7+
"compilerOptions": {
8+
"strict": true,
9+
"skipLibCheck": true,
10+
"moduleResolution": "bundler",
11+
"jsx": "react-jsx",
12+
13+
/* The following options are required by SpacetimeDB
14+
* and should not be modified
15+
*/
16+
"target": "ESNext",
17+
"lib": ["ES2021", "dom"],
18+
"module": "ESNext",
19+
"isolatedModules": true,
20+
"noEmit": true
21+
},
22+
"include": ["./**/*"]
23+
}

0 commit comments

Comments
 (0)