schema-bridge 0.1.0

Generate TypeScript type definitions from Rust types - perfect for Tauri applications
Documentation

schema-bridge

A minimal, practical Rust library for generating TypeScript type definitions from Rust types.

Features

  • Simple to use: Just derive SchemaBridge on your types
  • Serde compatible: Works with serde attributes
  • Minimal dependencies: No heavy tooling required
  • Workspace friendly: Organized as a clean workspace

Quick Start

Add to your Cargo.toml:

[dependencies]
schema-bridge = { path = "path/to/schema-bridge/crates/schema-bridge" }
serde = { version = "1.0", features = ["derive"] }

Define your types and export them:

use schema_bridge::{SchemaBridge, export_types};
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize, SchemaBridge)]
struct User {
    name: String,
    age: i32,
    email: Option<String>,
}

#[derive(Serialize, Deserialize, SchemaBridge)]
enum Status {
    Active,
    Inactive,
}

fn main() {
    // Easy export with the macro!
    export_types!("bindings.ts", User, Status).unwrap();
}

This generates bindings.ts:

// This file is auto-generated by schema-bridge

export type User = { name: string; age: number; email: string | null; };

export type Status = 'Active' | 'Inactive';

Architecture

The library is structured as a workspace with three crates:

  • schema-bridge: Main entry point (facade)
  • schema-bridge-core: Core traits and types
  • schema-bridge-macro: Procedural macro for #[derive(SchemaBridge)]

This follows the pattern used by popular libraries like serde.

Supported Types

  • Primitives: String, i32, f64, bool, etc.
  • Containers: Vec<T>, Option<T>
  • Structs with named fields
  • Enums (simple variants)
  • Newtype pattern: struct Wrapper(InnerType) - delegates to wrapped type
  • Tuple structs: struct Point(f64, f64) - generates TypeScript tuples

Newtype Pattern for External Types

Perfect for wrapping external types you don't control:

// Wrap an external enum
#[derive(Serialize, Deserialize, SchemaBridge)]
struct MyStatus(external_crate::Status);

// Wrap a primitive for type safety
#[derive(Serialize, Deserialize, SchemaBridge)]
struct UserId(String);  // Generates: export type UserId = string;

Use with Tauri

Perfect for Tauri applications where you need to keep Rust and TypeScript types in sync:

// In build.rs or a separate build tool
use schema_bridge::export_types;

fn main() {
    // Simple one-liner to export all your types!
    export_types!("../src/bindings.ts", AppConfig, UserData, TalkStyle).unwrap();
}

Or for more control:

use schema_bridge::{SchemaBridge, generate_ts_file};

fn main() {
    let types = vec![
        ("AppConfig", AppConfig::to_ts()),
        ("UserData", UserData::to_ts()),
    ];
    
    let ts_content = generate_ts_file(types);
    std::fs::write("../src/bindings.ts", ts_content)?;
}

License

MIT OR Apache-2.0