> ## Documentation Index
> Fetch the complete documentation index at: https://villagesql.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Writing Rust Extensions

> How to write a VillageSQL extension in Rust — when to choose Rust, cargo-vsql setup, writing a function, testing, and installing.

> [card] [VillageSQL is a drop-in replacement for MySQL with extensions.](https://villagesql.com/docs/en/8.4/stable/install-server.md)
>
> All examples on this page work on VillageSQL. Install Now →

VillageSQL extensions can be written in Rust using the `villagesql` crate. The SDK handles all FFI marshaling — you write ordinary Rust, and the `extension!` macro generates the C entry points the server calls at load time.

## When to Choose Rust

Rust is the right choice when:

* You prefer Rust and don't need a C++ codebase
* You want memory safety without a garbage collector
* You're building a new extension and have no existing C++ dependency

If you have an existing C++ codebase or need the most complete custom-type builder API available today, see [Writing C++ Extensions](https://villagesql.com/docs/en/guides/cpp-extensions.md).

> [!WARNING]
>
> The API is stable for extension development, but the custom-type builder API is still maturing.

## Prerequisites

You need:

* **Rust stable toolchain** — install at [rustup.rs](https://rustup.rs)
* **cargo-vsql** — the Cargo subcommand for packaging, installing, and testing

Install `cargo-vsql` from the SDK repo:

```bash theme={null}
git clone https://github.com/villagesql/vsql-rust-sdk
cd vsql-rust-sdk
cargo install --path cargo-vsql
```

## Set Up a New Crate

Create a library crate, add the SDK, and configure it:

```bash theme={null}
cargo new --lib vsql_my_extension
cd vsql_my_extension
cargo add villagesql
```

Then set the crate type in `Cargo.toml`:

```toml theme={null}
[lib]
crate-type = ["cdylib"]
```

Add `manifest.json` alongside `Cargo.toml`:

```json theme={null}
{
  "name": "vsql_my_extension",
  "version": "0.1.0",
  "description": "My VillageSQL extension",
  "author": "Your Name",
  "license": "GPL-2.0"
}
```

## Write a Function

The [Building Extensions in Rust](https://villagesql.com/docs/en/extensions/build/rust-sdk.md) page has the full walkthrough with the ROT-13 example. The short version: implement `fn(&[InValue]) -> VdfReturn`, register it with `func!`, and wrap everything in `extension!`:

```rust theme={null}
use villagesql::{InValue, VdfReturn};

fn my_func_impl(args: &[InValue]) -> VdfReturn {
    match args.first() {
        Some(InValue::String(s)) => VdfReturn::string(s.to_uppercase()),
        Some(InValue::Null) | None => VdfReturn::null(),
        _ => VdfReturn::error("my_func: expected a STRING argument"),
    }
}

villagesql::extension! {
    funcs: [
        villagesql::func!(my_func_impl, "my_func", [villagesql::Type::String] -> villagesql::Type::String),
    ]
}
```

For custom types (binary storage, ordering, hashing), see [Custom Types in Rust](https://villagesql.com/docs/en/sdk/rust/custom-types.md).

## Test Your Extension

Write a test in `mysql-test/t/basic.test`:

```sql theme={null}
INSTALL EXTENSION vsql_my_extension;
SELECT my_func('hello');
SELECT my_func(NULL);
UNINSTALL EXTENSION vsql_my_extension;
```

Set your VillageSQL build directory, generate expected results, then run:

```bash theme={null}
export VillageSQL_BUILD_DIR=/path/to/villagesql/build
cargo vsql test --record
cargo vsql test
```

A passing run prints `[ pass ]` for each test file.

## Install in SQL

Package and install:

```bash theme={null}
cargo vsql install
```

Then in SQL:

```sql theme={null}
INSTALL EXTENSION vsql_my_extension;
SELECT * FROM INFORMATION_SCHEMA.EXTENSIONS WHERE EXTENSION_NAME = 'vsql_my_extension';
SELECT my_func('hello');
-- → HELLO
```

## See also

* [Building Extensions in Rust](https://villagesql.com/docs/en/extensions/build/rust-sdk.md) — full walkthrough with the ROT-13 example, packaging, and testing details
* [Custom Types in Rust](https://villagesql.com/docs/en/sdk/rust/custom-types.md) — define new column types with binary storage and ordering
* [Rust API Reference](https://villagesql.com/docs/en/sdk/rust/api-reference.md) — InValue, VdfReturn, and all macros
* [Writing C++ Extensions](https://villagesql.com/docs/en/guides/cpp-extensions.md) — the C++ path for the same task


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.