Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions crates/bindings-typescript/src/browser/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export * from '../sdk/index';
export { Identity } from '../lib/identity';
export { ConnectionId } from '../lib/connection_id';
export { Timestamp } from '../lib/timestamp';
export { TimeDuration } from '../lib/time_duration';
export { ScheduleAt } from '../lib/schedule_at';
export { AlgebraicType, ProductType, SumType } from '../lib/algebraic_type';
31 changes: 31 additions & 0 deletions crates/bindings-typescript/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,37 @@ export default defineConfig([
esbuildOptions: commonEsbuildTweaks(),
},

// Browser bundle (IIFE for script tags): dist/browser.bundle.js
{
entry: { 'browser.bundle': 'src/browser/index.ts' },
format: ['iife'],
globalName: 'SpacetimeDB',
target: 'es2022',
outDir: 'dist',
dts: false,
sourcemap: true,
platform: 'browser',
treeshake: 'smallest',
noExternal: [/.*/],
outExtension: () => ({ js: '.js' }),
esbuildOptions: commonEsbuildTweaks(),
},

// Browser bundle ESM: dist/browser/index.mjs
{
entry: { index: 'src/browser/index.ts' },
format: ['esm'],
target: 'es2022',
outDir: 'dist/browser',
dts: false,
sourcemap: true,
clean: true,
platform: 'browser',
treeshake: 'smallest',
outExtension,
esbuildOptions: commonEsbuildTweaks(),
},

// The below minified builds are not referenced in package.json and are
// just included in the build for measuring the size impact of minification.
// It is expected that consumers of the library will run their own
Expand Down
118 changes: 118 additions & 0 deletions docs/docs/00100-intro/00200-quickstarts/00180-browser.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
---
title: Browser Quickstart
sidebar_label: Browser
slug: /quickstarts/browser
hide_table_of_contents: true
pagination_next: intro/quickstarts/typescript
---

import { InstallCardLink } from "@site/src/components/InstallCardLink";
import { StepByStep, Step, StepText, StepCode } from "@site/src/components/Steps";

Get a SpacetimeDB app running in the browser with inline JavaScript.

## Prerequisites

- [Node.js](https://nodejs.org/) 18+ installed
- [SpacetimeDB CLI](https://spacetimedb.com/install) installed

<InstallCardLink />

---

<StepByStep>
<Step title="Create your project">
<StepText>
Run the `spacetime dev` command to create a new project with a TypeScript SpacetimeDB module.

This will start the local SpacetimeDB server, publish your module, and generate TypeScript client bindings.
</StepText>
<StepCode>
```bash
spacetime dev --template browser-ts my-spacetime-app
```
</StepCode>
</Step>

<Step title="Build the client bindings">
<StepText>
The generated bindings need to be bundled into a JavaScript file that can be loaded in the browser.
</StepText>
<StepCode>
```bash
cd my-spacetime-app
npm install
npm run build
```
</StepCode>
</Step>

<Step title="Open in browser">
<StepText>
Open `index.html` directly in your browser. The app connects to SpacetimeDB and displays data in real-time.

The JavaScript code runs inline in a script tag, using the bundled `DbConnection` class.
</StepText>
<StepCode>
```html
<!-- Load the bundled bindings -->
<script src="dist/bindings.iife.js"></script>

<script>
const conn = DbConnection.builder()
.withUri('ws://localhost:3000')
.withModuleName('my-spacetime-app')
.withToken(localStorage.getItem('auth_token'))
.onConnect((conn, identity, token) => {
localStorage.setItem('auth_token', token);
console.log('Connected:', identity.toHexString());

// Subscribe to tables
conn.subscriptionBuilder()
.onApplied(() => {
for (const person of conn.db.person.iter()) {
console.log(person.name);
}
})
.subscribe(['SELECT * FROM person']);
})
.build();
</script>
```
</StepCode>
</Step>

<Step title="Call reducers">
<StepText>
Reducers are functions that modify data — they're the only way to write to the database.
</StepText>
<StepCode>
```javascript
// Call a reducer with named arguments
conn.reducers.add({ name: 'Alice' });
```
</StepCode>
</Step>

<Step title="React to changes">
<StepText>
Register callbacks to update your UI when data changes.
</StepText>
<StepCode>
```javascript
conn.db.person.onInsert((ctx, person) => {
console.log('New person:', person.name);
});

conn.db.person.onDelete((ctx, person) => {
console.log('Removed:', person.name);
});
```
</StepCode>
</Step>
</StepByStep>

## Next steps

- See the [Chat App Tutorial](/tutorials/chat-app) for a complete example
- Read the [TypeScript SDK Reference](/sdks/typescript) for detailed API docs
89 changes: 19 additions & 70 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ packages:
- 'templates/react-ts'
- 'templates/basic-ts'
- 'templates/vue-ts'
- 'templates/browser-ts'
- 'templates/svelte-ts'
- 'modules/benchmarks-ts'
- 'modules/module-test-ts'
Expand Down
5 changes: 5 additions & 0 deletions templates/browser-ts/.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"description": "Browser web app with TypeScript server",
"client_lang": "typescript",
"server_lang": "typescript"
}
1 change: 1 addition & 0 deletions templates/browser-ts/LICENSE
Loading
Loading