v1.8.0
clockworklabs/SpacetimeDBv1.8.0Nov 12, 2025by joshua-spacetime
AI Summary
SpacetimeDB introduces Module Defined Views, a powerful way to define procedural, read-only virtual tables for row-level security, and resolves views in SQL queries.
Key Highlights
- Module Defined Views allow defining procedural, read-only virtual tables derived from other tables.
- Views can be queried and subscribed to like normal tables with automatic realtime updates.
- Deprecation of the unstable RLS API in favor of the new View API.
- View resolution in SQL queries.
New Features
- Module Defined Views (Rust, C#, TypeScript)
- View resolution in SQL
- Host interface for WASM modules
- Rust client SDK bindings for procedures
- AuthCtx and JwtClaims exports in TS SDK
Full Release Notes
## Module Defined Views
The shipping continues! This time we have Module Defined Views or just "views". Views are a simple, but incredibly expressive way to define custom and intricate read permissioning for your tables.
Views, which are inspired by a [similar concept from SQL](https://en.wikipedia.org/wiki/View_(SQL)), are virtual tables that are defined by new "view functions" in your module and derived from other tables or parameters.
Views are defined by read-only procedural, functions in the language of your module. This function returns data derived from your database tables. You can then query and subscribe to this view as you would any normal database table and it will be updated automatically in realtime.
Here's a look at the syntax for defining a view in the various module languages:
### Rust
Declare with `#[view]`. First argument is a view context (`&ViewContext` or `&AnonymousViewContext`). Return `Option<T>` (0–1 row) or `Vec<T>` (many rows).
```rust
#[view(name = my_player, public)]
fn my_player(ctx: &ViewContext) -> Option<Player> {
ctx.db.player().identity().find(ctx.sender)
}
#[view(name = players_for_level, public)]
fn players_for_level(ctx: &AnonymousViewContext) -> Vec<Player> {
ctx.db
.player_level()
.level()
.filter(2u64) // players for level 2
.map(|player| {
ctx.db
.player()
.id()
.find(player.player_id)
})
.collect()
}
```
**Notes**
* A `name` is required.
* Only the context parameter is allowed; no extra args (yet).
* The context provides a read-only view of the database
* Mutations are not allowed
* Full table scans are not allowed
---
### C#
Use `[SpacetimeDB.View]` with `ViewContext` or `AnonymousViewContext`. Return a single row as `T?` or many rows as `List<T>` / `T[]`.
```csharp
[SpacetimeDB.View(Name = "my_player", Public = true)]
public static Player? MyPlayer(ViewContext ctx) =>
ctx.Db.Player.Identity.Find(ctx.Sender) as Player;
[SpacetimeDB.View(Name = "players_for_level", Public = true)]
public static List<Player> PlayerLocations(AnonymousViewContext ctx) {
var rows = new List<Player>();
foreach (var player in ctx.Db.PlayerLevel.Level.Filter(2))
{
if (ctx.Db.Player.Id.Find(player.PlayerId) is Player p)
{
rows.Add(p);
}
}
return rows;
}
```
---
### TypeScript
Register with `schema.view(...)` or `schema.anonymousView(...)`. Use `t.option(row)` for 0–1 row or `t.array(row)` for many rows.
```ts
spacetimedb.view(
{ name: 'my_player', public: true },
t.option(players.row()),
(ctx) => {
return ctx.db.players.identity.find(ctx.sender) ?? null;
}
);
spacetimedb.anonymousView(
{ name: 'players_for_level', public: true },
t.option(players.row()),
(ctx) => {
const out = [];
for (const pl of ctx.db.playerLevels.level.find(2)) {
const p = ctx.db.players.id.find(pl.player_id);
if (p) out.push(p);
}
return out;
}
);
```
### Row-level security rules
Currently procedurally defined view functions are limited to index probing tables so that we can efficiently compute the real-time delta for procedural functions. However, we also plan to shortly add the ability to return typed queries from view functions which will allow you to define performant, incrementally evaluated queries which execute full tables scans.
This functionality will make views strictly more expressive and powerful than the existing unstable RLS (row-level security) rules API that we introduced earlier this year. As such **we will be deprecating the RLS API** in favor of the view API. Here is an idea (not final API) of what that might look like in TypeScript
```ts
spacetimedb.view(
{ name: 'high_level_players', public: true },
t.query(players.row()),
(ctx) => {
return ctx.from(ctx.db.player).where(player => gt(player.level, 50))
}
);
```
## What's Changed
* Add typescript quickstart smoketest by @coolreader18 in https://github.com/clockworklabs/SpacetimeDB/pull/3463
* CI - Move the Package job to ubuntu-latest by @bfops in https://github.com/clockworklabs/SpacetimeDB/pull/3553
* CI - Fix NuGet smoketest dependencies by @bfops in https://github.com/clockworklabs/SpacetimeDB/pull/3557
* Fix Nix build by not using Git in Cargo build scripts by @gefjon in https://github.com/clockworklabs/SpacetimeDB/pull/3551
* Use production API key by @JulienLavocat in https://github.com/clockworklabs/SpacetimeDB/pull/3560
* Bump versions to 1.7.0 by @bfops in https://github.com/clockworklabs/SpacetimeDB/pull/3550
* Generate client bindings for views by @joshua-spacetime in https://github.com/clockworklabs/SpacetimeDB/pull/3564
* Add proper V8 sys module versioning by @coolreader18 in https://github.com/clockworklabs/SpacetimeDB/pull/3527
* Set default server to `local` in replication smoketests by @gefjon in https://github.com/clockworklabs/SpacetimeDB/pull/3562
* View resolution in sql by @joshua-spacetime in https://github.com/clockworklabs/SpacetimeDB/pull/3570
* [teams 1/5] Reset database by @kim in https://github.com/clockworklabs/SpacetimeDB/pull/3496
* Fix some annoyances with the smoketests by @coolreader18 in https://github.com/clockworklabs/SpacetimeDB/pull/3556
* Add view handling to query engine and planner by @joshua-spacetime in https://github.com/clockworklabs/SpacetimeDB/pull/3578
* CI - Fix the merge queue by @bfops in https://github.com/clockworklabs/SpacetimeDB/pull/3571
* Revert "[teams 1/5] Reset database (#3496)" by @bfops in https://github.com/clockworklabs/SpacetimeDB/pull/3580
* Decrement view subscriber count on disconnect by @joshua-spacetime in https://github.com/clockworklabs/SpacetimeDB/pull/3547
* Update C# client-api bindings by @gefjon in https://github.com/clockworklabs/SpacetimeDB/pull/3537
* Views: Host interface for WASM modules by @Shubham8287 in https://github.com/clockworklabs/SpacetimeDB/pull/3548
* Fix for multi-column indexes in typescript modules by @jsdt in https://github.com/clockworklabs/SpacetimeDB/pull/3589
* smoketests: Adjust enable replication tests by @kim in https://github.com/clockworklabs/SpacetimeDB/pull/3590
* `Dockerfile` fails more cleanly if `.git` is a submodule by @bfops in https://github.com/clockworklabs/SpacetimeDB/pull/3591
* fix: view index by @Shubham8287 in https://github.com/clockworklabs/SpacetimeDB/pull/3596
* remove module watcher from subscription by @Shubham8287 in https://github.com/clockworklabs/SpacetimeDB/pull/3602
* Fix issue with row id for non primary key tables by @aasoni in https://github.com/clockworklabs/SpacetimeDB/pull/3603
* Typescript views by @coolreader18 in https://github.com/clockworklabs/SpacetimeDB/pull/3584
* CI - Make Internal Tests less brittle by @bfops in https://github.com/clockworklabs/SpacetimeDB/pull/3536
* Materialize views on subscribe by @joshua-spacetime in https://github.com/clockworklabs/SpacetimeDB/pull/3599
* Refactor module instance code by @coolreader18 in https://github.com/clockworklabs/SpacetimeDB/pull/3605
* commitlog,durability: Support preallocation of disk space by @kim in https://github.com/clockworklabs/SpacetimeDB/pull/3437
* Add Rust client SDK bindings for calling procedures by @gefjon in https://github.com/clockworklabs/SpacetimeDB/pull/3532
* Add comment about public API key use on Docusaurus by @JulienLavocat in https://github.com/clockworklabs/SpacetimeDB/pull/3567
* Views: fix table schema creation from system table. by @Shubham8287 in https://github.com/clockworklabs/SpacetimeDB/pull/3615
* Disable parameterized views in rust by @joshua-spacetime in https://github.com/clockworklabs/SpacetimeDB/pull/3629
* CI - Fix format strings by @bfops in https://github.com/clockworklabs/SpacetimeDB/pull/3627
* Atomic view update by @joshua-spacetime in https://github.com/clockworklabs/SpacetimeDB/pull/3624
* Disconnect clients when updating RLS rules by @mamcx in https://github.com/clockworklabs/SpacetimeDB/pull/3574
* [teams 1/5] Reset database by @kim in https://github.com/clockworklabs/SpacetimeDB/pull/3611
* SQL smoketests for views by @Shubham8287 in https://github.com/clockworklabs/SpacetimeDB/pull/3616
* [teams 2/5] client-api: Add `parent` parameter to publish endpoint by @kim in https://github.com/clockworklabs/SpacetimeDB/pull/3519
* [teams 3/5] API authorization, CLI, smoketests by @kim in https://github.com/clockworklabs/SpacetimeDB/pull/3523
* C# bindings for views by @rekhoff in https://github.com/clockworklabs/SpacetimeDB/pull/3585
**Full Changelog**: https://github.com/clockworklabs/SpacetimeDB/compare/v1.7.0...v1.8.0