Skip to content

specta-rs/specta

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ab7d924 · Apr 28, 2025
Feb 13, 2025
Feb 16, 2025
Apr 28, 2025
Apr 15, 2025
Apr 28, 2025
Apr 20, 2025
Apr 20, 2025
Apr 28, 2025
Apr 15, 2025
Apr 28, 2025
Apr 15, 2025
Apr 22, 2025
Apr 28, 2025
Apr 28, 2025
Feb 15, 2023
Jun 28, 2024
Sep 21, 2023
Apr 15, 2025
Jan 2, 2023
Apr 28, 2025
Aug 1, 2024

Repository files navigation

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 Typescript
  • 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.

Support

Development of this project is supported by my GitHub Sponsors and also CrabNebula, a huge thanks to them!

CrabNebula Logo

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, for example specta-typescript.

cargo add specta
cargo add specta_typescript

Then you can use Specta like following:

use specta::{Type, TypeCollection};
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 = TypeCollection::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 };

"#
    );
}

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(export = 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.