Skip to main content
Version: 2.0.0

Connecting to SpacetimeDB

After generating client bindings for your module, you can establish a connection to your SpacetimeDB database from your client application. The DbConnection type provides a persistent WebSocket connection that enables real-time communication with the server.

Prerequisites​

Before connecting, ensure you have:

  1. Generated client bindings for your module
  2. A published database running on SpacetimeDB (local or on MainCloud)
  3. The database's URI and name or identity

Basic Connection​

Create a connection using the DbConnection builder pattern:

import { DbConnection } from './module_bindings';

const conn = DbConnection.builder()
    .withUri("https://maincloud.spacetimedb.com")
    .withDatabaseName("my_database")
    .withAutomaticReconnect()
    .build();

Replace "https://maincloud.spacetimedb.com" with your SpacetimeDB host URI, and "my_database" with your database's name or identity.

Connecting to MainCloud​

To connect to a database hosted on MainCloud:

const conn = DbConnection.builder()
    .withUri("https://maincloud.spacetimedb.com")
    .withDatabaseName("my_database")
    .withAutomaticReconnect()
    .build();

Authentication with Tokens​

To authenticate with a token (for example, from SpacetimeAuth), provide it when building the connection:

const conn = DbConnection.builder()
    .withUri("https://maincloud.spacetimedb.com")
    .withDatabaseName("my_database")
    .withToken("your_auth_token_here")
    .withAutomaticReconnect()
    .build();

The token is sent to the server during connection and validates your identity. See the SpacetimeAuth documentation for details on obtaining and managing tokens.

Advancing the Connection​

Critical: C#, Unity, and Unreal Users

In C# (including Unity), you must manually advance the connection to process incoming messages. In Unreal Engine, you must either manually advance the connection or enable automatic ticking. If the connection is not advanced, it will not process messages.

Call FrameTick() in your game loop or update method:

// In Unity, call this in your Update() method
void Update()
{
    conn.FrameTick();
}

// Or in a console application, call this in your main loop
while (running)
{
    conn.FrameTick();
    // Your application logic...
}

Failure to advance the connection means your client will not receive any updates from the server, including subscription data, reducer callbacks, or connection events.

In Rust and TypeScript, the connection processes messages automatically via the browser's event loop or Node.js's event loop. No manual polling is required.

Connection Lifecycle​

Connection Callbacks​

Register callbacks to observe connection state changes:

const HOST = "https://maincloud.spacetimedb.com";
const DB_NAME = "my_database";
const TOKEN_KEY = `${HOST}/${DB_NAME}/auth_token`;

const conn = DbConnection.builder()
    .withUri(HOST)
    .withDatabaseName(DB_NAME)
    .withToken(localStorage.getItem(TOKEN_KEY) ?? undefined)
    .withAutomaticReconnect()
    .onConnect((conn, identity, token) => {
        console.log(`Connected! Identity: ${identity.toHexString()}`);
        // Save token for reconnection — keyed per server/database
        localStorage.setItem(TOKEN_KEY, token);
    })
    .onAutomaticReconnect((_conn, identity, token) => {
        console.log(`Reconnected! Identity: ${identity.toHexString()}`);
        localStorage.setItem(TOKEN_KEY, token);
    })
    .onConnectError((_ctx, error, attempt, delayMs) => {
        console.error('Connection failed:', error);
        if (attempt !== undefined) console.log(`Retry ${attempt} in ${delayMs} ms`);
    })
    .onDisconnect((_ctx, error, attempt, delayMs) => {
        if (attempt !== undefined) {
            console.log(`Connection lost; retry ${attempt} in ${delayMs} ms`, error);
        } else {
            console.log('Connection ended', error);
        }
    })
    .build();

Disconnecting​

Explicitly close the connection when you're done:

conn.disconnect();

Reconnection Behavior​

Enable .withAutomaticReconnect() to recover after an established connection drops. The SDK retains the connection, cached rows, subscription handles, and callbacks, then restores subscriptions automatically. While isReconnecting is true, cache reads return the last known data.

Register subscriptions and row callbacks in onConnect, which runs only once, or once after build(). Successful recovery invokes onAutomaticReconnect(conn, identity, token) before subscription replay; wait for subscription onApplied callbacks when you need refreshed data. Save authentication tokens in both connection callbacks.

onDisconnect and onConnectError report the upcoming retry attempt and delay, or undefined when no retry is scheduled. Initial connection failures are not retried, and disconnect() stops recovery. For expiring credentials, combine .withToken(initialToken) with .withTokenProvider(() => auth.getAccessToken()) to refresh tokens when needed before reconnect attempts.

React, Solid, and Svelte providers enable automatic reconnect through their shared connection manager. Vue and Angular require .withAutomaticReconnect() on the provider's builder. Without automatic reconnect, create a new connection after a connection loss. See the TypeScript reference for backoff options, pending-call behavior, and server requirements.

Connection Identity​

Every connection receives a unique identity from the server. Access it through the on_connect callback:

.onConnect((conn, identity, token) => {
    console.log(`Identity: ${identity.toHexString()}, ConnectionId: ${conn.connectionId}`);
})

The identity persists across connections and represents the user, while the connection ID is unique to each connection session.

Next Steps​

Now that you have a connection established, you can:

  • Use the SDK API to interact with tables, invoke reducers, and subscribe to data
  • Register callbacks for observing database changes
  • Call reducers and procedures on the server

For language-specific details, see: