Agent skill
tauri
Tauri path handling, cross-platform file operations, and API usage. Use when the user mentions Tauri, desktop app, or when working with file paths in Tauri frontend code, accessing native filesystem APIs, invoking Tauri commands, or handling platform differences.
Install this agent skill to your Project
npx add-skill https://github.com/EpicenterHQ/epicenter/tree/main/.agents/skills/tauri
Metadata
Additional technical details for this skill
- author
- epicenter
- version
- 1.0
SKILL.md
Tauri Path Handling
Reference Repositories
- Tauri — Desktop app framework with Rust backend and web frontend
When to Apply This Skill
Use this pattern when you need to:
- Build file paths in Tauri frontend code running in the webview.
- Choose correctly between
@tauri-apps/api/pathand Node/BunpathAPIs. - Replace manual slash concatenation with
join(),dirname(), and related helpers. - Handle cross-platform filesystem behavior for desktop apps.
- Combine Tauri path APIs with
@tauri-apps/plugin-fsoperations.
Context Detection
Before choosing a path API, determine your execution context:
| Context | Location | Correct API |
|---|---|---|
| Tauri frontend | apps/*/src/**/*.ts, apps/*/src/**/*.svelte |
@tauri-apps/api/path |
| Node.js/Bun backend | packages/**/*.ts, CLI tools |
Node.js path module |
Rule: If the code runs in the browser (Tauri webview), use Tauri's path APIs. If it runs in Node.js/Bun, use the Node.js path module.
Available Functions from @tauri-apps/api/path
Path Manipulation
| Function | Purpose | Example |
|---|---|---|
join(...paths) |
Join path segments with platform separator | await join(baseDir, 'workspaces', id) |
dirname(path) |
Get parent directory | await dirname('/foo/bar/file.txt') → /foo/bar |
basename(path, ext?) |
Get filename, optionally strip extension | await basename('/foo/bar.txt', '.txt') → bar |
extname(path) |
Get file extension | await extname('file.txt') → .txt |
normalize(path) |
Resolve .. and . segments |
await normalize('/foo/bar/../baz') → /foo/baz |
resolve(...paths) |
Resolve to absolute path | await resolve('relative', 'path') |
isAbsolute(path) |
Check if path is absolute | await isAbsolute('/foo') → true |
Platform Constants
| Function | Purpose | Returns |
|---|---|---|
sep() |
Platform path separator | \ on Windows, / on POSIX |
delimiter() |
Platform path delimiter | ; on Windows, : on POSIX |
Base Directories
| Function | Purpose |
|---|---|
appLocalDataDir() |
App's local data directory |
appDataDir() |
App's roaming data directory |
appConfigDir() |
App's config directory |
appCacheDir() |
App's cache directory |
appLogDir() |
App's log directory |
tempDir() |
System temp directory |
resourceDir() |
App's resource directory |
resolveResource(path) |
Resolve path relative to resources |
Patterns
Constructing Paths (Correct)
import { appLocalDataDir, dirname, join } from '@tauri-apps/api/path';
// Join path segments - handles platform separators automatically
const baseDir = await appLocalDataDir();
const filePath = await join(baseDir, 'workspaces', workspaceId, 'data.json');
// Get parent directory - cleaner than manual slicing
const parentDir = await dirname(filePath);
await mkdir(parentDir, { recursive: true });
Logging Paths (Exception)
For human-readable log output, hardcoded / is acceptable since it's not used for filesystem operations:
// OK for logging - consistent cross-platform log output
const logPath = pathSegments.join('/');
console.log(`[Persistence] Loading from ${logPath}`);
Anti-Patterns
Never: Manual String Concatenation
// BAD: Hardcoded separator breaks on Windows
const filePath = baseDir + '/' + 'workspaces' + '/' + id;
// BAD: Template literal with hardcoded separator
const filePath = `${baseDir}/workspaces/${id}`;
// GOOD: Use join()
const filePath = await join(baseDir, 'workspaces', id);
Never: Manual Parent Directory Extraction
// BAD: Manual slicing is error-prone
const parentSegments = pathSegments.slice(0, -1);
const parentDir = await join(baseDir, ...parentSegments);
// GOOD: Use dirname()
const parentDir = await dirname(filePath);
Never: Hardcoded Separators in Filesystem Operations
// BAD: Windows uses backslashes
const configPath = appDir + '/config.json';
// GOOD: Platform-agnostic
const configPath = await join(appDir, 'config.json');
Never: Assuming Path Format
// BAD: Splitting on '/' fails on Windows paths
const parts = filePath.split('/');
// GOOD: Use dirname/basename for extraction
const dir = await dirname(filePath);
const file = await basename(filePath);
Import Pattern
Always import from @tauri-apps/api/path:
import {
appLocalDataDir,
dirname,
join,
basename,
extname,
normalize,
resolve,
sep,
} from '@tauri-apps/api/path';
Note on Async
All Tauri path functions are async because they communicate with the Rust backend via IPC. Always await them:
// All path operations return Promises
const baseDir = await appLocalDataDir();
const filePath = await join(baseDir, 'file.txt');
const parent = await dirname(filePath);
const separator = await sep();
Filesystem Operations
Use @tauri-apps/plugin-fs for file operations, combined with Tauri path APIs:
import { appLocalDataDir, dirname, join } from '@tauri-apps/api/path';
import { mkdir, readFile, writeFile } from '@tauri-apps/plugin-fs';
async function saveData(segments: string[], data: Uint8Array) {
const baseDir = await appLocalDataDir();
const filePath = await join(baseDir, ...segments);
// Ensure parent directory exists
const parentDir = await dirname(filePath);
await mkdir(parentDir, { recursive: true });
await writeFile(filePath, data);
}
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
svelte
Svelte 5 patterns including runes ($state, $derived, $props), TanStack Query, SvelteMap reactive state, shadcn-svelte components, and component composition. Use when the user mentions .svelte files, Svelte components, or when using TanStack Query, fromTable/fromKv, or shadcn-svelte UI.
autumn
Integrate Autumn billing—define features/plans in autumn.config.ts, use autumn-js SDK for credit checks/tracking, manage the atmn CLI for push/pull. Use when working on billing, pricing, credits, plan gating, or metered usage.
handoff-prompt
Draft a self-contained implementation prompt that an agent can execute with zero prior context. Use when the user says "draft a prompt", "write a handoff", "make a prompt I can copy-paste", "create a delegation brief", or wants to hand off a task to another agent, tool, or conversation.
typebox
TypeBox and TypeMap patterns for runtime schema validation and JSON Schema generation. Use when the user mentions TypeBox, TypeMap, Standard Schema, or when working with runtime type validation, JSON Schema, or schema-based validation.
factory-function-composition
Apply factory function patterns to compose clients and services with proper separation of concerns. Use when creating functions that depend on external clients, wrapping resources with domain-specific methods, or refactoring code that mixes client/service/method options together.
progress-summary
This skill should be used when the user asks questions like "can you summarize", "what happened", "what did we do", "what's the situation", "where are we at", "explain what's going on", "give me an overview", "what's been done", "tell me about this", "walk me through what happened", or any question asking to understand the current state of work or changes. Provides conversational, PR-style summaries with visual diagrams.
Didn't find tool you were looking for?