# Creating custom modules

Step-by-step guide to scaffolding a Surrealism module, exposing functions with attributes, compiling and loading into SurrealDB.

This page walks you through the options available when building a [Surrealism](/docs/learn/extensions/plugins/overview.md) module from scratch.

## Prerequisites

You need a recent [Rust toolchain](https://www.rust-lang.org/tools/install), the `wasm32-wasip2` target, and the SurrealDB CLI (`surreal`) on your `PATH`.

```sh
rustup target add wasm32-wasip2
```

Install SurrealDB from the [installation guide](/docs/running/installation.md) if you have not already.

## Scaffold a module project

The fastest way to start is `surreal module init`:

```sh
surreal module init
```

This creates the project scaffold (`Cargo.toml`, `surrealism.toml`, `.cargo/Config.toml` with flags needed for the WASI build, and `src/lib.rs`) ready for Surrealism builds.

```toml title=".cargo/Config.toml flags"
[build]
rustflags = ["--cfg", "tokio_unstable"]
```

To automatically set the name and organisation for a project, you can use the following flags:

```sh
surreal module init --headless --org surrealdb --name my_surreal_module ./my_surreal_module
```

## Create a Rust project manually

Create a new library crate for your module:

```sh
cargo new --lib my_surreal_module
cd my_surreal_module
```

Configure the library as a dynamic WASM library and add the Surrealism SDK plus any other crates you need to `Cargo.toml`, following versions recommended for your SurrealDB release:

```toml
[lib]
crate-type = ["cdylib"]
```

For a full annotated example, follow the [quick tutorial](/docs/learn/extensions/plugins/quick-tutorial.md).

## Configure `surrealism.toml`

Add a `surrealism.toml` file at the crate root next to `Cargo.toml`.

A minimal example:

```toml
[package]
organisation = "surrealdb"
name = "demo"
version = "1.0.0"

[capabilities]
allow_scripting = true
allow_arbitrary_queries = true
allow_functions = ["fn::test"]
allow_net = ["127.0.0.1:8080"]
```

Optional attached filesystem:

```toml
[attach]
fs = "fs"
```

When `[attach] fs = "fs"` is present, the `fs/` folder in your project is packed into the module archive as a read-only filesystem available to the module at runtime.

## Annotate exported functions

Expose functions to SurrealQL by annotating them with `#[surrealism]`. Only functions you mark this way are included in the module and callable from the database.

```rust
use surrealism::surrealism;

#[surrealism]
fn can_drive(age: i64) -> bool {
    age >= 18
}

#[surrealism(writeable, comment = "Creates a value in module KV")]
fn kv_set_value(key: String, value: String) -> bool {
    // implementation omitted
    true
}
```

For the full attribute reference (`writeable`, `comment`, `init`, and namespaced modules), see [Surrealism attribute reference](/docs/learn/extensions/guides/surrealism-attribute-reference.md).

## Compile with `surreal module`

From your project directory, compile to a `.surli` artefact with the Surreal CLI:

```sh
surreal module build --out demo.surli .
```

For faster local iteration, use debug builds. This works in the same way as `cargo build --debug` in skipping optimisation passes to speed up compiling time in exchange for lower performance.

```sh
surreal module build --debug --out demo.surli .
```

See the [module command reference](/docs/reference/cli/surrealdb-cli/commands/module.md) for all flags.

## Load into SurrealDB

Upload the `.surli` file with [`DEFINE BUCKET`](/docs/reference/query-language/statements/define/bucket.md) so SurrealDB can store it, then register exported functions with [`DEFINE MODULE`](/docs/reference/query-language/statements/define/module.md). The exact names and paths must match your bucket and module identifiers.

## Test your functions

Connect with the CLI, [SurrealDB Studio](/docs/explore/studio.md), or an SDK and invoke your functions from SurrealQL. Confirm return values and error handling match what you expect.

If something fails:

- verify that experimental capabilities include `surrealism` (and `files` if using buckets/files);
- verify the module was rebuilt after source changes;
- verify your SurrealDB build supports the Surrealism version your module targets.

For a high-level picture of how these steps fit together, see the [Surrealism overview](/docs/learn/extensions/plugins/overview.md).
