Specta
Export your Rust types to any language
Specta exports Rust types to other languages. Derive Type on your structs and enums, collect the types you want to share, then pass them to an exporter.
Specta generates type definitions. It does not serialize values or send requests. Use Serde for serialization and a framework integration for typed API calls.
Getting started
Install
These guides use Specta v2. Pin the release candidate so a dependency update does not change the API.
cargo add specta@=2.0.0-rc.27 --features derive
cargo add specta-serde@0.0.14 specta-typescript@0.0.14Export your first type
use specta::{Type, Types};
use specta_typescript::Typescript;
#[derive(Type)]
pub struct User {
pub id: u32,
pub name: String,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let types = Types::default().register::<User>();
Typescript::default().export_to(
"./bindings.ts",
&types,
specta_serde::Format,
)?;
Ok(())
}Run cargo run to write bindings.ts:
export type User = { id: number; name: string };Register the types your application exposes. Specta also collects their referenced types, so you do not need to list every nested type.
For data sent through Serde, derive Serialize or Deserialize as needed. specta_serde::Format applies Serde attributes to the exported shape. See Core for details.
When to export
The exporter runs as Rust code. Choose a place where you can call it and handle errors:
- A test: export with
cargo test. This keeps generation separate from application startup. - A small binary or example: run generation as an explicit development or CI step.
- Application startup: export in debug builds with
#[cfg(debug_assertions)]. This works well for desktop applications. - A build script: use this only when the types are available to the build script, for example from a separate crate.
build.rscannot import the application crate it is about to compile.
Generate bindings before checking or building the frontend. If you commit generated files, regenerate them in CI and check for a diff. Do not edit generated bindings by hand.
Next steps
- Language exporters: TypeScript, JavaScript, Swift, and other targets.
- Core: type registration, Serde attributes, and type overrides.
- Frameworks: typed commands and APIs.
Last updated on
