Expand description
Tauri Specta will generate a Typescript or JSDoc file (powered by Specta) to provide a typesafe interface to your Tauri backend.
§Installation
Tauri Specta v2 is still in beta, and requires using Tauri v2 and Specta v2 lands as stable.
It is really important you use = in your versions to ensure your project will not break after future updates!
To get started run the following commands to add the required dependencies to your Cargo.toml:
# Always required
cargo add tauri@2.0 specta@=2.0.0-rc.21
# Typescript
cargo add specta-typescript@0.0.9
cargo add tauri-specta@=2.0.0-rc.21 --features derive,typescript
# JSDoc
cargo add specta-jsdoc@0.0.9
cargo add tauri-specta@=2.0.0-rc.21 --features derive,javascript§Features
There are the following optional features which can be enabled:
derive- Enables theEventderive macro. This is only required if your using events.javascript- Enables the JSDoc exporter.typescript- Enables the Typescript exporter.
§Setup
The follow is a minimal example of how to setup Tauri Specta with Typescript.
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
use serde::{Deserialize, Serialize};
use specta_typescript::Typescript;
use tauri_specta::{collect_commands, Builder};
#[tauri::command]
#[specta::specta] // < You must annotate your commands
fn hello_world(my_name: String) -> String {
format!("Hello, {my_name}! You've been greeted from Rust!")
}
fn main() {
let mut builder = Builder::<tauri::Wry>::new()
// Then register them (separated by a comma)
.commands(collect_commands![hello_world,]);
#[cfg(debug_assertions)] // <- Only export on non-release builds
builder
.export(Typescript::default(), "../src/bindings.ts")
.expect("Failed to export typescript bindings");
tauri::Builder::default()
// and finally tell Tauri how to invoke them
.invoke_handler(builder.invoke_handler())
.setup(move |app| {
// This is also required if you want to use events
builder.mount_events(app);
Ok(())
})
// on an actual app, remove the string argument
.run(tauri::generate_context!("tests/tauri.conf.json"))
.expect("error while running tauri application");
}§Export to JSDoc
If your interested in using JSDoc instead of Typescript you can replace the specta_typescript::Typescript struct
with specta_jsdoc::JSDoc like the following:
let mut builder = tauri_specta::Builder::<tauri::Wry>::new();
#[cfg(debug_assertions)]
builder
.export(specta_jsdoc::JSDoc::default(), "../src/bindings.js")
.expect("Failed to export typescript bindings");§Usage on frontend
import { commands, events } from "./bindings"; // This should point to the file we export from Rust
console.log(await commands.greet("Brendan"));§Custom types
Similar to serde::Serialize you must put the specta::Type derive macro on your own types to allow Specta to understand your types. For example:
use serde::{Serialize, Deserialize};
use specta::Type;
#[derive(Serialize, Deserialize, Type)]
pub struct MyStruct {
a: String
}
// Call `typ()` as much as you want.
let mut builder = tauri_specta::Builder::<tauri::Wry>::new().typ::<MyStruct>();§Events
You can also make events typesafe by following the following example:
use serde::{Serialize, Deserialize};
use specta::Type;
use tauri_specta::{Builder, collect_commands, collect_events, Event};
// Add `tauri_specta::Event` to your event
#[derive(Serialize, Deserialize, Debug, Clone, Type, Event)]
pub struct DemoEvent(String);
let mut builder = Builder::<tauri::Wry>::new()
// and then register it to your builder
.events(collect_events![DemoEvent]);
tauri::Builder::default()
.invoke_handler(builder.invoke_handler())
.setup(move |app| {
// Ensure you mount your events!
builder.mount_events(app);
// Now you can use them
DemoEvent::listen(app, |event| {
println!("{:?}", event.payload);
});
DemoEvent("Test".into()).emit(app).unwrap();
Ok(())
});and it can be used on the frontend like the following:
import { commands, events } from "./bindings";
import { appWindow } from "@tauri-apps/api/window";
// For all windows
events.demoEvent.listen((e) => console.log(e));
// For a single window
events.demoEvent(appWindow).listen((e) => console.log(e));
// Emit to the backend and all windows
await events.demoEvent.emit("Test")
// Emit to a window
await events.demoEvent(appWindow).emit("Test")Refer to Event for all the possible methods for listening and emitting events.
§Channel
Macros§
- Collect commands and their types.
- Collect events and their types.
Structs§
- Builder for configuring Tauri Specta in your application.
- A wrapper around the output of the
collect_commandsmacro. - A wrapper around the output of the
collect_commandsmacro. - The context of what needs to be exported. Used when implementing
LanguageExt. - A typed event that was emitted.
Enums§
- The mode which the error handling is done in the bindings.
Traits§
- Extends your event type with typesafe methods for listening to and emitting events.
- Implemented for all languages which Tauri Specta supports exporting to.