# embed_schema! macro

The embed_schema! macro bakes your .surql schema files into the Rust binary at compile time, so schema is always in sync with the application that ships it.

The `embed_schema!` macro reads your `database/schema/` directory at compile time and generates a Rust module containing the SQL for every `.surql` file it finds. Because the schema is compiled into the binary, there are no external files to deploy and the schema version is always tied to the application version.

Add SurrealKit to your dependencies. The `embed_schema!` macro is re-exported from the main crate, so a single dependency is enough:

```toml
[dependencies]
surrealkit = "0.7"
```

## Basic usage

Call the macro at the crate root (typically `main.rs` or `lib.rs`):

```rust
surrealkit::embed_schema!();
```

This generates an `embedded_schema` module. Call `sync` on it after connecting to apply any outstanding schema changes:

```rust
#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let db = surrealkit::connect(
        &surrealkit::DbCfg::from_env(None, &Default::default())?
    ).await?;

    embedded_schema::sync(&db).await?;

    // application startup continues here
    Ok(())
}
```

`sync` behaves identically to `surrealkit sync` from the CLI: it applies new or changed definitions and prunes any that have been removed, using the `__entity` metadata table to track state.

## What the macro generates

Given a `database/schema/` directory with these files:

```
database/schema/
├── users.surql
└── orders.surql
```

The macro generates roughly:

```rust
pub mod embedded_schema {
    pub static SCHEMA: &[surrealkit::EmbeddedSchemaFile] = &[
        surrealkit::EmbeddedSchemaFile {
            path: "database/schema/users.surql",
            sql: "DEFINE TABLE user SCHEMAFULL; ...",
        },
        surrealkit::EmbeddedSchemaFile {
            path: "database/schema/orders.surql",
            sql: "DEFINE TABLE order SCHEMAFULL; ...",
        },
    ];

    pub async fn sync(
        db: &surrealkit::Surreal<surrealkit::engine::any::Any>,
    ) -> surrealkit::anyhow::Result<()> {
        surrealkit::Sync::embedded(SCHEMA).run(db).await
    }
}
```

The generated `SCHEMA` static is public, so when you need to customise sync behaviour you can pass it to the [`Sync`](/docs/manage/schema-migration/library.md) builder directly instead of calling `embedded_schema::sync`:

```rust
use surrealkit::Sync;

Sync::embedded(embedded_schema::SCHEMA)
    .prune(false)
    .run(&db)
    .await?;
```

## Compile-time rebuild behaviour

Cargo re-runs the macro whenever a `.surql` file in `database/schema/` changes, because the macro registers each file with `include_str!`. This means schema changes always produce a fresh build, and there is no risk of shipping stale SQL.

## When to use the macro vs runtime loading

|-| `embed_schema!` | Runtime `Sync` |
|---|---|---|
| Schema location | Compiled into binary | Built from files at runtime |
| Deployment | No schema files needed | Schema directory must be present |
| Dev iteration | Rebuild required on change | Files can be swapped without rebuild |
| Best for | Production builds, Docker images | Development, mounted volumes |

For most production deployments `embed_schema!` is the right choice. For local development or environments that mount schema as a volume, building an `EmbeddedSchemaFile` slice at runtime and passing it to [`Sync::embedded`](/docs/manage/schema-migration/library.md) is more convenient.
