github clockworklabs/SpacetimeDB v2.0.0-rc1
SpacetimeDB 2.0 - Release Candidate 1

pre-release10 hours ago

SpacetimeDB 2.0 is almost here! 🌟

image

Today we're announcing SpacetimeDB 2.0 as a preview release. SpacetimeDB 2.0 has some big changes, so buckle up!

TypeScript/JavaScript Support

In October we launched beta support for TypeScript and JavaScript, and we're happy to announce that with the release of 2.0 TypeScript support is leaving beta! We also have a bunch of updates to the API that being much needed consistency to the APIs.

Web framework integration

Along with TypeScript and JavaScript support, we've built integrations and templates with all your favorite frameworks including:

  • Angular
  • React
  • Nuxt
  • Vue
  • Next.js
  • Node
  • Deno
  • TanStack
  • Remix
  • Svelte
  • Bun

Unreal Engine/C++ Support

For all those who have been waiting for official Unreal Engine 5 support, it's here! Alongside C++ modules as well!

Incredible performance

SpacetimeDB 2.0 delivers eye watering throughput even for tiny transactions with high contention. Well over 100k transactions per second for TypeScript modules and up to 170k transactions per second for Rust modules!

image

A new Maincloud FREE tier and all new pricing!

With 2.0, we're also announcing a brand new, simpler pricing scheme along with a free tier for users who want to try out Maincloud!

This new simplified pricing makes it easier than ever to predict your costs. Check out our pricing calculator on the pricing page.

Spacerace Referral Program

Alongside our new pricing, we're introducing the Spacerace Referral Program where you can get up to 400x more free credits per month by referring friends to the platform.

image

Procedures and HTTP calls

With 2.0 your SpacetimeDB modules are getting a big boost in capability too. For the first time, your modules can now access the outside world with Procedure Functions. Procedure functions give you the ability to make HTTP calls from within your module, letting you integrate directly with external APIs. This is how easy it is to call ChatGPT's API from within your module:

export const ask_ai = spacetimedb.procedure(
  { prompt: t.string(), apiKey: t.string() },
  t.string(),
  (ctx, { prompt, apiKey }) => {
    // Make the HTTP request to OpenAI
    const response = ctx.http.fetch('https://api.openai.com/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${apiKey}`,
      },
      body: JSON.stringify({
        model: 'gpt-4',
        messages: [{ role: 'user', content: prompt }],
      }),
      // Give it some time to think
      timeout: TimeDuration.fromMillis(3000),
    });

    if (response.status !== 200) {
      throw new SenderError(`API returned status ${response.status}`);
    }

    const data = response.json();
    const aiResponse = data.choices?.[0]?.message?.content;

    if (!aiResponse) {
      throw new SenderError('Failed to parse AI response');
    }

    // Store the conversation in the database
    ctx.withTx(txCtx => {
      txCtx.db.aiMessage.insert({
        user: txCtx.sender,
        prompt,
        response: aiResponse,
        createdAt: txCtx.timestamp,
      });
    });

    return aiResponse;
  }

SpacetimeAuth (and Clerk and Auth0)

And to help you avoid needing to set up additional sidecars and services alongside SpacetimeDB we've also introduced SpacetimeAuth, our first party auth solution. SpacetimeAuth is completely free to use with SpacetimeDB Maincloud!

We've also built tutorials for how to integrate with other auth providers like Clerk and Auth0!

View Functions

In SpacetimeDB 2.0, adding sophisticated read permissions to expose portions of your data to users is as simple as creating a function:

export const players_for_level = spacetimedb.anonymousView(
   { name: 'players_for_level', public: true },
   t.array(playerAndLevelRow),
   (ctx) => {
       const out: Array<{ id: bigint; name: string; level: bigint }> = [];
       for (const playerLevel of ctx.db.playerLevels.level.filter(2n)) {
           const p = ctx.db.players.id.find(playerLevel.player_id);
           if (p) out.push({ id: p.id, name: p.name, level: playerLevel.level });
       }
       return out;
   }
);

You can think of view functions as a table that is backed by a reducer. From the client, they look just like any other table in your database, but in the module they're represented as a function that returns rows that you want to expose to clients. Better yet, the table is automatically parameterized by the identity of the viewing client, allowing different clients to see different data when viewing the same table.

Views can also return custom types allowing you to not only filter rows, but also columns. Views are an elegant way of solving read permissions without introducing a single new concept!

Typed Query Builder

In SpacetimeDB 2.0, you can kiss your stringly-typed queries goodbye! With our 2.0 SDK and code generation, we generate beautifully typed query builder APIs that allows your clients to build arbitrary queries over the data.

ctx.subscriptionBuilder().subscribe([tables.user.where(user => user.name.eq("Tyler")), tables.message]);

Never worry about runtime errors with your queries again! And the strongly typed queries also help LLMs succeed more often as well.

Even better, you can access this same query builder API inside your view functions to return queries from your views so they can be optimized by our incremental evaluation query engine!

export const high_scorers = spacetimedb.anonymousView(
  { name: 'high_scorers', public: true },
  t.array(players.rowType),
  (ctx) => {
    return ctx.from.players
      .where(p => p.score.gte(1000n))
      .where(p => p.name.ne('BOT'));
  }
);

Event Tables

Event tables are also all new in SpacetimeDB 2.0. Event tables allow you to publish short lived event information to clients without needing to clean up your tables later on. Event tables act like regular tables, but the rows are automatically deleted by SpacetimeDB at the end of a transaction. This both saves you storage costs and also bandwidth, as the database needs to synchronize less state!

Publishing an event to clients is as simple as inserting into a row into the event table, and subscribing to it like any other table.

// server
const damageEvent = table({
  public: true,
  event: true,
}, {
  entity_id: t.identity(),
  damage: t.u32(),
  source: t.string(),
});

export const attack = spacetimedb.reducer(
  { target_id: t.identity(), damage: t.u32() },
  (ctx, { target_id, damage }) => {
    // Game logic...

    // Publish the event
    ctx.db.damageEvent.insert({
      entity_id: target_id,
      damage,
      source: "melee_attack",
    });
  }
);

// client
conn.db.damageEvent.onInsert((ctx, event) => {
  console.log(`Entity ${event.entityId} took ${event.damage} damage from ${event.source}`);
});

spacetime.json configuration

With 2.0, we're also introducing a new config file to make it easier to interact with your databases. Now with spacetime.json you can save all your database configuration in a single file that you check in to git, so instead of this:

spacetime generate --lang typescript --out-dir src/module_bindings
spacetime publish --server maincloud --module-path spacetimedb my-database

You can now just type this:

spacetime generate
spacetime publish

spacetime dev

Development is getting simpler too, with our new spacetime dev command. This command is your one stop shop for development. It:

  1. Watches for changes in your module code
  2. Compiles your module
  3. Generates your client module bindings
  4. Publishes your module
  5. Runs your client

Now all you have to do is change your code and your whole app updates instantly!

All new dashboard and metrics

We've also added beautiful new dashboards and analytics so you can monitor your apps and data in real-time! And they update in real-time too! It's incredible to see tables updating live, trust us!

Better LLM tools and benchmarks

SpacetimeDB is now also optimized for LLMs as well, both to help you understand SpacetimeDB and also to help you write your SpacetimeDB apps. New projects automatically ship with the appropriate AGENT.md files to help you get started immediately.

Project collaborators and organizations

For groups and teams, we've not introduced project collaborators and organizations. With project collaborators you can invite your friends and colleagues to build and publish modules with you.

Larger organizations can sign up for our Maincloud Team tier to reserve their team name and get advanced features for permissions management.

Postgres Wire Protocol Compatibility

If you've got existing tools that work with Postgres, they might work with SpacetimeDB now too! SpacetimeDB 2.0 supports the Postgres Wire Protocol, meaning you can use psql and other Postgres tools to query SpacetimeDB directly.

SpacetimeDB does not yet support the full suite of Postgres features, but this is the beginning of a long effort to make SpacetimeDB fully Postgres compatible.

Much much more

Over the past several months we've merged literally hundreds of bug fixes, UX improvements, and performance improvements. If you haven't tried SpacetimeDB out, now is an excellent time to try!

What's Changed

New Contributors

Full Changelog: v1.12.0-hotfix1...v2.0.0-rc1

Don't miss a new SpacetimeDB release

NewReleases is sending notifications on new releases.