| Crates.io | schema-bridge |
| lib.rs | schema-bridge |
| version | 0.3.0 |
| created_at | 2025-11-21 14:03:46.089657+00 |
| updated_at | 2025-11-24 00:46:02.139441+00 |
| description | Generate TypeScript type definitions from Rust types - perfect for Tauri applications |
| homepage | |
| repository | https://github.com/ynishi/tauri-schema |
| max_upload_size | |
| id | 1943604 |
| size | 19,595 |
A minimal, practical Rust library for generating TypeScript type definitions from Rust types.
SchemaBridge on your typesAdd 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';
The library is structured as a workspace with three crates:
#[derive(SchemaBridge)]This follows the pattern used by popular libraries like serde.
String, i32, f64, bool, etc.Vec<T>, Option<T>struct Wrapper(InnerType) - delegates to wrapped typestruct Point(f64, f64) - generates TypeScript tuples#[serde(rename_all = "...")] for name transformationsThe library respects #[serde(rename_all)] attributes on enums:
#[derive(Serialize, Deserialize, SchemaBridge)]
#[serde(rename_all = "snake_case")]
enum ConversationMode {
Normal, // → 'normal'
Concise, // → 'concise'
Creative, // → 'creative'
}
Supported transformations:
snake_case: MyVariant → my_variantcamelCase: MyVariant → myVariantPascalCase: MyVariant → MyVariant (no change)SCREAMING_SNAKE_CASE: MyVariant → MY_VARIANTkebab-case: MyVariant → my-variantGenerate Display and FromStr implementations for easy string conversion:
#[derive(SchemaBridge)]
#[schema_bridge(string_conversion)] // Enable Display + FromStr
#[serde(rename_all = "snake_case")]
enum TalkStyle {
Brainstorm,
Casual,
}
// Usage:
let style = TalkStyle::Brainstorm;
let s = style.to_string(); // "brainstorm"
let parsed: TalkStyle = "casual".parse().unwrap(); // TalkStyle::Casual
Perfect for:
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;
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)?;
}
MIT OR Apache-2.0