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.

Stars 4,333
Forks 311

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/path and Node/Bun path APIs.
  • 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-fs operations.

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)

typescript
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:

typescript
// OK for logging - consistent cross-platform log output
const logPath = pathSegments.join('/');
console.log(`[Persistence] Loading from ${logPath}`);

Anti-Patterns

Never: Manual String Concatenation

typescript
// 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

typescript
// 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

typescript
// BAD: Windows uses backslashes
const configPath = appDir + '/config.json';

// GOOD: Platform-agnostic
const configPath = await join(appDir, 'config.json');

Never: Assuming Path Format

typescript
// 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:

typescript
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:

typescript
// 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:

typescript
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);
}

Expand your agent's capabilities with these related and highly-rated skills.

EpicenterHQ/epicenter

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.

4,333 311
Explore
EpicenterHQ/epicenter

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.

4,333 311
Explore
EpicenterHQ/epicenter

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.

4,333 311
Explore
EpicenterHQ/epicenter

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.

4,333 311
Explore
EpicenterHQ/epicenter

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.

4,333 311
Explore
EpicenterHQ/epicenter

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.

4,333 311
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results