Skip to content

ImJeremyHe/gents

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

32 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gents

MIT/Apache 2.0

gents is a tool for generating Typescript interfaces from Rust code.

It bridges the gap between Rust backends and TypeScript frontends by automatically generating type definitions, making it easy to use serde-json for communication between the two languages without manually maintaining duplicate type stubs.

Why use gents?


  • Automatic type synchronization: When your Rust data models change, you can instantly regenerate matching TypeScript interfaces, ensuring your frontend and backend always stay in sync.
  • Eliminate manual boilerplate: No need to hand-write or update TypeScript types every time your Rust structs or enums change, reducing human error and saving time.
  • Ideal for rapid iteration: If your API or data structures evolve frequently, gents lets you iterate quickly without worrying about type mismatches.
  • Great for fullstack Rust+TS/JS projects: Whether you’re building a RESTful API, a WebAssembly app, or any project where Rust and TypeScript need to share data structures, gents makes cross-language type safety effortless.

Typical scenarios where gents shines:

  • Building a web server in Rust with a TypeScript (React/Vue/Svelte) frontend, and you want to keep your types always correct and up-to-date.
  • Developing a WASM project where Rust and TypeScript interact closely.
  • Working in a team where backend and frontend developers need a single source of truth for data models.

This tool is designed for LogiSheets and is inspired by ts-rs. Many thanks to them!

Your issues and PRs are welcome!


🛠️ How to Use gents (Quickstart & Advanced)

1. Add Dependencies

In your Cargo.toml:

[dev-dependencies]
gents = "1.0"
gents_derives = "1.0"

2. Annotate Your Types

Use gents_derives::TS and specify the output file:

use gents_derives::TS;

#[derive(TS)]
#[ts(file_name = "person.ts", rename_all = "camelCase")]
pub struct Person {
    pub age: u16,
    pub en_name: String,
}

#[derive(TS)]
#[ts(file_name = "group.ts", rename_all = "camelCase")]
pub struct Group {
    pub name: String,
    pub capacity: u16,
    pub members: Vec<Person>,
    pub leader: Option<Person>,
}

You can use rename_all and rename for field naming policies.

3. Generate TypeScript Files

Write a binary or unit test:

#[ignore]
#[test]
fn gents() {
    use gents::FileGroup;
    let mut group = FileGroup::new();
    // Add your root types; dependencies will be included automatically
    group.add::<Group>();
    // The second argument controls whether to generate index.ts
    group.gen_files("outdir", false);
}

Since Group has dependencies on Person, gents will automatically include Person in the generated files.

  • Run with cargo test -- --ignored to generate files.

4. Output Directory

  • All generated .ts files will be placed in the directory you specify (e.g., outdir).
  • If you set the second argument of gen_files to true, an index.ts exporting all types will be generated.

5. Integration with Frontend

  • Add the generated .ts files to your frontend project (or link via a monorepo).
  • Now your TypeScript code can safely import and use the types generated from Rust, ensuring type consistency.

💡 Advanced Tips

  • Dependencies auto-detection: When you add a type to FileGroup, all of its dependencies (other structs/enums it uses) are automatically included.
  • Customizing output: You can control file names, field naming, and more via attributes.
  • Use in CI: You can run the generation test in your CI pipeline to ensure TypeScript types are always up to date.

Why not ts-rs?

  • ts-rs generates the files when running cargo test and in this way we must commit those generated files into our repo. It is not necessary and is even an obstacle when we use other build tools like bazel. gents acts as a binary to generate Typescript files.

  • gents introduces a concept Group that from all the members in this group files generated will be placed in the same directory. Group is seperate from the other group even though they can share some dependecies. Therefore, gents requires you to specify the file_name on structs or enums and to specify the dir on group, while ts-rs requires specifing the path on every item.

  • gents helps you manage the export files. And it gathers all the dependencies automatically.

  • gents is well support for referencing other crates.

  • Code generated by ts-rs is not match our coding style.

About

A tool for generating Typescript interfaces in your Rust code

Topics

Resources

Stars

Watchers

Forks