Overall Layout
Learn how a Tauri v2 project organizes its frontend and Rust backend into a clean two-part structure and what a typical directory tree looks like.
A Tauri project separates the web‑based user interface from the native Rust logic.
This split keeps your frontend and backend independent: you develop each with its own toolchain, and you can swap the frontend framework without touching the Rust code.
The layout mirrors a standard web project sitting alongside a Cargo workspace, so it’s easy to navigate even if you’re new to Tauri.
Two-Part Project Structure
Every Tauri application consists of two distinct parts that work together but are built and managed separately.
The first part is the frontend — the code that runs in the webview.
It’s a typical web project with HTML, CSS, and JavaScript (or TypeScript).
You can use any frontend framework that compiles to static files: React, Vue, Svelte, Solid, Angular, plain HTML, or even a Rust‑based framework like Yew or Leptos that targets WebAssembly.
The frontend lives at the root of your project.
A typical structure includes a package.json, an index.html, and a src/ directory containing your framework’s components.
During development, Tauri starts a dev server for the frontend and loads its URL in a native window.
When you build for production, the frontend is compiled to static assets, and Tauri bundles them into the final executable.
The second part is the Rust backend — a standard Cargo project located inside the src-tauri/ directory.
This is where the native application logic lives: window management, system tray, file system access, custom Rust commands that the frontend can call, and any other native APIs.
The Rust code uses the Tauri crate to set up the application, configure windows, and handle lifecycle events.
Because the frontend and the Rust backend are separate projects, you can use npm (or yarn, pnpm, bun) for the frontend and cargo for the backend without them interfering with each other.
This also means you can add Tauri to an existing web app by creating a src-tauri/ folder and configuring a few files — your original frontend code stays untouched.
Rust-only projects:
If you’re using a Rust‑based frontend like Yew, Leptos, or Sycamore, the top‑level project is a Cargo workspace, and src-tauri/ is a member crate.
The same two‑part logic still applies: the src-tauri/ crate handles the Tauri glue, and your UI crate handles the webview content.
Typical Directory Tree
When you scaffold a new Tauri project with create-tauri-app, you get a directory tree that looks like this:
my-tauri-app/
├── package.json
├── index.html
├── src/
│ └── main.js # or main.tsx, App.vue, etc.
├── src-tauri/
│ ├── Cargo.toml
│ ├── Cargo.lock
│ ├── build.rs
│ ├── tauri.conf.json
│ ├── src/
│ │ ├── main.rs
│ │ └── lib.rs
│ ├── icons/
│ │ ├── icon.png
│ │ ├── icon.icns
│ │ └── icon.ico
│ └── capabilities/
│ └── default.json
The top‑level files and folders — package.json, index.html, and src/ — belong to the frontend.
They are exactly what you’d see in any modern web project, with the framework‑specific entry points configured by the scaffolding tool.
Everything inside src-tauri/ is the Rust side.
Here’s a quick fly‑by of what each piece does.
(Each file is explained in detail in the Key Files and Directories Explained chapter.)
Cargo.tomlandCargo.lock— standard Cargo manifest and dependency lock file for the Rust project. Build profiles and crate metadata are covered in Cargo.toml Configuration.tauri.conf.json— the main Tauri configuration file. It sets the application identifier, window settings, dev server URL, bundle options, and more. It also acts as a marker that tells the Tauri CLI where the Rust project lives. See tauri.conf.json for the field-by-field walkthrough.capabilities/— a directory that holds capability files. These are security descriptors that declare which Tauri commands and plugin operations your frontend is allowed to invoke. Details live in the capabilities Directory page.icons/— the default output directory for thetauri iconcommand. The icon files here are used for application bundles on each platform. See the icons Directory page.build.rs— a Cargo build script that callstauri_build::build(). It wires up Tauri’s build‑time setup, like generating the schema fortauri.conf.json. Explained in build.rs.src/main.rs— the desktop entry point. It callsapp_lib::run(), which delegates to the sharedlib.rs. You normally don’t edit this file. See src/main.rs.src/lib.rs— the main Rust file you’ll work in. It contains the application setup, the mobile entry point, and all your custom Rust commands. See src/lib.rs.
Scaffolding confirmation:
If you see this exact layout after running create-tauri-app and installing dependencies, your project is correctly set up and ready for development.
Edit lib.rs, not main.rs:
On desktop builds, src/main.rs boots the app by calling a function defined in src/lib.rs.
On mobile, the app is compiled as a library, and lib.rs is the only entry point.
To keep the codebase unified, put your application logic in lib.rs — modifying main.rs can lead to inconsistencies across platforms.
Don’t move or rename src-tauri:
The Tauri CLI discovers the Rust project by looking for tauri.conf.json inside the src-tauri directory.
Moving or renaming that folder breaks the tooling unless you also update the detection path manually. Keep the layout as‑is unless you fully understand the CLI’s project resolution.
This two‑part layout is the foundation for everything that follows.
Two-Part Project Structure
Understand why a Tauri app consists of a frontend web project and a Rust backend project, how they fit together, and what this separation means for development, builds, and security.
Typical Directory Tree
Understand the file and folder layout of a Tauri v2 project, what each component does, and how the frontend and backend are organized