Rust is a systems programming language known for safety and performance, while Tauri is a lightweight framework that enables the creation of cross-platform desktop applications. In this post, we'll explore how to create a simple desktop app using Rust and Tauri, with detailed code examples to help you get started.
Why Rust and Tauri?
- Performance: Rust offers memory safety and concurrency without a garbage collector, making it ideal for high-performance applications.
- Small Binary Size: Tauri produces smaller and faster binaries compared to frameworks like Electron.
- Security: Tauri emphasizes security with its permission management system and content security policies.
- Cross-Platform: One codebase runs on Windows, macOS, and Linux.
Setting Up Your Environment
To begin, you’ll need to have Rust and the Tauri CLI installed. Follow the steps below to set up your environment.
1. Install Rust
If you don’t have Rust installed, get it by running the following command:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
2. Install Node.js (for Frontend Development)
Most Tauri applications use a frontend framework like Vue.js, React, or Svelte. Ensure you have Node.js installed:
curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash - && sudo apt-get install -y nodejs
3. Install Tauri CLI
The Tauri CLI provides tools to create, build, and manage your Tauri project.
cargo install tauri-cli
Creating a New Tauri Project
To create a new Tauri project, use the `cargo tauri init` command. This command sets up the basic file structure of your Tauri project, with a Rust backend and a frontend built using your preferred web framework.
1. Initialize a Tauri Project
cargo tauri init
The tauri init
command prompts you to choose a frontend framework (like Vue, React, or Svelte). For simplicity, we'll use vanilla HTML and JavaScript in this example, but you can easily adapt this to a more sophisticated frontend.
Setting Up the Frontend
Your project will have a src-tauri
directory for the Rust backend and a src
directory for the frontend. Let's create a basic HTML frontend with a button that invokes a Rust function.
2. Write the Frontend (HTML + JavaScript)
In the src
directory, create an `index.html` file with the following content:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tauri App</title>
</head>
<body>
<h1>Hello from Tauri!</h1>
<button id="rustButton">Call Rust</button>
<script>
document.getElementById("rustButton").addEventListener("click", () => {
window.__TAURI__.invoke("greet", { name: "Tauri User" });
});
</script>
</body>
</html>
Here, we add a button that, when clicked, will invoke a Rust function called greet
. The JavaScript uses Tauri's window.__TAURI__.invoke
API to send a message to the Rust backend.
Setting Up the Rust Backend
Now, let's add some Rust code to handle this JavaScript invocation.
3. Write the Backend (Rust)
In the src-tauri/src/main.rs
file, modify the code as follows:
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
#[tauri::command]
fn greet(name: &str) {
println!("Hello, {}! This message is from Rust.", name);
}
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("error while running Tauri application");
}
This code does the following:
- The greet
function is a Tauri command that receives a string name
and prints a message to the console.
- The invoke_handler
connects this Rust function to the JavaScript side, making it callable from the frontend.
Building and Running the App
Now that both the frontend and backend are ready, let's build and run the application.
4. Build the App
To compile and package your app, run:
cargo tauri build
5. Run the App
You can run the development server to test your app without building the final executable using:
cargo tauri dev
Advanced Example: File System Access
Now, let’s expand this simple app by allowing it to access the file system, a common need for desktop applications.
Modifying the Rust Backend
In src-tauri/src/main.rs
, add the following code to read the contents of a file and return it to the frontend:
use std::fs;
#[tauri::command]
fn read_file(path: &str) -> Result<String, String> {
fs::read_to_string(path).map_err(|err| format!("Failed to read file: {}", err))
}
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet, read_file])
.run(tauri::generate_context!())
.expect("error while running Tauri application");
}
This code defines a new Tauri command, read_file
, that reads the content of a file given its path and returns the content or an error message to the frontend.
Updating the Frontend
Now, modify the `index.html` file to allow users to select a file and display its contents:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tauri App</title>
</head>
<body>
<h1>Hello from Tauri!</h1>
<button id="rustButton">Call Rust</button>
<input type="file" id="fileInput">
<pre id="fileContent"></pre>
<script>
document.getElementById("rustButton").addEventListener("click", () => {
window.__TAURI__.invoke("greet", { name: "Tauri User" });
});
document.getElementById("fileInput").addEventListener("change", (event) => {
const file = event.target.files[0];
if (file) {
window.__TAURI__.invoke("read_file", { path: file.path })
.then(content => document.getElementById("fileContent").innerText = content)
.catch(err => document.getElementById("fileContent").innerText = `Error: ${err}`);
}
});
</script>
</body>
</html>
Here, when a file is selected, its path is sent to the Rust backend using the read_file
command, and the content of the file is displayed in the HTML <pre>
element.
Building the Final App
After making these changes, you can again build the final executable:
cargo tauri build
Conclusion
Tauri, combined with Rust, allows you to create lightweight, secure, and performant desktop applications that can easily interact with the underlying operating system. This blog post showcased a simple desktop app, complete with Rust backend commands, HTML/JavaScript frontend, and system file access functionality. Whether you're building productivity tools or more complex applications, Tauri and Rust provide the ideal foundation for modern desktop app development.
With Tauri, you can leverage Rust’s strengths while enjoying the flexibility of web technologies. Happy coding!
Comments (0)