## Summary
- Update the experimental NativeAOT-LLVM build path
(`EXPERIMENTAL_WASM_AOT=1`) to include all host function imports from
ABI versions 10.0 through 10.4
- Fix the compiler package reference to work on both Windows x64 and
Linux x64 (was hardcoded to Windows only)
- Add a CI smoketest to verify AOT builds work on Linux x64
## Context
See #4514 for the full writeup on the C# AOT situation. The
`wasi-experimental` workload that all C# module builds depend on is
deprecated and removed from .NET 9+. NativeAOT-LLVM is the recommended
path forward for ahead-of-time compilation of C# to WebAssembly.
The existing NativeAOT-LLVM support (added by RReverser in #713) was
stale: missing imports added since then and a Windows-only package
reference.
## Changes
**`SpacetimeDB.Runtime.targets`:**
- Add 10 missing `WasmImport` declarations across spacetime_10.0 through
10.4
- Replace `runtime.win-x64.Microsoft.DotNet.ILCompiler.LLVM` with
`runtime.$(NETCoreSdkPortableRuntimeIdentifier).Microsoft.DotNet.ILCompiler.LLVM`
so it resolves correctly on Linux x64 as well
- Use explicit version strings instead of the `$(SpacetimeNamespace)`
variable
**`ci.yml`:**
- Add AOT build smoketest step in the `csharp-testsuite` job
## Test plan
- [x] CI smoketest passes: `EXPERIMENTAL_WASM_AOT=1 dotnet publish -c
Release` builds successfully on Linux x64
- [ ] Existing C# tests continue to pass (no changes to the default
interpreter path)
---------
Signed-off-by: Ryan <r.ekhoff@clockworklabs.io>
Co-authored-by: Ryan <r.ekhoff@clockworklabs.io>
Co-authored-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
## Motivation
Feature request: "Is there any way we can lock a module to prevent it
from being deleted? A bit concerned about some fat finger risk of
accidentally deleting prod."
## Solution
Adds a database lock mechanism. A locked database cannot be deleted
until explicitly unlocked.
### New CLI Commands
```bash
# Lock a database to prevent deletion
spacetime lock my-database
# Attempt to delete a locked database (fails with 403)
spacetime delete my-database
# Error: Database is locked and cannot be deleted. Run \`spacetime unlock\` first.
# Unlock when you actually need to delete
spacetime unlock my-database
spacetime delete my-database
```
Both commands support `--server` and `--no-config` flags, and resolve
the database from `spacetime.json` when no argument is given (same as
`spacetime delete`).
### New HTTP API
- `POST /v1/database/:name_or_identity/lock` -- Lock a database
- `POST /v1/database/:name_or_identity/unlock` -- Unlock a database
Both require the same authorization as `DELETE` (owner only).
### Implementation
- Lock state stored in a separate `database_locks` sled tree in the
standalone control DB (avoids changing the `Database` struct and needing
a data migration)
- `ControlStateReadAccess::is_database_locked()` and
`ControlStateWriteAccess::set_database_lock()` added to the trait
- `delete_database` route checks lock state before proceeding; returns
`403 Forbidden` with a descriptive message if locked
- Locking is idempotent (locking an already-locked database is a no-op,
same for unlock)
- Lock only prevents deletion, not publishing updates
### What is NOT locked
- `spacetime publish` (updating module code) still works on locked
databases
- Only `spacetime delete` is blocked
This matches the intent: protect prod from accidental destruction while
allowing normal deployments.
---------
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
## Summary
- add a new `templates/astro-ts` template based on the existing Astro +
SpacetimeDB integration work
- include Astro SSR, a React client island for realtime updates, and a
small `server:defer` example
- add Astro quickstart documentation under
`docs/docs/00100-intro/00200-quickstarts/00152-astro.md`
## Validation
- `pnpm install`
- `pnpm -F spacetimedb build`
- `pnpm -F ./templates/astro-ts build`
## Notes
- I did not add `astro-ts` to the built-in template listing in
`spacetime dev` docs, to match the current `nextjs-ts` pattern.
---------
Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
# Description of Changes
<!-- Please describe your change, mention any related tickets, and so on
here. -->
moves the docs file for spacetime.json into the right folder so that the
website shows it.
# API and ABI breaking changes
<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->
no
# Expected complexity level and risk
<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.
This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.
If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->
1
# Testing
<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->
no testing needed
Per Tyler's request. Consolidates the three commitlog proposals from
SpacetimeDBPrivate into a single public reference document:
- **Proposal 0003** (commitlog format): Segment structure, commit
format, transaction records, mutations, integrity model, wire format,
versioning
- **Proposal 0016** (offset index): Index files, entry format,
read/write behavior, configuration
- **Proposal 0027** (commitlog epoch): Epoch field for replication,
format version 1
The document is written in textbook style with no emdashes or
contractions, following the docs style guide. All proposal-specific
language (motivation sections, alternatives considered, implementation
stages, etc.) has been removed in favor of a direct reference format.
Placed at
`docs/docs/00200-core-concepts/00100-databases/00400-commitlog.md`
alongside the existing database concept docs.
No private repo details are referenced.
---------
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
# Description of Changes
Fixed a CLI call in docs Unity tutorial that generated client module
code in an incorrect directory.
# API and ABI breaking changes
None.
# Expected complexity level and risk
1
# Testing
Built a project by following the tutorial with the wrong call vs the
fixed call. Compared against different parts of the tutorial to confirm
the intent.
---------
Signed-off-by: T-Podgorski <147391857+T-Podgorski@users.noreply.github.com>
Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Fixes#4592
Adds a "Supported Column Types" section to the Index documentation page
listing:
- **Supported types**: integers (all widths), bool, String, Identity,
ConnectionId, Uuid, Hash, and no-payload enums with
`#[derive(SpacetimeType)]`
- **Unsupported types**: floats (no total ordering),
ScheduleAt/TimeDuration/Timestamp (not yet supported, links #2650),
Vec/arrays, enums with payloads, nested structs
- **Workaround tip**: scaled integers for floating-point coordinates
- **Direct index restrictions**: only u8/u16/u32/u64 and no-payload
enums
The list is derived from the `FilterableValue` trait implementations in
`crates/lib/src/filterable_value.rs` and the direct index validation in
`crates/schema/src/def/validate/v9.rs`.
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
This is the implementation to resolve#4424
# Description of Changes
* Add support for `IEnumerable<T>` as a valid C# View return type in
codegen, so view implementations can return query results without
forcing `ToList()`. The generator now detects `IEnumerable<T>`,
serializes it via the list serializer.
* Snapshots have been updated with a test to confirm that
`IEnumerable<T>` rather than checking it is unsupported (which we had
added when removing support during the transition away from `Query<T>`
usage.
* Refreshes docs/examples to reflect the new supported signature.
# API and ABI breaking changes
No breaking changes. This is additive support for an existing .NET
interface.
# Expected complexity level and risk
2 - Low
# Testing
- [X] Rebuilt CLI locally, ran regression tests, and `dotnet tests` in
C# module bindings.
- [X] Tested updated docs code snippets to ensure they resolve in an IDE
and publish.
---------
Signed-off-by: Ryan <r.ekhoff@clockworklabs.io>
Per Joshua: the note about `Math.random()` in the reducer context docs
is out of date and incorrect. TypeScript modules should use `ctx.random`
instead.
**Changes:**
- Remove `Math.random()` from the warning about non-deterministic RNGs
(it was listed alongside C#'s `Random` as something to avoid)
- Replace the incorrect `:::note` block with a proper table row
documenting `ctx.random` in the TypeScript context properties reference
- Same fixes applied to versioned docs (v1.12.0)
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
# Description of Changes
Implements the fix for #4130 by updating docs with accurate usage
instructions for Query with Indexes in C#.
# API and ABI breaking changes
Docs only, no API or ABI changes
# Expected complexity level and risk
1
# Testing
- [X] Tested code snippets through addition of regression tests in #4123
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
# Description of Changes
- Fix issue with back to top button displays incorrectly
- Move the button to bottom left not to overlap with Ask AI
# Demo and screenshots
- After
<img width="1459" height="894" alt="image"
src="https://github.com/user-attachments/assets/75b4edda-dc54-493f-9274-0ca78f10fac7"
/>
https://github.com/user-attachments/assets/4cf7c3f4-51cc-4987-87db-b065ce4f7746
- Before
<img width="173" height="78" alt="image"
src="https://github.com/user-attachments/assets/052be945-fd2b-4276-a129-89c34a6a818b"
/>
<!-- Please describe your change, mention any related tickets, and so on
here. -->
# API and ABI breaking changes
<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->
# Expected complexity level and risk
1
<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.
This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.
If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->
# Testing
<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->
- [x] Back to top button displays correctly and works
# Description of Changes
- Updated the Unreal SDK and generated Unreal bindings for the websocket
2.0 protocol/model
- Reworked DbConnectionBase to handle the updated message shapes
- Switched subscription handling over to new message types and
QuerySetId
- Updated reducer to ReducerResult, removal of callbacks, and set
reducer flags
- Added event table support
- Baked in multi-module support replacing [the old
PR](<https://github.com/clockworklabs/SpacetimeDB/pull/3417>)
- Added functionality to generate module support for multiple folders in
the Unreal project (add <module>.Build.cs, <module>.h, <module>.cpp)
using the --module-name
- Add new configuration option for spacetime generate to handle module
prefix
- Regenerated Unreal Blackholio/TestClient/QuickstartChat bindings
- Rebuilt Unreal Blackholio's consume entity to use event tables
- Updated migration documentation
- Updated the version bump tool to impact C++
# API and ABI breaking changes
- Unreal websocket/message handling updated to the new protocol
- Unreal generation now expects a real .uproject target and will stop
immediately if project
metadata is invalid instead of continuing past setup issues.
# Expected complexity level and risk
3 - A large set of changes to update the websocket/message handling
along with heavy codegen changes to handle multi-module support
# Testing
Test coverage of the Unreal SDK will need expansion in a future ticket
once our issues with flakiness on CI is resolved.
- [x] Updated Unreal Blackholio
- [x] Ran full Unreal SDK test suite
- [x] Built new test project using the new `--module-prefix`
- [x] Run through Unreal Blackholio (C++ and Blueprint)
- [x] Rebuilt Unreal Blackholio with multi-module, and duplicate
generated module testing side-by-side modules that would overlap
# Review Question(s)
- [x] Updates to `spacetime init` have made the tutorial a little
confusing with pathing for the Unreal Blackholio tutorial. To fix though
we'd have to update all the commands to be more explicit, or update the
tutorial `spacetime init` to use `--project-path .` to keep pathing
simpler, thoughts?
---------
Signed-off-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: Ryan <r.ekhoff@clockworklabs.io>
# Description of Changes
Adds `count` to rust's procedural view API.
This API already existed in C# and typescript. This patch just adds
tests for those module languages.
We were already tracking reads for `count`, and so all this patch does
is add the new rust module bindings.
# API and ABI breaking changes
None
# Expected complexity level and risk
1
# Testing
Smoketests for rust, C#, and typescript.
# Description of Changes
Adds a new reference documentation page for `spacetime.json` and fixes
several bugs where the CLI behavior diverged from the proposal.
**Docs:**
- New page at `/cli-reference/spacetime-json` covering config structure,
field reference, generate configuration, children/inheritance,
`spacetime dev` config, database selection, flag overrides,
`--no-config`, `--env`/environments, config file discovery, and editor
support
**Bug fixes:**
- `generate` was incorrectly inherited by child databases. A child with
a different `module-path` would silently inherit the parent's generate
entries, causing bindings to be written to the wrong output directory.
Generate is now never inherited, matching the proposal.
- The source conflict rule for `module-path`/`bin-path`/`js-path` was
not implemented during inheritance. A child specifying `module-path`
could still inherit `bin-path` from the parent. Now, if a child
specifies any module source, the others are not inherited.
- `--num-replicas` was not marked as a per-database override, so it
could be used with multiple databases selected without error.
# API and ABI breaking changes
None. These are bug fixes aligning the implementation with the intended
behavior from the proposal:
- `generate` inheritance was never documented or intended
- The source conflict rule was specified in the proposal but not
implemented
- `--num-replicas` as per-database is consistent with the other
module-source flags
# Expected complexity level and risk
2 - The changes are small and well-scoped. The generate inheritance fix
simplifies the code (removes a parameter). The source conflict rule adds
a straightforward check during field inheritance. Tests have been
updated to match.
# Testing
- [x] All 136 existing CLI tests pass
- [x] Updated tests for generate non-inheritance behavior
- [x] Docs site builds successfully, page renders in sidebar
- [ ] Manual test: verify a child with a different `module-path` no
longer inherits parent's `generate`
- [ ] Manual test: verify `--num-replicas` errors when multiple
databases are selected
---------
Signed-off-by: Tyler Cloutier <cloutiertyler@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Phoebe Goldman <phoebe@clockworklabs.io>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
# Description of Changes
Updates the reference docs with the implications of primary key
inference for query builder views, implemented in #4572, #4573, #4614.
# API and ABI breaking changes
None
# Expected complexity level and risk
1. Docs only change
# Testing
N/A
Relates to #4608
## Timeout bump
The previous defaults for HTTP requests in procedures were far too
restrictive:
| | Before | After |
|---|---|---|
| Default (no timeout set) | 500ms | **30s** |
| Maximum (clamp ceiling) | 10s | **180s** |
Users are hitting the 10s ceiling when calling LLM APIs (OpenAI, Gemini,
etc.) from procedures. These APIs routinely take 30-120 seconds,
especially for image/vision models. The 500ms default also caused silent
failures for users who did not explicitly set a timeout.
### Comparable platforms
- **Supabase Edge Functions**: 150s (free) / 400s (pro) total execution
- **Vercel Functions**: 10s (hobby) / 60s (pro) / 300s (enterprise)
total
- **Convex actions**: 120s limit
- **AWS Lambda**: up to 15 min total
- **Firebase/GCF**: 60s default, configurable up to 540s
Most platforms do not separately clamp outbound HTTP timeouts at all.
## Docs fix
The procedures docs page had a note inside the C++ tab only that said
`All timeouts are clamped to a maximum of 500ms by the host`. This was
wrong (the max was 10s, not 500ms) and buried in the wrong place
(applies to all languages, not just C++).
Moved the note outside the language tabs and updated the values to match
the new code.
### Changes
- `crates/core/src/host/instance_env.rs`: `HTTP_DEFAULT_TIMEOUT` 500ms →
30s, `HTTP_MAX_TIMEOUT` 10s → 180s
- `docs/.../procedures.md`: Fix and relocate timeout note
---------
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
# Description of Changes
This fixes an Issue in the Rust [Chat App
Tutorial](https://spacetimedb.com/docs/tutorials/chat-app#creating-the-client),
that is caused by the [Event Type
Changes](https://spacetimedb.com/docs/upgrade/?client-language=rust&server-language=rust#event-type-changes)
in 2.0
This resulted in other clients not receiving new messages, since they
are now Event::Transaction and no longer included within the
Event::Reducer
# API and ABI breaking changes
<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->
I don't think any? I only changed a tutorial, the real change was in 2.0
# Expected complexity level and risk
1
# Testing
- [x] I ran the Tutorial app with these changes and messages started to
appear as expected on the second client when writing something on the
first.
There might be more places where this is an Issue, I just noticed this
one while following the Tutorial.
---------
Signed-off-by: Frederik <39029799+OMGeeky@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Phoebe Goldman <phoebe@clockworklabs.io>
Audited all registered routes in `database.rs` and `identity.rs` against
the HTTP API documentation.
## Fixes
**database.md:**
- `/v1/database/:name_or_identity` publish: `POST` → `PUT` (code has
`db_put: put(publish::<S>)`)
- `DELETE` row in summary table: anchor pointed to POST section instead
of DELETE section
- Typo: `Updgrade` → `Upgrade` in WebSocket subscribe headers
**identity.md:**
- Removed `POST /v1/identity/:identity/set-email` — documented but has
no handler registered in `IdentityRoutes` (dead documentation)
## Routes in code but intentionally not documented (internal/unstable)
- `POST /v1/database/:noi/pre_publish`
- `PUT /v1/database/:noi/reset`
- `GET /v1/database/:noi/unstable/timestamp`
These are used internally by the CLI and are not part of the public API.
---------
Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
## Summary
This PR creates a comprehensive self-hosted JWT key rotation how-to for
SpacetimeDB with reproducible defaults, identity-preserving rotation
guidance, and host-scoped data migration runbooks. It is written for
both operators and automation workflows, with explicit guardrails for
production-like VM environments.
## Key Changes
- Adds a top-level assumptions/risk section for a multi-host topology
(`prod`, `test`, `dev`, optional `local`) including backup prerequisites
before rotation or sync.
- Defines an opinionated, end-to-end path contract for keys:
- host source: `./.generated/spacetimedb-keys`
- runtime mount: `/etc/spacetimedb`
- startup args pinned to `/etc/spacetimedb/id_ecdsa` and
`/etc/spacetimedb/id_ecdsa.pub`
- Includes reproducible quickstart scaffolding:
- OpenSSL commands for compatible ES256/P-256 key generation
- non-container and Docker startup examples
- rotation/verify command sequence and marker checks
- Documents one unified tooling surface around `spacetimedb-tooling.ts`
for:
- rotate (`--dry-run`, `--yes`)
- verify (`--verify-only`)
- token continuity (`--resign-token-only`)
- explicit token/key path overrides (`--publisher-cli-toml-path`,
`--private-key-path`)
- Clarifies 401 vs 403 behavior and why identity drift causes publish
failures after rotation.
- Covers all rotation strategies in one place:
- clean-slate rotation (stateless/dev)
- identity-preserving rotation (stateful)
- OIDC-backed identity model for production
- Adds host-scoped migration runbooks for staged sync (`prod -> test ->
dev`) with destination-side token re-signing semantics (run on
destination host context, including SSH examples).
- Explicitly separates conceptual topology guidance from currently
implemented sync primitives in reference tooling to avoid over-claiming.
- Adds operational guardrails for sync promotions:
- `rsync --delete` is destructive
- stop/start ordering around sync
- required acceptance gates: key parity, destination re-sign,
restart/redeploy, publish marker validation
- Expands verification and automation content:
- PEM/parity/fingerprint/newline checks
- AI/automation contract with inputs, outputs, required command order,
and success/failure markers
- troubleshooting flow for `InvalidSignature` and ownership mismatch
errors
## Why This Matters
The most common failure mode in self-hosted fleets is identity drift:
signatures validate, but `spacetime publish` still fails with `403
Forbidden` because destination ownership no longer matches the
publishing identity after key rotation or data movement.
The updated how-to makes these operator requirements explicit:
1. preserve identity continuity across rotations and host promotions
2. re-sign destination tokens after `rsync` in destination host context
3. treat restart/redeploy and publish markers as promotion gates
Following this runbook prevents regressions where key material is
correct but publish still fails due to stale signatures or owner
mismatch state.
## Why JWT Key Rotation Is Essential for Self-Hosters
In self-hosted deployments, operators are the signing authority.
Rotation is both a security control and an operational correctness
requirement.
### Security value
- reduces exposure window for compromised private keys
- invalidates old/stolen tokens after rotation
- mitigates risk from snapshots, backups, clones, and long-lived VM
access
### Operational value
- keeps key material consistent across multi-VM environments
- reduces publish outages after promotion/sync operations
- prevents avoidable `401`/`403` failures in routine release workflows
## Scope
- docs-only change
- public-safe examples only (no internal org names, private vault IDs,
or private secret prefixes)
- includes non-container and Docker workflows, self-publish/versioning
guidance, and marker-based validation (`PUBLISH_SUCCESS`,
`PUBLISH_FAILED`)
- includes data migration workflow guidance (`rsync` + destination
re-sign + restart/redeploy + publish checks)
---------
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Fixes#1972
Adds client-side log level filtering to `spacetime logs`:
- `--level <LEVEL>` / `-l <LEVEL>`: Show only logs at the specified
severity or higher. Valid values: `trace`, `debug`, `info`, `warn`,
`error`, `panic`. Default: show all logs (no filtering).
- `--level-exact`: When combined with `--level`, show only logs at
exactly the specified level.
Severity order (most to least): panic > error > warn > info > debug >
trace.
Examples:
```
spacetime logs mydb --level warn # Show only warn, error, and panic
spacetime logs mydb --level info # Show info and above
spacetime logs mydb --level error --level-exact # Show only errors
```
Filtering is done client-side.
---------
Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
# Description of Changes
Closes https://github.com/clockworklabs/SpacetimeDB/issues/4496.
The docs refer to a block mentioning `/v1/publish` but we don't have
such a block in our example config. What we actually have is:
```
# Block all other routes explicitly. Only localhost can use these routes. If you want to open your
# server up so that anyone can publish to it you should comment this section out.
location / {
allow 127.0.0.1;
deny all;
}
```
# API and ABI breaking changes
None.
# Expected complexity level and risk
1.
# Testing
None
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
# Description of Changes
Contains 2 changes to documentation:
* Updates Unity Client Blackholio tutorial, part 2, with a corrected
`call` command. `Debug` became `debug` to match the automatic case
conversion that now occurs. Originally found and reported by discord
user `chrispavs`
* Updates Unity Client Blackholio tutorial, part 2, with the `out-dir`
path to match the path given in the [Entering the
Game](https://spacetimedb.com/docs/tutorials/unity/part-3#entering-the-game)
of `step 3`.
# API and ABI breaking changes
None
# Expected complexity level and risk
1 - Docs correction
# Testing
- [X] Tested all `blackholio` tutorial steps using C# server and Unity
client
In the `init` reducer, `ctx.sender` is the **module owner** — the
identity of the user who published the database. This is the only
lifecycle reducer where the owner identity is automatically provided.
Added a tip to the lifecycle docs showing:
- That `ctx.sender` in `init` is the owner
- How to store it in a table for later authorization checks
- Examples in TypeScript, C#, and Rust
Closes#3229
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
The 'Option 2: overwrite the name of individual tables' section of the
2.0 migration guide had an empty TypeScript tab. Adds a complete example
using `table()` with an explicit `name` property to preserve the
pre-conversion table name.
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
# Description of Changes
LLM benchmark updates for local development:
- **Local SDK paths**: Templates use relative paths to workspace crates
(`crates/bindings`, `crates/bindings-csharp`,
`crates/bindings-typescript`) instead of published packages, so the
bench runs against local SDK changes.
- **NODEJS_DIR support**: On Windows (e.g. nvm4w), if `pnpm` is not on
PATH, the bench uses `NODEJS_DIR` to locate `pnpm` and prepends it to
PATH for subprocesses.
- **Refactor**: Extracted `relative_to_workspace()` in `templates.rs`
and removed noisy `NODEJS_DIR` logging in `publishers.rs`.
- **Benchmark results**: Updated `docs/llms/llm-comparison-details.json`
and `docs/llms/llm-comparison-summary.json`.
# API and ABI breaking changes
None.
# Expected complexity level and risk
**2** — Local-only changes to the benchmark tool. Templates now require
local SDKs to be built (especially TypeScript: `pnpm build` in
`crates/bindings-typescript`). No impact on published SDKs or runtime.
# Testing
- [ ] Run `cargo llm run --lang rust --modes docs --providers openai`
from repo root
- [ ] Run TypeScript benchmarks with `pnpm build` in
`crates/bindings-typescript` first
- [ ] On Windows with nvm4w, set `NODEJS_DIR` if `pnpm` is not on PATH
and run TypeScript benchmarks
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: clockwork-labs-bot <bot@clockworklabs.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Fixes a missing word in the Unity and Unreal tutorial part-3 docs.
**Before:** `specify a specific at which to call a reducer once`
**After:** `specify a specific **time** at which to call a reducer once`
Fixed in 4 files (current docs + v1.12.0 versioned docs), 6 occurrences
total.
Spotted by Tyler.
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Now that scheduled reducers are private, this warning is no longer
necessary.
# Description of Changes
- removed Security Considerations section from Schedule Tables
documentation
Signed-off-by: Tao Tien <29749622+taotien@users.noreply.github.com>
Co-authored-by: joshua-spacetime <josh@clockworklabs.io>
# Description of Changes
- Rename `Spacerace` to `Referrals` for docs nav item to align with
updated naming
<!-- Please describe your change, mention any related tickets, and so on
here. -->
# Screenshots
- After:
<img width="1510" height="49" alt="image"
src="https://github.com/user-attachments/assets/3bdbe6ec-8a51-4686-9292-28c38b6d14d9"
/>
- Before:
<img width="1460" height="47" alt="image"
src="https://github.com/user-attachments/assets/5c70b0ef-d5fc-42fa-9dc9-5fd4f034d415"
/>
# API and ABI breaking changes
<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->
# Expected complexity level and risk
1
<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.
This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.
If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->
# Testing
<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->
- [x] Docs displays correctly
# Description of Changes
This change is needed since the AI halicunates that the name is schedule
for some dam reason every time in the llm tests. while it is scheduled
https://github.com/clockworklabs/SpacetimeDB/blob/e2f8a607593f8e2e446df06d84b21e26af2bfc68/docs/llms/docs-benchmark-details.json#L90
# API and ABI breaking changes
<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->
# Expected complexity level and risk
1
<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.
This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.
If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->
# Testing
<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->
- [ ] Run the LLM benchmark and see if this fixes it
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
# Description of Changes
Some examples in our cheat-sheet incorrectly used a `filter` method on a
unique index. Unique indexes expose `find`, and non-unique indexes
expose `find`. This commit updates the cheatsheet to use the appropriate
index seek methods.
# API and ABI breaking changes
N/a
# Expected complexity level and risk
N/a
# Testing
N/a
# Reviewers
Does the C++ code work as written, or do you have to do something
horrible to do with ranges?
# Description of Changes
* Updates `00500-views.md` with:
* Changes returned value to a nullable value, to match the return type
defintion.
* Wraps sample code in `public partial class Module` so pasting it in to
IDE will not return errors.
* Updates `00500-cheat-sheet.md` with:
* Changes reducer names to not start with `On` to avoid error `STDB0010:
Reducer method OnConnect starts with 'On', which is a reserved prefix.`
* Adds `Accessor` values to views.
* Updates `Filter()` returned value to use `.ToList()` and the return
type to use `List<Player>` rather than `IEnumerable<Player>` to avoid
error, due to needing a return type to be `Vec<T>` or `Option<T>`.
* Updated `Coddgen.Test` to include tests verifying current behavior of
`IEnumerable<T>`, to aid in future update to allow a return type of
`IEnumerable<T>` to be allowed and converted internally to the required
type.
# API and ABI breaking changes
None
# Expected complexity level and risk
1 – documentation-only edits with no behavioral impact.
# Testing
- [X] Changed code blocks tested locally to ensure formatting resolved
in IDE.
# Description of Changes
<!-- Please describe your change, mention any related tickets, and so on
here. -->
- Right now if you go to the docs https://spacetimedb.com/docs/ and you
click on spacerace in the upper right it will 404. This PR fixes this
issue.
# API and ABI breaking changes
None
<!-- If this is an API or ABI breaking change, please apply the
corresponding GitHub label. -->
# Expected complexity level and risk
1 - just a docs update
<!--
How complicated do you think these changes are? Grade on a scale from 1
to 5,
where 1 is a trivial change, and 5 is a deep-reaching and complex
change.
This complexity rating applies not only to the complexity apparent in
the diff,
but also to its interactions with existing and future code.
If you answered more than a 2, explain what is complex about the PR,
and what other components it interacts with in potentially concerning
ways. -->
# Testing
<!-- Describe any testing you've done, and any testing you'd like your
reviewers to do,
so that you're confident that all the changes work as expected! -->
```
cd docs
npm install
npm run dev
```
- [x] spacerace button works in docs
# Description of Changes
Fix AI assistant rules links in llms.txt, they were missing a `/docs`
# API and ABI breaking changes
None.
# Expected complexity level and risk
0.0001
# Testing
Clicked the link
## Summary
Multiple fixes and improvements to `spacetime dev`, `spacetime publish`,
`spacetime init`, and templates:
### CLI fixes
- **Fix `spacetime dev` watch path and .env.local handling** for
templates with a `spacetimedb/` subdirectory
- **Validate package manager availability** before installing
dependencies — re-prompts if the selected PM isn't on PATH
- **Remove JS/TS beta warning** from `spacetime publish`
- **Remove unstable warning** from `spacetime init`
- **Remove unused `spacetime energy` command** (can be re-added later
when properly implemented)
- **Fix `tsc` detection on Windows** — `set_extension(".cmd")` produced
`tsc..cmd` (double dot); fixed to `set_extension("cmd")`
- **Add `typescript` as devDependency** to all server template
`spacetimedb/package.json` files so `tsc` is available during build
- **Strip `\?\` extended-length path prefix** from user-facing output in
both `dev` and `publish` commands (produced by `fs::canonicalize()` on
Windows)
- **Fix publish reporting success when user declines** non-local server
prompt — changed `return Ok(())` to `bail!()` consistent with other
abort cases
- **Forward stdin to client process** in `spacetime dev` so interactive
CLI templates work
### Template fixes
- **Fix Angular template environment variables** — Angular's esbuild
builder doesn't support `import.meta.env`, so we use a dev script to
generate `environment.local.ts` with Angular's native `fileReplacements`
pattern
- **Fix TanStack Start template** — rename `createRouter` to `getRouter`
(v1.121+ breaking change), upgrade to React 19, and add
`@vitejs/plugin-react` for automatic JSX runtime support
- **Fix `moduleResolution` in remix-ts and nextjs-ts** server tsconfigs
— change from `"node"` to `"bundler"` to support subpath exports like
`spacetimedb/server`
- **Fix browser-ts template** — convert from static HTML + IIFE bundle
to standard Vite dev server app so it works with `spacetime dev` and
reads env vars from `.env.local`
- **Add `deno` as devDependency** to deno-ts template (matches how
bun-ts includes bun)
- **Convert basic-ts from empty web app to CLI app** matching basic-rs —
connect, subscribe to person table, print on insert
## Test plan
- [x] `cargo test -p spacetimedb-cli` — all 133 tests pass
- [ ] `spacetime dev --template angular-ts` — verify Angular app
connects with correct database name
- [ ] `spacetime dev --template react-ts` — verify React template still
works
- [ ] `spacetime dev --template tanstack-ts` — verify TanStack Start
template loads without errors
- [ ] `spacetime dev --template remix-ts` — verify Remix template builds
and runs
- [ ] `spacetime dev --template nextjs-ts` — verify Next.js template
still works
- [ ] `spacetime dev --template browser-ts` — verify Vite dev server
starts and app connects
- [ ] `spacetime dev --template bun-ts` — verify Bun CLI template runs
interactively
- [ ] `spacetime dev --template basic-ts` — verify CLI connects and
prints on insert
- [ ] Verify no `\?\` prefix in any displayed paths on Windows
- [ ] Verify no `tsc not found` warning when building server modules
- [ ] Select unavailable package manager at init prompt — verify
re-prompt
- [ ] Decline non-local server prompt — verify clean error instead of
"Published successfully!"
---------
Co-authored-by: Piotr Sarnacki <drogus@gmail.com>
Co-authored-by: John Detter <4099508+jdetter@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <bot@clockworklabs.com>
## Summary
Enable confirmed reads by default for all WebSocket subscriptions and
SQL queries. This is a 2.0 breaking change that improves data integrity.
### What changed
Previously, subscription updates and SQL results were sent to clients
immediately, before the transaction was confirmed durable. A server
crash could cause clients to have observed data that was lost.
Now the server defaults to `confirmed=true`. Clients receive updates
only after durability is confirmed. This adds a small latency cost but
guarantees that any data a client receives will survive a server
restart.
### Changes
**Server (2 files, 2 lines each):**
- `subscribe.rs`: `SubscribeQueryParams.confirmed` defaults to `true`
- `database.rs`: `SqlQueryParams.confirmed` defaults to `true`
**Documentation:**
- Migration guide updated with "Confirmed Reads Enabled by Default"
section
- Added to overview list and quick migration checklist
### Opt-out
Clients can opt out by explicitly passing `?confirmed=false` in the
WebSocket URL or using `.withConfirmedReads(false)` /
`.WithConfirmedReads(false)` / `.with_confirmed_reads(false)` in SDKs.
### Smoketest impact
Smoketests that don't explicitly pass `--confirmed` will now get
confirmed reads via the server default. This should not cause failures
-- confirmed reads only add a small wait for durability confirmation
before sending results. The `confirmed_reads.py` smoketest explicitly
passes `--confirmed` and continues to work as before.
### SDK impact
No SDK changes needed. SDKs only send the `confirmed` query parameter
when explicitly set by the user. When not set, the server default
applies -- which is now `true`.
---------
Signed-off-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: clockwork-labs-bot <bot@clockworklabs.com>
Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
Co-authored-by: Zeke Foppa <bfops@users.noreply.github.com>
# Description of Changes
- Update llm benchmark results based on latest testing
- Clean up details file to remove old models
- Regenerated the summary file
# API and ABI breaking changes
- None
# Expected complexity level and risk
- 1
# Testing
- Verify the new summary file loads correctly on the website.
# Description of Changes
* Updates directory tree to reflect the actual results of running
`spacetime dev --template basic-cs my-spacetime-app` with no additional
arguments.
* Updates the `Add` -> `add` reducer call to use lower-case to match the
default when no override is specified.
* Updates the `SayHello` -> `say_hello` reducer call to use lower-case
to match the default when no override is specified.
# API and ABI breaking changes
None
# Expected complexity level and risk
1
# Testing
- [X] Walked through every step with a local server to test behavior.
This involved.
* Cleared all local cache and rebuilding the CLI.
* Rebuilding the DLLs
* From my test project directory, running:
`D:\Projects\ClockworkLabs\SpacetimeDB\target\debug\spacetimedb-cli.exe
dev --template basic-cs my-spacetime-app` and selecting the default
values.
* This threw an error because, I believe, it was not using the local
DLLs.
* Going into each `.csproj` to ensure they are using the local versions
of the files.
* Running the remaining commands, while targeting the local CLI
executables:
* Note: `local` server is mapped to `127.0.0.1:3000`
```
D:\Projects\ClockworkLabs\SpacetimeDB\target\debug\spacetimedb-cli.exe publish -s local my-spacetime-app
D:\Projects\ClockworkLabs\SpacetimeDB\target\debug\spacetimedb-cli.exe call -s local my-spacetime-app add Alice
D:\Projects\ClockworkLabs\SpacetimeDB\target\debug\spacetimedb-cli.exe sql -s local my-spacetime-app "SELECT * FROM Person"
D:\Projects\ClockworkLabs\SpacetimeDB\target\debug\spacetimedb-cli.exe call -s local my-spacetime-app say_hello
D:\Projects\ClockworkLabs\SpacetimeDB\target\debug\spacetimedb-cli.exe logs -s local my-spacetime-app
```
# Description of Changes
Docs will now go to version 2.0.0 by default, and there is a banner with
a link to the newer docs if someone is viewing the v1 docs.
# Expected complexity level and risk
1. Biggest risk here is breaking links.
# Testing
I tested this locally, and checked that links are working.
There is also a broken link checker in the CI.
# Description of Changes
Removes left over references to the query builder's `.build()` method as
well as some stale C# references from `llms.md`.
Only rust and C# docs needed updating.
# API and ABI breaking changes
None
# Expected complexity level and risk
1. Small docs update
# Testing
N/A
## Summary
- Update the `QuickstartLinks` component on the Getting Started
(`/docs`) page to show all 16 quickstart guides instead of just 4
(TypeScript, C#, Rust, React)
- The component now uses `useDocsVersion()` to filter items based on the
active doc version, so v1.12 only shows quickstarts that exist in that
version while v2.0 shows all 16
- Add new SVG logos for Vue, Nuxt, Svelte, Angular, TanStack Start,
Deno, and C++
- Replace existing logos (React, Next.js, Node.js, Bun, Remix, HTML5)
with consistent monochrome `currentColor` versions sourced from the
spacetime-web homepage
- Fix Rust logo visibility in dark mode by removing hardcoded
`style="color: black;"`
## Test plan
- [ ] Verify the Getting Started page on v2.0.0-rc1 shows all 16
quickstart cards
- [ ] Verify the Getting Started page on v1.12.0 shows only the
quickstarts that exist in that version (react, vue, svelte, typescript,
rust, c-sharp)
- [ ] Verify all card links navigate to the correct quickstart page
- [ ] Verify logos are visible in both light and dark mode
# Description of Changes
- Node.js: Use esbuild instead of tsx
- Node.js: Remove interactive CLI since it doesn't work with `spacetime
dev`
- Next.js: Fix onError callback to use single argument (ctx) and use
ctx.event for the error.
- Next.js: Replace lint-disable comment with `_connection` for the
unused variable.
- Updated quickstart docs to use proper `withDatabaseName`
# API and ABI breaking changes
None.
# Expected complexity level and risk
**Complexity: 1–2.** Small tooling, type, and lint tweaks. Low risk.
# Testing
- [ ] Build affected templates (e.g. `pnpm build` in nextjs-ts).
- [ ] Lint passes.
# Description of Changes
Expanded and reorganized the 2.0 migration guide, and also deleted a
file that was in the wrong place. (The word "migration" is
overloaded...)
# API and ABI breaking changes
N/a
# Expected complexity level and risk
Like, 1 I guess, since this isn't code? But we should be careful to get
this right.
# Testing
- [x] Pasted all 2.0 Rust examples into a project based on the
`basic-rs` template and got 'em to build.
- This required filling in some code outside the examples (defining
`play_damage_animation`, binding `target` and `amount`), and changing
one table name that was used in two examples, but otherwise everything
is valid.
- I didn't test the 1.0 examples.
---------
Co-authored-by: Jason Larabie <jason@clockworklabs.io>
Co-authored-by: = <cloutiertyler@gmail.com>
# Description of Changes
This change cuts a version of the docs from 1.12.0
(e45cf891c2), and saves it under
`docs/versioned_docs/version-1.12.0`.
If you go to the docs page, it will redirect to the 1.12.0 docs, which
has a banner at the top for trying the prerelease docs:
<img width="1027" height="283" alt="Screenshot 2026-02-20 at 12 07
39 PM"
src="https://github.com/user-attachments/assets/8ff3d622-b693-469a-980a-01c34d0506b8"
/>
If you select the prelease docs, there is a warning banner at the top:
<img width="886" height="299" alt="Screenshot 2026-02-20 at 12 08 52 PM"
src="https://github.com/user-attachments/assets/5508a635-765e-40cc-ad2a-cbbed7f779dd"
/>
# Expected complexity level and risk
This only changes docs.
# Testing
I've testing by running this locally.
# Description of Changes
Deno quickstart template now uses `package.json` instead of `deno.json`
so `spacetime dev` can run it. Added `templates/deno-ts/package.json`,
removed `deno.json`, and updated the Deno quickstart doc.
# API and ABI breaking changes
None.
# Expected complexity level and risk
**1** — Template and docs only.
# Testing
- [ ] `spacetime dev --template deno-ts` and confirm client runs.
- [ ] Spot-check updated Deno quickstart doc.
# Description of Changes
This PR introduces a possibility to skip passing a DB name to various
commands if there is a config file with one database defined
# API and ABI breaking changes
This changes the behaviour of several CLI commands:
1. call
2. subscribe
3. sql
4. describe
5. logs
6. delete
# Expected complexity level and risk
4 - it's tricky to get all of the combinations of CLI arguments right
# Testing
I've tested the simplest cases manually.
---------
Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com>
Co-authored-by: = <cloutiertyler@gmail.com>