understanding-tauri-ipc
Teaches the assistant about Tauri IPC (Inter-Process Communication) patterns including brownfield and isolation approaches for secure message passing between frontend and Rust backend.
What this skill does
# Tauri Inter-Process Communication (IPC)
This skill covers Tauri's IPC system, including the brownfield and isolation patterns for secure communication between frontend and backend processes.
## Overview
Tauri implements Inter-Process Communication using **Asynchronous Message Passing**. This enables isolated processes to exchange serialized requests and responses securely.
**Why Message Passing?**
- Safer than shared memory or direct function access
- Recipients can reject or discard malicious requests
- Tauri Core validates all requests before execution
- Prevents unauthorized function invocation
## IPC Primitives
Tauri provides two IPC primitives:
### Events
- **Direction**: Bidirectional (Frontend <-> Tauri Core)
- **Type**: Fire-and-forget, one-way messaging
- **Best for**: Lifecycle events, state changes, notifications
**Rust (emit to frontend):**
```rust
use tauri::{AppHandle, Emitter};
fn emit_event(app: &AppHandle) {
app.emit("backend-event", "payload data").unwrap();
}
```
**Frontend (listen):**
```typescript
import { listen } from '@tauri-apps/api/event';
const unlisten = await listen('backend-event', (event) => {
console.log('Received:', event.payload);
});
// Call unlisten() when done
```
**Frontend (emit to backend):**
```typescript
import { emit } from '@tauri-apps/api/event';
await emit('frontend-event', { data: 'value' });
```
### Commands
- **Direction**: Frontend -> Rust backend
- **Protocol**: JSON-RPC-based abstraction
- **API**: Similar to browser's `fetch()` API
- **Requirement**: Arguments and return data must be JSON-serializable
**Rust command definition:**
```rust
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}!", name)
}
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
```
**Frontend invocation:**
```typescript
import { invoke } from '@tauri-apps/api/core';
const greeting = await invoke('greet', { name: 'World' });
console.log(greeting); // "Hello, World!"
```
**Async command with Result:**
```rust
#[tauri::command]
async fn read_file(path: String) -> Result<String, String> {
std::fs::read_to_string(&path)
.map_err(|e| e.to_string())
}
```
## IPC Patterns
Tauri provides two IPC security patterns: **Brownfield** (default) and **Isolation**.
---
## Brownfield Pattern
### What It Is
The brownfield pattern is Tauri's **default** IPC approach. It prioritizes compatibility with existing web frontend projects by requiring minimal modifications.
### When to Use
- Migrating existing web applications to desktop
- Rapid prototyping and development
- Applications with trusted frontend code
- Simple applications with limited IPC surface
### Why Use It
- Zero configuration required
- Minimal changes to existing web code
- Direct access to Tauri APIs
- Fastest development path
### Configuration
Brownfield is the default. Explicit configuration is optional:
```json
{
"app": {
"security": {
"pattern": {
"use": "brownfield"
}
}
}
}
```
**Note:** There are no additional configuration options for brownfield.
### Code Example
**Rust backend:**
```rust
#[tauri::command]
fn process_data(input: String) -> Result<String, String> {
// Direct processing without isolation layer
Ok(format!("Processed: {}", input))
}
```
**Frontend:**
```typescript
import { invoke } from '@tauri-apps/api/core';
// Direct invocation - no isolation layer
const result = await invoke('process_data', { input: 'test' });
```
### Security Considerations
- Frontend code has direct access to all exposed commands
- No additional validation layer between frontend and backend
- Supply chain attacks in frontend dependencies could invoke commands
- Rely on command-level validation in Rust
---
## Isolation Pattern
### What It Is
The isolation pattern intercepts and modifies **all** Tauri API messages from the frontend using JavaScript before they reach Tauri Core. A secure JavaScript application (the Isolation application) runs in a sandboxed iframe to validate and encrypt all IPC communications.
### When to Use
- Applications with many frontend dependencies
- High-security requirements
- Handling sensitive data or operations
- Public-facing applications
- When supply chain attacks are a concern
### Why Use It
**Protection against Development Threats:**
- Validates all IPC calls before execution
- Catches malicious or unwanted frontend calls
- Mitigates supply chain attack risks
- Provides a checkpoint for all communications
**Tauri recommends using isolation whenever feasible.**
### How It Works
1. Tauri's IPC handler receives a message from frontend
2. Message routes to the Isolation application (sandboxed iframe)
3. Isolation hook validates and potentially modifies the message
4. Message encrypts using AES-GCM with runtime-generated keys
5. Encrypted message returns to IPC handler
6. Encrypted message passes to Tauri Core for decryption and execution
**Key Security Features:**
- New encryption keys generated on each application launch
- Sandboxed iframe prevents isolation code manipulation
- All IPC calls validated, including event-based APIs
### Configuration
**tauri.conf.json:**
```json
{
"app": {
"security": {
"pattern": {
"use": "isolation",
"options": {
"dir": "../dist-isolation"
}
}
}
}
}
```
### Code Example
**Directory structure:**
```
project/
src/ # Main frontend
src-tauri/ # Rust backend
dist-isolation/
index.html
index.js
```
**dist-isolation/index.html:**
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Isolation Secure Script</title>
</head>
<body>
<script src="index.js"></script>
</body>
</html>
```
**dist-isolation/index.js:**
```javascript
window.__TAURI_ISOLATION_HOOK__ = (payload) => {
// Log all IPC calls for debugging
console.log('IPC call intercepted:', payload);
// Return payload unchanged (passthrough)
return payload;
};
```
**Validation example (index.js):**
```javascript
window.__TAURI_ISOLATION_HOOK__ = (payload) => {
// Validate command calls
if (payload.cmd === 'invoke') {
const { __tauriModule, message } = payload;
// Block unauthorized file system access
if (message.cmd === 'readFile') {
const path = message.path;
if (!path.startsWith('/allowed/directory/')) {
console.error('Blocked unauthorized file access:', path);
return null; // Block the request
}
}
// Validate specific commands
if (message.cmd === 'deleteItem') {
if (!confirm('Are you sure you want to delete this item?')) {
return null; // User cancelled
}
}
}
return payload;
};
```
**Comprehensive validation example:**
```javascript
const ALLOWED_COMMANDS = ['greet', 'read_config', 'save_settings'];
const BLOCKED_PATHS = ['/etc/', '/usr/', '/System/'];
window.__TAURI_ISOLATION_HOOK__ = (payload) => {
// Validate invoke commands
if (payload.cmd === 'invoke') {
const commandName = payload.message?.cmd;
// Whitelist approach
if (!ALLOWED_COMMANDS.includes(commandName)) {
console.warn('Blocked unknown command:', commandName);
return null;
}
// Validate path arguments
const args = payload.message?.args || {};
if (args.path) {
for (const blocked of BLOCKED_PATHS) {
if (args.path.startsWith(blocked)) {
console.error('Blocked access to protected path:', args.path);
return null;
}
}
}
}
// Validate event emissions
if (payload.cmd === 'emit') {
const eventName = payload.event;
// Add event validation as needed
}
return payload;
};
```
### Performance Considerations
- AES-GCM encryption overhead is minimal for most applications
- Comparable to TLS encryptiRelated in Web Dev
generating-lwc-components
IncludedLightning Web Components with PICKLES methodology and 165-point scoring. Use this skill when the user creates or edits LWC components, builds wire service patterns, or writes Jest tests for LWC. TRIGGER when: user creates/edits LWC components, touches lwc/**/*.js, .html, .css, .js-meta.xml files, or asks about wire service, SLDS, or Jest LWC tests. DO NOT TRIGGER when: Apex classes (use generating-apex), Aura components, or Visualforce.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Set up queries with useQuery, mutations with useMutation, configure QueryClient caching strategies, implement optimistic updates, and handle infinite scroll with useInfiniteQuery. Use when: setting up data fetching in React projects, migrating from v4 to v5, or fixing object syntax required errors, query callbacks removed issues, cacheTime renamed to gcTime, isPending vs isLoading confusion, keepPreviousData removed problems.
document-processor-api
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
nutrient-document-processing
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Covers useMutationState, simplified optimistic updates, throwOnError, network mode (offline/PWA), and infiniteQueryOptions. Use when setting up data fetching, fixing v4→v5 migration errors (object syntax, gcTime, isPending, keepPreviousData), or debugging SSR/hydration issues with streaming server components.
accelint-nextjs-best-practices
IncludedNext.js performance optimization and best practices. Use when writing Next.js code (App Router or Pages Router); implementing Server Components, Server Actions, or API routes; optimizing RSC serialization, data fetching, or server-side rendering; reviewing Next.js code for performance issues; fixing authentication in Server Actions; or implementing Suspense boundaries, parallel data fetching, or request deduplication.