Skip to content

Events and Windows: Interactive Apps

A static application is rarely useful. To build truly interactive software, your Frontend needs to talk to the Rust Core in real-time, and you need control over the application window itself. In this chapter, we will explore the Event System for message passing and the Window API for managing your application’s lifecycle and appearance.

While Commands (IPC) are great for request-response interactions (like asking Rust to calculate something and return the result), they aren’t ideal for spontaneous occurrences. For example, if a long-running download finishes in Rust, how does the frontend know? This is where Events come in.

Tauri provides a global event bus that operates on a publish-subscribe model. Both the Rust backend and the JavaScript frontend can emit and listen to events.

To send a message from Rust to your UI, you use the emit method on an app handle or window instance.

src-tauri/src/lib.rs
// Inside a command or setup hook
app.emit("download-progress", "99%").unwrap();

On the JavaScript side, you subscribe to this event. Remember to clean up the listener to avoid memory leaks, especially in frameworks like React or Vue.

import { listen } from '@tauri-apps/api/event';
// Set up the listener
const unlisten = await listen<string>('download-progress', (event) => {
console.log(`Download status: ${event.payload}`);
});
// Later, when you want to stop listening:
unlisten();

Tauri gives you programmatic control over your application windows. You aren’t limited to just one window; you can modify existing ones or spawn new ones dynamically. This is handled via the @tauri-apps/api/window module.

Common operations include:

  • Decorations: Showing or hiding the title bar and window controls.
  • Resizing: setting the specific width and height.
  • Focus: Bringing the window to the front.
  • Closing: Terminating the window.
import { getCurrentWindow } from '@tauri-apps/api/window';
const appWindow = getCurrentWindow();
// Minimize the window
await appWindow.minimize();
// Toggle fullscreen
await appWindow.setFullscreen(true);
// Close the window
await appWindow.close();

Many complex apps require multiple windows—for example, a main dashboard and a separate settings window or a splash screen.

You can define windows statically in tauri.conf.json, or create them at runtime using the WebviewWindow class in JavaScript. This allows you to load a different HTML file or route for the new window.

import { WebviewWindow } from '@tauri-apps/api/webviewWindow';
const settings = new WebviewWindow('settings', {
url: 'settings.html',
title: 'Preferences',
width: 600,
height: 400
});
settings.once('tauri://created', function () {
console.log('Settings window created successfully');
});

By mastering Events and Windows, you transform your app from a static page into a fluid, desktop-class application.