specta-rs/specta

Easily export your Rust types to other languages

Rust

643

1,018 commits

updated Oct 6, 2026

See the code

README

Specta Logo

Specta

Easily export your Rust types to other languages

Discord Crates.io crates.io docs.rs License

Features

  • Export structs and enums to multiple languages
  • Get function types to use in libraries like tauri-specta
  • Supports wide range of common crates in Rust ecosystem
  • Supports type inference - can determine type of fn demo() -> impl Type

Language Support

LanguageStatusExporterFeatures
TypeScript✅ Stablespecta-typescriptFull type support, generics, unions
Swift✅ Stablespecta-swiftIdiomatic Swift, custom Codable, Duration support
Rust🚧 Partialspecta-rustRust source, modules, generics; structural wire-only shapes error
OpenAPI🚧 Partialspecta-openapiOpenAPI 3.0 schemas, generics, JSON and YAML
Go🚧 Partialspecta-goStructs, generics, string enums, layouts, Serde
Kotlin🚧 Partialspecta-kotlinData/sealed classes, generics, optional Kotlinx
JSON Schema🚧 Partialspecta-jsonschemaDraft 7/2019-09/2020-12, generics, Serde
Zod🚧 Partialspecta-zodZod 4 schemas, inferred types, generics, layouts
Valibot🚧 Partialspecta-valibotValibot schemas, inferred types, generics, layouts
Python🚧 Partialspecta-pythonPython 3.13 TypedDicts and type hints
C#🚧 Partialspecta-csharpRecords, enums, generics, namespaces, file layouts
Java🚧 Partialspecta-javaJava 17 records, enums, and sealed interfaces

Legend

  • ✅ Stable: Production-ready with comprehensive test coverage
  • 🚧 Partial: Basic functionality implemented, complex types in progress

Implementation Status

The Specta ecosystem is actively developed with varying levels of completeness:

  • Production Ready (2): TypeScript and Swift exporters are fully functional with comprehensive test coverage
  • Partially Implemented (10): Rust, OpenAPI, Go, C#, Java, Kotlin, JSON Schema, Zod, Valibot, and Python have broad type support but are still stabilizing
  • Planned (0): All currently listed exporters have an initial implementation

For the most up-to-date status of each exporter, check the individual crate documentation and issue trackers.

Ecosystem

Specta can be used in your application either directly or through a library which simplifies the process of using it.

  • rspc - Easily building end-to-end typesafe APIs
  • tauri-specta - Typesafe Tauri commands and events
  • TauRPC - Tauri extension to give you a fully-typed IPC layer.

Usage

Add the specta crate along with any Specta language exporter crate:

# Core Specta library
cargo add specta

# Language exporters (choose one or more)
cargo add specta_typescript  # TypeScript (stable)
cargo add specta_swift       # Swift (stable)
cargo add specta_rust        # Rust (partial)
cargo add specta_openapi     # OpenAPI 3.0 schemas (JSON or YAML)
cargo add specta_java        # Java 17 (partial)
cargo add specta_go           # Go (partial)
cargo add specta-python      # Python 3.13 type hints (partial)
cargo add specta_kotlin       # Kotlin (partial)
cargo add specta_jsonschema   # JSON Schema (partial)
cargo add specta_zod          # Zod schemas (partial)
cargo add specta-valibot      # Valibot schemas (partial)
cargo add specta-csharp       # C# (partial)

Then you can use Specta like following:

TypeScript Example

use specta::{Type, Types};
use specta_typescript::Typescript;

#[derive(Type)]
pub struct TypeOne {
    pub a: String,
    pub b: GenericType<i32>,
    #[serde(rename = "cccccc")]
    pub c: MyEnum,
}

#[derive(Type)]
pub struct GenericType<A> {
    pub my_field: String,
    pub generic: A,
}

#[derive(Type)]
pub enum MyEnum {
    A,
    B,
    C,
}

fn main() {
    let types = Types::default()
        // You don't need to specify `GenericType` or `MyEnum` because they are referenced by `TypeOne`
        .register::<TypeOne>();

    Typescript::default()
        .export_to("./bindings.ts", &types)
        .unwrap();

    // if you need more control over file saving
    assert_eq!(
        Typescript::default().export(&types).unwrap(),
        r#"// This file has been generated by Specta. DO NOT EDIT.

export type GenericType<A> = { my_field: string; generic: A };

export type MyEnum = "A" | "B" | "C";

export type TypeOne = { a: string; b: GenericType<number>; cccccc: MyEnum };

"#
    );
}

Multi-Language Export Example

You can export the same types to multiple languages:

use specta::{Type, Types};
use specta_typescript::Typescript;
use specta_swift::Swift;

#[derive(Type)]
pub struct User {
    pub id: u32,
    pub name: String,
    pub email: Option<String>,
}

fn main() {
    let types = Types::default()
        .register::<User>();

    // Export to TypeScript (stable)
    Typescript::default()
        .export_to("./types.ts", &types)
        .unwrap();

    // Export to Swift (stable)
    Swift::default()
        .export_to("./Types.swift", &types)
        .unwrap();

    // Note: Other exporters are in development
}

A common use case is to export all types for which specta::Type is derived into a single file:

//! NOTE: This example requires the `export` feature on the `specta` crate
use specta::Type;
use specta_typescript::Typescript;

#[derive(Type)]
pub enum MyEither<L, R> {
    Left(L),
    Right(R),
}

#[derive(Type)]
pub struct GenericType<A> {
    pub my_field: String,
    pub generic: A,
}

#[derive(Type)]
pub enum MyEnum {
    A,
    B,
    C,
}

#[derive(Type)]
#[specta(collect = false)]
pub struct DontExportMe {
    field: String,
}

fn main() {
    Typescript::default()
        .export_to("./bindings.ts", &specta::export())
        .unwrap();
}

Check out the docs for more information.

Motivation

This library was originally created to power the type exporting functionality of rspc, but after building it we realized that it could be useful for other projects as well so we decided to move it into a dedicated library.

A huge thanks to Brendonovich for doing a heap of early development on this library.

reflection
rspc
rust
rust-macro
specta
tauri-specta
typesafe
typescript

specta-rs/specta

Easily export your Rust types to other languages

Rust

643

1,018 commits

updated Oct 6, 2026

See the code

README

Specta Logo

Specta

Easily export your Rust types to other languages

Discord Crates.io crates.io docs.rs License

Features

  • Export structs and enums to multiple languages
  • Get function types to use in libraries like tauri-specta
  • Supports wide range of common crates in Rust ecosystem
  • Supports type inference - can determine type of fn demo() -> impl Type

Language Support

LanguageStatusExporterFeatures
TypeScript✅ Stablespecta-typescriptFull type support, generics, unions
Swift✅ Stablespecta-swiftIdiomatic Swift, custom Codable, Duration support
Rust🚧 Partialspecta-rustRust source, modules, generics; structural wire-only shapes error
OpenAPI🚧 Partialspecta-openapiOpenAPI 3.0 schemas, generics, JSON and YAML
Go🚧 Partialspecta-goStructs, generics, string enums, layouts, Serde
Kotlin🚧 Partialspecta-kotlinData/sealed classes, generics, optional Kotlinx
JSON Schema🚧 Partialspecta-jsonschemaDraft 7/2019-09/2020-12, generics, Serde
Zod🚧 Partialspecta-zodZod 4 schemas, inferred types, generics, layouts
Valibot🚧 Partialspecta-valibotValibot schemas, inferred types, generics, layouts
Python🚧 Partialspecta-pythonPython 3.13 TypedDicts and type hints
C#🚧 Partialspecta-csharpRecords, enums, generics, namespaces, file layouts
Java🚧 Partialspecta-javaJava 17 records, enums, and sealed interfaces

Legend

  • ✅ Stable: Production-ready with comprehensive test coverage
  • 🚧 Partial: Basic functionality implemented, complex types in progress

Implementation Status

The Specta ecosystem is actively developed with varying levels of completeness:

  • Production Ready (2): TypeScript and Swift exporters are fully functional with comprehensive test coverage
  • Partially Implemented (10): Rust, OpenAPI, Go, C#, Java, Kotlin, JSON Schema, Zod, Valibot, and Python have broad type support but are still stabilizing
  • Planned (0): All currently listed exporters have an initial implementation

For the most up-to-date status of each exporter, check the individual crate documentation and issue trackers.

Ecosystem

Specta can be used in your application either directly or through a library which simplifies the process of using it.

  • rspc - Easily building end-to-end typesafe APIs
  • tauri-specta - Typesafe Tauri commands and events
  • TauRPC - Tauri extension to give you a fully-typed IPC layer.

Usage

Add the specta crate along with any Specta language exporter crate:

# Core Specta library
cargo add specta

# Language exporters (choose one or more)
cargo add specta_typescript  # TypeScript (stable)
cargo add specta_swift       # Swift (stable)
cargo add specta_rust        # Rust (partial)
cargo add specta_openapi     # OpenAPI 3.0 schemas (JSON or YAML)
cargo add specta_java        # Java 17 (partial)
cargo add specta_go           # Go (partial)
cargo add specta-python      # Python 3.13 type hints (partial)
cargo add specta_kotlin       # Kotlin (partial)
cargo add specta_jsonschema   # JSON Schema (partial)
cargo add specta_zod          # Zod schemas (partial)
cargo add specta-valibot      # Valibot schemas (partial)
cargo add specta-csharp       # C# (partial)

Then you can use Specta like following:

TypeScript Example

use specta::{Type, Types};
use specta_typescript::Typescript;

#[derive(Type)]
pub struct TypeOne {
    pub a: String,
    pub b: GenericType<i32>,
    #[serde(rename = "cccccc")]
    pub c: MyEnum,
}

#[derive(Type)]
pub struct GenericType<A> {
    pub my_field: String,
    pub generic: A,
}

#[derive(Type)]
pub enum MyEnum {
    A,
    B,
    C,
}

fn main() {
    let types = Types::default()
        // You don't need to specify `GenericType` or `MyEnum` because they are referenced by `TypeOne`
        .register::<TypeOne>();

    Typescript::default()
        .export_to("./bindings.ts", &types)
        .unwrap();

    // if you need more control over file saving
    assert_eq!(
        Typescript::default().export(&types).unwrap(),
        r#"// This file has been generated by Specta. DO NOT EDIT.

export type GenericType<A> = { my_field: string; generic: A };

export type MyEnum = "A" | "B" | "C";

export type TypeOne = { a: string; b: GenericType<number>; cccccc: MyEnum };

"#
    );
}

Multi-Language Export Example

You can export the same types to multiple languages:

use specta::{Type, Types};
use specta_typescript::Typescript;
use specta_swift::Swift;

#[derive(Type)]
pub struct User {
    pub id: u32,
    pub name: String,
    pub email: Option<String>,
}

fn main() {
    let types = Types::default()
        .register::<User>();

    // Export to TypeScript (stable)
    Typescript::default()
        .export_to("./types.ts", &types)
        .unwrap();

    // Export to Swift (stable)
    Swift::default()
        .export_to("./Types.swift", &types)
        .unwrap();

    // Note: Other exporters are in development
}

A common use case is to export all types for which specta::Type is derived into a single file:

//! NOTE: This example requires the `export` feature on the `specta` crate
use specta::Type;
use specta_typescript::Typescript;

#[derive(Type)]
pub enum MyEither<L, R> {
    Left(L),
    Right(R),
}

#[derive(Type)]
pub struct GenericType<A> {
    pub my_field: String,
    pub generic: A,
}

#[derive(Type)]
pub enum MyEnum {
    A,
    B,
    C,
}

#[derive(Type)]
#[specta(collect = false)]
pub struct DontExportMe {
    field: String,
}

fn main() {
    Typescript::default()
        .export_to("./bindings.ts", &specta::export())
        .unwrap();
}

Check out the docs for more information.

Motivation

This library was originally created to power the type exporting functionality of rspc, but after building it we realized that it could be useful for other projects as well so we decided to move it into a dedicated library.

A huge thanks to Brendonovich for doing a heap of early development on this library.

reflection
rspc
rust
rust-macro
specta
tauri-specta
typesafe
typescript

Project health

crates.io

Latest release

1.0.5 · Jul 17, 2023

Releases this year

0

Significant stargazers

Caleb Maclennan

486 followers · starred Oct 2024

Koichi Shiraishi

795 followers · starred Sep 2026

Trevor Manz

325 followers · starred Aug 2026

Xuan Zhang

624 followers · starred Sep 2025