Skip to content
Backend
Skill

/csharp-server

SpacetimeDB C# server module SDK reference. Use when writing tables, reducers, or module logic in C#.

From plugin
spacetimedb
26k11 skills1 MCP

Claude Code

$ npx -y skills add clockworklabs/spacetimedb --skill csharp-server --agent claude-code

SKILL.md

csharp-server.SKILL.md
name: csharp-server
description: SpacetimeDB C# server module SDK reference. Use when writing tables, reducers, or module logic in C#.
license: Apache-2.0
metadata:
  author: clockworklabs
  version: "2.0"
  role: server
  language: csharp
  cursor_globs: "**/*.cs"
  cursor_always_apply: true

SpacetimeDB C# SDK Reference

Build Configuration (.NET 10)

New .NET 10 modules build as managed libraries by default. Use the CLI for WASM builds, or select the runtime identifier explicitly when invoking dotnet:

spacetime init my-project --lang csharp --dotnet-version 10
# From the generated module directory:
dotnet build                              # managed DLL
dotnet publish -c Release -r wasi-wasm     # NativeAOT-LLVM WASM
spacetime build                           # CLI selects WASM automatically
  • Do not set an unconditional `RuntimeIdentifier=wasi-wasm` in .NET 10 projects.

Keep WASM-only settings such as `PublishTrimmed`, `SelfContained`, and `MSBuildEnableWorkloadResolver=false` conditional on that RID.

  • The module must reference both `Microsoft.DotNet.ILCompiler.LLVM` and

`runtime.$(NETCoreSdkPortableRuntimeIdentifier).Microsoft.DotNet.ILCompiler.LLVM` (version `10.0.0-*`) conditionally on `RuntimeIdentifier=wasi-wasm`. The runtime package no longer supplies these dependencies transitively. Keep the dotnet-experimental NuGet feed configured for WASM restores.

  • `spacetime build` and `spacetime publish` select WASM automatically. .NET 10

does not require `--native-aot` or an AOT environment variable.

  • Allow restore when switching between managed and WASM builds; do not reuse

`--no-restore` across modes. For multi-targeted projects, select `-f net10.0` when publishing and restrict the LLVM 10 package references to .NET 10.

  • .NET 8 behavior is unchanged: WASM/JIT by default, with `--native-aot` selecting

NativeAOT where supported. The current flag is `SPACETIMEDB_WASM_AOT`; the CLI also sets/clears `EXPERIMENTAL_WASM_AOT` for older projects. Do not manually define the C# compiler symbol to choose a .NET 10 build mode.

  • Module dependencies use ordinary `ProjectReference` or packaged managed

assemblies. .NET 10 composition uses generated assembly descriptors, not the dependency's standalone WASM exports; no special root/library build flag is needed.

Module Structure

Reducers are static methods in a `static partial class`; tables are `public partial struct`s. This reference keeps everything in one `public static partial class Module`, which needs only `using SpacetimeDB;`:

Methods exported through SpacetimeDB attributes, including reducers, procedures, views, HTTP handlers, and routers, must be `public static`; generated bindings invoke them from another class.

using SpacetimeDB;

public static partial class Module
{
    [SpacetimeDB.Table(Accessor = "ScoreRecord", Public = true)]
    public partial struct ScoreRecord
    {
        [PrimaryKey]
        [AutoInc]
        public ulong Id;
        public Identity Owner;
        public uint Value;
    }

    [SpacetimeDB.Reducer]
    public static void AddRecord(ReducerContext ctx, uint value)
    {
        ctx.Db.ScoreRecord.Insert(new ScoreRecord { Id = 0, Owner = ctx.Sender, Value = value });
    }
}

Tables

`[SpacetimeDB.Table(...)]` on a `public partial struct`. `Accessor` should be PascalCase:

[SpacetimeDB.Table(Accessor = "Entity", Public = true)]
public partial struct Entity
{
    [PrimaryKey]
    [AutoInc]
    public ulong Id;
    [SpacetimeDB.Index.BTree]
    public Identity Owner;
    public string Name;
    [SpacetimeDB.Index.BTree]
    public bool Active;
}

Options: `Accessor = "PascalCase"` (recommended), `Public = true`, `Scheduled = nameof(ReducerFn)`, `ScheduledAt = nameof(field)`, `Event = true`

`ctx.Db` accessors use the `Accessor` name: `ctx.Db.Entity`, `ctx.Db.ScoreRecord`.

Column Types

| C# type | Notes | |---------|-------| | `byte` / `ushort` / `uint` / `ulong` | unsigned integers | | `U128` / `U256` | large unsigned integers (SpacetimeDB types) | | `sbyte` / `short` / `int` / `long` | signed integers | | `I128` / `I256` | large signed integers (SpacetimeDB types) | | `float` / `double` | floats | | `bool` | boolean | | `string` | text | | `List<T>` | list/array | | `Identity` | user identity | | `ConnectionId` | connection handle | | `Timestamp` | server timestamp (microseconds since epoch) | | `TimeDuration` | duration in microseconds | | `Uuid` | UUID |

Optional columns: nullable types (`string? Nickname`, `uint? HighScore`)

Column Attributes

The complete set of column attributes:

[PrimaryKey]          // primary key
[AutoInc]             // auto-increment (use 0 as placeholder on insert)
[Unique]              // unique constraint; indexes the column, enables .Find()
[SpacetimeDB.Index.BTree]  // btree index (enables .Filter() on this column)
[Default(true)]       // migration-safe default for a newly appended field

Defaults support compatible addition of a newly appended field. Do not apply `[Default(...)]` to primary-key, unique, or auto-increment fields.

Indexes

Write the index attribute fully qualified: `[SpacetimeDB.Index.BTree]`. Prefer inline for single-column; multi-column uses struct-level:

// Inline (preferred for single-column):
[SpacetimeDB.Index.BTree]
public ulong AuthorId;
// Access: ctx.Db.Post.AuthorId.Filter(authorId)

// Multi-column (struct-level):
[SpacetimeDB.Table(Accessor = "Membership")]
[SpacetimeDB.Index.BTree(Accessor = "ByGroupUser", Columns = new[] { nameof(GroupId), nameof(UserId) })]
public partial struct Membership { public ulong GroupId; public Identity UserId; ... }

Prefer a multi-column index over filtering by one column and looping.

Reducers

[SpacetimeDB.Reducer]
public static void CreateEntity(ReducerContext ctx, string name, int age)
{
    ctx.Db.Entity.Insert(new Entity { Owner = ctx.Sender, Name = name, Age = age, Activ
Read more
@clockworklabs
Ships withspacetimedb

Development at the speed of light

26k11 skills1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
25.5k
Star history of clockworklabs/spacetimedb on GitHub, a chart by star-history.com

Other skills on spacetimedb.

cli

cli

SpacetimeDB CLI reference for initializing projects, building modules, publishing databases, querying data, and managing servers

concepts

concepts

Understand SpacetimeDB architecture and core concepts. Use when learning SpacetimeDB or making architectural decisions.

csharp-client

csharp-client

SpacetimeDB C#/.NET client SDK reference. Use when building C# clients that connect to SpacetimeDB (console, desktop, or any .NET…

mcp

mcp

Operate a running SpacetimeDB database through MCP tools rather than the CLI - list databases, read schemas, run SQL, and call…

More skills from other plugins.

backend

backend

Use this skill when contributing to InsForge's backend package. This is for maintainers editing backend routes, services,…

@insforge@insforgeInstall Skill
exa-agent

exa-agent

Use Exa Agent for multi-step web research, list-building, enrichment, structured output, run continuation, and coverage…

exa10d5.2k
@exa-labs@exa-labsInstall Skill
fde-ontology

fde-ontology

多源输入→本体检出→AI审核→场景升级→代码生成 自动化管线

dgiot4w4.9k
@dgiot@dgiotInstall Skill

Questions about csharp-server.

Which coding agents can use csharp-server?
csharp-server installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.