Enquire Now
Rust Systems Programming

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!

Gnanavel

Author

Gnanavel

Founder and CEO

Related Posts

Comments (0)