Skip to content
Back to skills

Tauri Impl Project Setup

ASecurity

Use when starting a new Tauri 2 project, choosing a frontend framework, or understanding project structure. Prevents incorrect lib.rs/main.rs split and missing build configuration that breaks dev and production builds. Covers create-tauri-app scaffolding, project structure, frontend framework integration, src-tauri layout, and source control. Keywords: tauri project setup, create-tauri-app, scaffolding, lib.rs, main.rs, frontend framework, project structure.

  • 5 stars
  • 0 votes
  • 0 copies
  • 5 views
  • Added September 10, 2026
developmentjavascripttypescriptrustgojavabashreactvuenextjsnode

Works with

  • claude code
  • vscode
  • cli
  • api

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 4 files and shows the line behind each finding

Scanned September 10, 2026

npx -y skills add OpenAEC-Foundation/OpenAEC-Workspace-Composer --skill tauri-impl-project-setup --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Tauri Impl Project Setup?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Tauri Impl Project Setup
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/openaec-foundation-tauri-impl-project-setup/badge)](https://www.skillsdirectory.com/skills/openaec-foundation-tauri-impl-project-setup)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: tauri-impl-project-setup
description: >
  Use when starting a new Tauri 2 project, choosing a frontend framework, or understanding project structure.
  Prevents incorrect lib.rs/main.rs split and missing build configuration that breaks dev and production builds.
  Covers create-tauri-app scaffolding, project structure, frontend framework integration, src-tauri layout, and source control.
  Keywords: tauri project setup, create-tauri-app, scaffolding, lib.rs, main.rs, frontend framework, project structure.
license: MIT
compatibility: "Designed for Claude Code. Requires Tauri 2.x with Rust and TypeScript."
metadata:
  author: OpenAEC-Foundation
  version: "1.0"
---

# tauri-impl-project-setup

## Quick Reference

### Scaffolding Commands

| Package Manager | Command |
|----------------|---------|
| npm | `npm create tauri-app@latest` |
| yarn | `yarn create tauri-app` |
| pnpm | `pnpm create tauri-app` |
| bun | `bunx create-tauri-app` |
| cargo | `cargo create-tauri-app` |

### Project Structure

```
my-tauri-app/
├── src/                        # Frontend source (varies by framework)
│   ├── index.html
│   ├── main.ts
│   └── styles.css
├── src-tauri/                  # Rust backend
│   ├── src/
│   │   ├── lib.rs              # App logic (mobile entry point)
│   │   └── main.rs             # Desktop entry point (calls lib.rs)
│   ├── capabilities/           # Permission capability files
│   │   └── default.json        # Default window capabilities
│   ├── permissions/            # Custom command permissions (optional)
│   ├── icons/                  # Application icons (all sizes)
│   ├── gen/                    # Generated files (schemas, etc.)
│   │   └── schemas/
│   ├── Cargo.toml              # Rust dependencies
│   ├── Cargo.lock              # Deterministic build lock
│   ├── tauri.conf.json         # Main configuration
│   ├── build.rs                # Cargo build script
│   └── .taurignore             # Exclude files from watch
├── package.json                # Frontend dependencies
├── tsconfig.json               # TypeScript config
└── vite.config.ts              # Bundler config (if Vite)
```

### Key Config Files

| File | Location | Purpose |
|------|----------|---------|
| `tauri.conf.json` | `src-tauri/` | Main app configuration |
| `Cargo.toml` | `src-tauri/` | Rust crate dependencies |
| `Cargo.lock` | `src-tauri/` | Deterministic dependency lock |
| `default.json` | `src-tauri/capabilities/` | Permission grants for windows |
| `build.rs` | `src-tauri/` | Build script (plugin permission gen) |
| `package.json` | root | Frontend dependencies |

### Critical Warnings

**ALWAYS** commit `src-tauri/Cargo.lock` to source control -- it ensures deterministic builds across environments.

**ALWAYS** add `src-tauri/target/` to `.gitignore` -- build artifacts should NEVER be committed.

**NEVER** put app logic in `main.rs` only -- ALWAYS use the `lib.rs` + `main.rs` split pattern for mobile compatibility.

**NEVER** forget to set a unique `identifier` in `tauri.conf.json` -- duplicate identifiers cause conflicts with other apps on the system.

**ALWAYS** set `beforeDevCommand` and `beforeBuildCommand` in `tauri.conf.json` -- without them, the frontend dev server will not start and builds will lack compiled assets.

**NEVER** skip adding `core:default` permissions in your capability file -- basic window and event operations will fail silently.

---

## Essential Patterns

### Pattern 1: Creating a New Project

```bash
# Interactive scaffolding (recommended)
npm create tauri-app@latest

# This prompts for:
# - Project name
# - Package manager (npm, yarn, pnpm, bun, cargo)
# - Frontend language (TypeScript, JavaScript, Rust)
# - Frontend framework (React, Vue, Svelte, SolidJS, vanilla, etc.)
```

After scaffolding:

```bash
cd my-tauri-app
npm install          # Install frontend dependencies
npm run tauri dev    # Start development mode
```

### Pattern 2: The lib.rs + main.rs Split

This is the REQUIRED pattern for mobile support. Even for desktop-only apps, use this pattern to future-proof your codebase.

**`src-tauri/src/lib.rs`** -- Contains all app logic:

```rust
#[tauri::command]
fn greet(name: String) -> String {
    format!("Hello, {}!", name)
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    tauri::Builder::default()
        .invoke_handler(tauri::generate_handler![greet])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
```

**`src-tauri/src/main.rs`** -- Desktop entry point (thin wrapper):

```rust
// Prevents additional console window on Windows in release
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

fn main() {
    my_tauri_app_lib::run();
}
```

**WHY this split matters**: On mobile platforms (iOS/Android), there is no `main()` function. The `#[cfg_attr(mobile, tauri::mobile_entry_point)]` macro generates the platform-specific entry point on `lib.rs`. Without this split, your app cannot compile for mobile.

### Pattern 3: Minimal tauri.conf.json

```json
{
  "$schema": "./gen/schemas/desktop-schema.json",
  "identifier": "com.example.myapp",
  "build": {
    "devUrl": "http://localhost:5173",
    "frontendDist": "../dist",
    "beforeDevCommand": "npm run dev",
    "beforeBuildCommand": "npm run build"
  },
  "app": {
    "windows": [
      {
        "title": "My App",
        "width": 800,
        "height": 600
      }
    ]
  },
  "bundle": {
    "active": true,
    "icon": [
      "icons/32x32.png",
      "icons/128x128.png",
      "icons/128x128@2x.png",
      "icons/icon.icns",
      "icons/icon.ico"
    ]
  }
}
```

### Pattern 4: Default Capability File

**`src-tauri/capabilities/default.json`**:

```json
{
  "$schema": "../gen/schemas/desktop-schema.json",
  "identifier": "default",
  "description": "Default permissions for the main window",
  "windows": ["main"],
  "permissions": [
    "core:default",
    "core:window:default",
    "core:webview:default"
  ]
}
```

This grants the main window access to core features. Without this, even basic window operations fail.

### Pattern 5: Frontend Framework Integration

All frameworks follow the same integration pattern: the frontend runs its dev server, and Tauri proxies to it.

**Vite (React/Vue/Svelte/SolidJS):**

```json
{
  "build": {
    "devUrl": "http://localhost:5173",
    "frontendDist": "../dist",
    "beforeDevCommand": "npm run dev",
    "beforeBuildCommand": "npm run build"
  }
}
```

**Next.js (SSG mode):**

```json
{
  "build": {
    "devUrl": "http://localhost:3000",
    "frontendDist": "../out",
    "beforeDevCommand": "npm run dev",
    "beforeBuildCommand": "npm run build && npm run export"
  }
}
```

**No framework (vanilla):**

```json
{
  "build": {
    "frontendDist": "../src"
  }
}
```

When using vanilla HTML/CSS/JS without a dev server, omit `devUrl` and `beforeDevCommand`. Tauri serves the files directly.

### Pattern 6: Key Dependencies

**`package.json`:**

```json
{
  "devDependencies": {
    "@tauri-apps/cli": "^2"
  },
  "dependencies": {
    "@tauri-apps/api": "^2"
  },
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "tauri": "tauri"
  }
}
```

**`src-tauri/Cargo.toml`:**

```toml
[package]
name = "my-tauri-app"
version = "0.1.0"
edition = "2021"

[lib]
name = "my_tauri_app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]

[build-dependencies]
tauri-build = { version = "2", features = [] }

[dependencies]
tauri = { version = "2", features = [] }
tauri-plugin-opener = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
```

The `crate-type` array is required for mobile builds: `staticlib` for iOS, `cdylib` for Android, `rlib` for desktop.

### Pattern 7: Development Commands

```bash
# Start development (hot-reload frontend + Rust backend)
npm run tauri dev

# Build for production
npm run tauri build

# Generate icons from a source image
npm run tauri icon /path/to/app-icon.png

# Generate TypeScript bindings
npm run tauri completions
```

### Pattern 8: Adding Plugins

```bash
# Install plugin (both Rust crate and npm package)
npm run tauri plugin add fs

# This does three things:
# 1. Adds tauri-plugin-fs to src-tauri/Cargo.toml
# 2. Adds @tauri-apps/plugin-fs to package.json
# 3. Registers the plugin in lib.rs
```

After installation, ALWAYS add the plugin's permissions to your capability file:

```json
{
  "permissions": [
    "core:default",
    "fs:default"
  ]
}
```

---

## Source Control Best Practices

### .gitignore

```gitignore
# Frontend build artifacts
dist/
node_modules/

# Rust build artifacts
src-tauri/target/

# Generated schemas (regenerated on build)
src-tauri/gen/

# OS-specific
.DS_Store
Thumbs.db

# IDE
.vscode/
.idea/
```

### Files to ALWAYS Commit

| File | Why |
|------|-----|
| `src-tauri/Cargo.lock` | Deterministic Rust builds |
| `src-tauri/tauri.conf.json` | App configuration |
| `src-tauri/capabilities/*.json` | Security permissions |
| `src-tauri/icons/*` | Application icons |
| `package-lock.json` / `pnpm-lock.yaml` | Deterministic JS builds |

### Files to NEVER Commit

| File/Dir | Why |
|----------|-----|
| `src-tauri/target/` | Build artifacts (large, platform-specific) |
| `node_modules/` | Installed packages (reproducible from lockfile) |
| `dist/` | Frontend build output (regenerated) |

---

## Configuration Deep Dive

### Build Section

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `devUrl` | `string` | For dev server | URL of the frontend dev server |
| `frontendDist` | `string` | Yes | Path to compiled frontend assets |
| `beforeDevCommand` | `string` | For dev server | Command to start dev server |
| `beforeBuildCommand` | `string` | Yes | Command to build frontend |
| `beforeBundleCommand` | `string` | No | Command before bundling phase |
| `features` | `string[]` | No | Cargo feature flags to enable |

### Window Configuration (`app.windows[]`)

| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `label` | `string` | `"main"` | Unique window identifier |
| `title` | `string` | -- | Window title bar text |
| `url` | `string` | `"/"` | URL or path to load |
| `width` / `height` | `number` | -- | Size in logical pixels |
| `minWidth` / `minHeight` | `number` | -- | Minimum dimensions |
| `resizable` | `boolean` | `true` | Allow resizing |
| `fullscreen` | `boolean` | `false` | Start fullscreen |
| `decorations` | `boolean` | `true` | Show title bar/borders |
| `transparent` | `boolean` | `false` | Enable transparency |
| `create` | `boolean` | `true` | Create at startup |

### Top-Level Configuration

| Property | Required | Description |
|----------|----------|-------------|
| `identifier` | **Yes** | Reverse-domain notation (e.g., `com.company.app`) |
| `productName` | No | Display name of the application |
| `version` | No | Semver version string |

---

## Reference Links

- [references/methods.md](references/methods.md) -- CLI commands, Cargo.toml options, and tauri.conf.json schema
- [references/examples.md](references/examples.md) -- Complete project setup examples for different frameworks
- [references/anti-patterns.md](references/anti-patterns.md) -- Common setup mistakes and how to avoid them

### Official Sources

- https://v2.tauri.app/start/create-project/
- https://v2.tauri.app/develop/
- https://v2.tauri.app/reference/config/

Files in this skill

  • SKILL.md11.3 KB
  • references/anti-patterns.md7.5 KB
  • references/examples.md6.1 KB
  • references/methods.md6.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.