# tauri-specta: generating TypeScript types for your Tauri commands

> Tauri Specta is a MIT licensed Rust library that derives TypeScript types for Tauri commands, and for the events they emit, so that the boundary between a Rust backend and a TypeScript front end stops being an unchecked JSON contract. The judgement is that the type generation is the whole point and works well, and that the version matrix is the part to read first, because the v2 line is still a release candidate and the supported combinations are narrow.

**specta-rs/tauri-specta** — Completely typesafe Tauri commands

- Repository: https://github.com/specta-rs/tauri-specta
- Stars: 811 · Forks: 74
- Language: Rust
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/specta-rs-tauri-specta

## The JSON boundary is where types get lost

Tauri Specta describes itself in one line, as completely typesafe Tauri commands, and the problem it solves follows from how a Tauri application is put together. The front end calls a command by name with arguments that are serialised, and the back end returns a value that is deserialised. Both sides are ordinary Rust and TypeScript, and neither compiler can see the other, so the contract between them is a convention that nothing enforces. A renamed field or a changed argument type is a runtime error rather than a compile error, and the type errors surface in whichever direction the data happens to travel. Specta is the type derivation library that this project builds on, and the repository keywords name both, along with rspc for the RPC layer and typesafe for the promise. The value of the arrangement is that the TypeScript definitions are generated from the Rust definitions, so the two cannot drift apart.

## The version matrix is narrow and the README says so

The first thing to read is the note at the top of the README, which says that this branch contains tauri-specta v2, and that the previous version is available at the git tag v1.0.2. Below it sits a compatibility table with four cells, and only two of them are supported. Tauri v1 with Specta v1 is supported, and Tauri v2 with Specta v2 is supported, while Tauri v1 with Specta v2 and Tauri v2 with Specta v1 are both marked unsupported. That is an unusually honest matrix, since it explicitly tells you that you cannot move the Specta major version without moving the Tauri major version, and it means the choice of Tauri version effectively determines which line of this library you use. The documentation links are given per cell, so the route to the API docs and the getting started guide differs depending on which combination you land on. Tauri Specta v2 also comes with support for generating types for events, which extends the same treatment to the messages a backend pushes to the front end.

## Events are part of the same contract

Most Tauri applications have two kinds of traffic between the two sides. There are the commands, where the front end asks and the back end answers, and there are the events, where the back end pushes. Handling only the first leaves the second half of the interface untyped, and event payloads are where the naming drift tends to hurt, because a front end that listens for a payload field the back end renamed gets undefined rather than a compiler error. Tauri Specta v2 adds type generation for events on top of the command support, which means both directions are covered by generated definitions. The README does not go into detail on how that is configured, and points at the documentation links for the getting started instructions, so the practical route is to follow the v2 documentation rather than to infer the setup from the readme.

## Feature flags decide which pieces you pull in

The manifest makes the optional surface explicit. The default feature list is empty, so an installation that does not ask for anything gets the core. The derive feature pulls in the tauri-specta-macros crate, and the javascript and typescript features pull in specta-typescript, which is the piece that emits the TypeScript. The base dependencies are small and mostly workspace inherited. The crate depends on specta with the function feature, on tauri with its specta feature, on specta-serde and specta-util, and on serde, serde_json and thiserror, with heck in the private section, which is the case conversion library used to turn Rust identifiers into names a JavaScript developer recognises. The macros crate is pinned to the exact version of the main crate, so the derive macro and the runtime cannot drift apart, and the type generation is behind a feature because a build that never emits TypeScript should not pay for it.

## Lint policy and docs.rs configuration

The workspace lint table deserves a read, because it states the project's rules rather than implying them. Unsafe code is forbidden at the workspace level, missing documentation is a warning, and the clippy configuration enables the all, cargo and other groups at warning level. The manifest also carries the metadata for docs.rs, with all-features enabled and the rustc and rustdoc arguments that set the docsrs cfg flag, and a comment above it records the command used to build the documentation, cargo +nightly doc with all-features and a rustdoc flag. That combination of a forbidden unsafe block, a documentation requirement and a dedicated docs.rs configuration is what you would expect from a library that generates code, since the generated output is only as good as the discipline around the macros that produce it.

## Running the sample app and the tests

The Development section has two parts, one for the working application and one for the suite. The example is a JavaScript and Rust workspace driven by pnpm:

```bash
pnpm i
cd examples/app/
pnpm tauri dev
```

The repository holds three runnable applications, an app, a custom-plugin project and a tanstack-query project, and the workspace members list shows that each has its own src-tauri crate, with a separate plugin crate for the custom plugin example, alongside a crates/tauri-specta-query member and the macros directory. The test suite is a single Cargo invocation:

```bash
cargo test --all --all-features
```

Running everything with all features is the right habit here, since the feature flags decide which code paths exist at all, and a default-features test run would not touch the TypeScript generation or the derive macro at all.

## A release candidate line, and where the stable option is

The licence is MIT, with the licence file referenced from the manifest and the README linking it, and the crate is published on crates.io as tauri-specta with API documentation on docs.rs. The version in the manifest is 2.0.0-rc.25, and the release history shows the same pattern, with v2.0.0-rc.21 from January 2025, v2.0.0-rc.24 under the title Phasing Forward in March 2026, and v2.0.0-rc.25 in May 2026. That is the fact to plan around. The v2 line is a release candidate line, so anyone adopting it today is depending on a version that is still labelled as a candidate, and the documentation links in the compatibility table point at a specific release candidate, 2.0.0-rc.21, rather than at a final version. The stable option remains the v1 line at the v1.0.2 tag, which supports Tauri v1. The last push was on 2026-10-15 and the repository is not archived, so the work continues, and the project is credited to Oscar Beaumont and Brendonovich.

## Conclusion

tauri-specta fits a team building a Tauri application with a TypeScript front end, since it turns the command signatures into a generated type layer that both sides compile against, and it fits teams that already use Specta elsewhere and want the Tauri binding to speak the same dialect. It is the wrong choice if you are on Tauri v1 and intend to stay there, because the v2 line does not support it, and it is a poor fit for a project that needs a stable release, since the current v2 line is still at a release candidate and the published documentation points at a specific release candidate version. Before you adopt it, confirm the Tauri and Specta version pair from the compatibility table, decide whether you want the derive macro, the TypeScript output or both, and pin the exact release candidate you build against.

## FAQ

### Which Tauri and Specta version combinations does tauri-specta v2 support?

Only Tauri v2 with Specta v2, and Tauri v1 with Specta v1. The README's compatibility table marks Tauri v1 with Specta v2 and Tauri v2 with Specta v1 as unsupported, and the previous line of the library is kept at the v1.0.2 git tag.

### What do the tauri-specta feature flags control?

The default feature list is empty. The derive feature pulls in the tauri-specta-macros crate, and the javascript and typescript features pull in specta-typescript, which produces the TypeScript output. The crate always depends on specta with its function feature and on tauri with its specta feature.

### How do I run the tauri-specta example application and its tests?

For the example, run pnpm i, change into examples/app/ and run pnpm tauri dev. For the test suite, run cargo test --all --all-features, and using all features matters because the feature flags decide which code paths are compiled at all.

## Sources

- [Issues](https://github.com/specta-rs/tauri-specta/issues)
- [License: MIT](https://github.com/specta-rs/tauri-specta/blob/main/LICENSE)
- [README](https://github.com/specta-rs/tauri-specta/blob/main/README.md)
- [Releases](https://github.com/specta-rs/tauri-specta/releases)
- [specta-rs/tauri-specta on GitHub](https://github.com/specta-rs/tauri-specta)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/specta-rs-tauri-specta
