Build lightweight, blazing-fast desktop apps with Tauri + Bun
Features • How It Works • Installation • Usage • FAQ
Tauribun is a Tauri plugin and template for building Tauri desktop applications with Bun running as a sidecar. If you love how light and fast Tauri is, but prefer writing backend logic in TypeScript instead of Rust, this is for you.
Tauribun connects your frontend to your Bun backend via oRPC over stdio, giving you full-stack TypeScript with native performance.
🤩 Want to see it in action? Check out the example app for a complete working implementation with React, TanStack Query, and shadcn/ui.
- 🚀 Native performance — Bun compiles to a single executable
- 📦 Tiny bundle size — Tauri's minimal footprint + Bun's efficient runtime
- 🔒 Type safety — End-to-end TypeScript with oRPC
- 🎨 Full-stack TypeScript — No context switching between languages
- ⚡ Fast startup — ~10ms sidecar startup time
- 🔌 Simple integration — Tauri plugin handles sidecar lifecycle
┌─────────────────────────────────────────────────────────────┐
│ Tauri Application │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────────────┐ ┌─────────────────────────┐ │
│ │ React Frontend │◄───►│ Bun Sidecar Binary │ │
│ │ (Webview) │ │ (TypeScript backend) │ │
│ │ │ │ │ │
│ │ • React UI │ │ • oRPC Router │ │
│ │ • TanStack Query │ │ • Business Logic │ │
│ │ • shadcn/ui │ │ • File System Access │ │
│ │ │ │ • Native APIs │ │
│ └─────────────────────┘ └─────────────────────────┘ │
│ │ │ │
│ └───────── stdio ───────────┘ │
│ (oRPC messages) │
└─────────────────────────────────────────────────────────────┘
The communication flow:
- Frontend uses TanStack Query to call oRPC procedures
- oRPC serializes the call and sends it via Tauri's shell plugin to the sidecar's stdin
- Bun sidecar processes the request and writes the response to stdout
- Frontend receives the response and updates the UI
This architecture keeps your Rust code minimal (just the Tauri plugin) while allowing you to write all your business logic in TypeScript.
- Bun (v1.3.6 or later)
- Rust (v1.77.2 or later)
- Tauri prerequisites
Install the plugin:
# Add the Rust plugin to your Tauri app
cargo add tauri-plugin-tauribun
# Add the TypeScript package
bun add tauri-plugin-tauribunRegister the plugin in your Tauri app (src-tauri/src/lib.rs):
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_tauribun::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}Include the plugin capabilities in your Tauri config (src-tauri/capabilities/default.json):
{
"permissions": [
"tauribun:default"
]
}Compile your Bun backend to an executable binary and add it to your Tauri config (src-tauri/tauri.conf.json):
{
"build": {
"additionalWatchFolders": ["binaries"],
"beforeDevCommand": "bun build --compile --watch ./src-bun/main.ts",
"beforeBuildCommand": "bun build --compile ./src-bun/main.ts",
"frontendDist": "../dist",
"devUrl": "http://localhost:3000"
},
"bundle": {
"externalBin": ["binaries/bun-server"]
}
}You can also extract the build command to a script (see examples/tauribun/scripts/build.ts).
Create your oRPC server in your Bun backend (src-bun/main.ts):
import { createServer } from "tauri-plugin-tauribun";
import { router } from "./router";
createServer("bun-server", router);Create your oRPC router in your Bun backend (src-bun/router.ts):
import { os } from "@orpc/server";
import * as z from "zod";
export const router = {
greet: os
.route({
method: "POST",
path: "/greet",
summary: "Greet the user",
})
.input(z.object({ name: z.string() }))
.output(z.object({ greeting: z.string() }))
.handler(async ({ input }) => {
return { greeting: `Hello, ${input.name}!` };
}),
// Add more procedures here
getSystemInfo: os
.route({
method: "GET",
path: "/system-info",
})
.output(z.object({
platform: z.string(),
arch: z.string(),
}))
.handler(async () => {
return {
platform: process.platform,
arch: process.arch,
};
}),
};
export type Router = typeof router;Use TanStack Query (or call directly with the oRPC client) for type-safe calls:
import { useMutation, useQuery } from "@tanstack/react-query";
import { createClient } from "tauri-plugin-tauribun";
import type { Router } from "src-bun/router.ts";
// Create a typed client that spawns and connects to the Bun server
// Replace "bun-server" with the name of the binary you added to tauri.conf.json
const client = createClient<Router>("bun-server");
// You can call the oRPC client directly:
const response = await client.orpc.greet({ name: "World" });
console.log(response.greeting); // "Hello, World!"
// And you can use TanStack Query with the oRPC client:
const orpc = createTanstackQueryUtils(client.orpc);
function App() {
// Query example
const { data: systemInfo } = useQuery(
orpc.getSystemInfo.queryOptions()
);
// Mutation example
const { mutate: greet } = useMutation(
orpc.greet.mutationOptions({
onSuccess: (data) => console.log(data.greeting),
})
);
return (
<div>
<p>Platform: {systemInfo?.platform}</p>
<button onClick={() => greet({ name: "World" })}>
Say Hello
</button>
</div>
);
}See the examples for more complete working implementations.
Bun can compile TypeScript directly to a single executable binary. This means:
- No Node.js runtime needed on the user's machine
- Fast startup time (~10ms)
- Small binary size (~50MB)
- Full access to Bun's APIs (file system, SQLite, HTTP, etc.)
Tauri's sidecar communication is limited to stdio. Tauribun uses orpc-adapter-stdio to adapt messages for oRPC, providing end-to-end type safety between your frontend and backend.
Anything you can do in Node.js/Bun:
- File system operations
- SQLite database (Bun has built-in SQLite)
- HTTP requests to external APIs
- Spawn child processes
- Access environment variables
- And more...
We welcome contributions! Please see our Contributing Guide for details on:
- Setting up the development environment
- Understanding the project structure
- Running tests and linting
- Submitting pull requests
This project is open source and available under the MIT License.
Created by ShipWorthy ⛵️
