CodeVetter · Repo Unpack · Contributor handoff
tauri-apps/tauri
Start with ARCHITECTURE.md, then crates/tauri/src/lib.rs for the module map and feature flags. Most edits land in crates/tauri/src (runtime), crates/tauri-utils (config/ACL schema), crates/tauri-cli/src (commands), or packages/api/src (JS API). Respect the cfg matrix (desktop/mobile/dev custom cfgs), keep cross-language constants in sync, add a .changes changefile for any user-visible change, and regenerate committed artifacts before pushing. Test with cargo test per-crate plus pnpm-level JS checks; e2e needs the examples/api app and tauri-driver.
- First reads: ARCHITECTURE.md (component map), crates/tauri/src/lib.rs (module layout + feature docs), crates/tauri/src/app.rs (Builder/App lifecycle), crates/tauri/src/ipc/protocol.rs + webview/mod.rs on_message (IPC security boundary).
- Use either `tauri-build` + `tauri_build_context!` or `generate_context!` — never both; lib.rs warns they generate the same code and duplicate work.
- When touching IPC serialization keep `__TAURI_TO_IPC_KEY__`/`__TAURI_INVOKE_KEY__` consistent across packages/api/src/core.ts, crates/tauri/scripts/ipc.js and crates/tauri/scripts/process-ipc-message-fn.js — the files carry mutual-sync comments.
- Every user-facing change needs a changefile markdown in .changes/ (covector-driven releases via covector-version-or-publish.yml); the dir already holds ~114 pending change files.
- Generated files (schema, templates) are CI-verified — after editing tauri-utils config types or CLI templates run the generators or check-generated-files.yml fails. (inferred)
- Custom cfgs `dev`, `desktop`, `mobile` are pervasive (e.g. `#[cfg(dev)]`, `#[cfg(all(desktop, feature = "tray-icon"))]`); these are set by tauri-build at compile time, not standard cargo features — grep for `cfg(` before assuming a block compiles.
- Feature `custom-protocol` is set by the CLI during production builds and makes `is_dev()` false; conversely `cfg(dev)` paths (e.g. config_parent, mobile dev-server proxying) only compile in dev builds.
- Run `cargo test -p tauri -p tauri-utils` plus `cargo test -p acl-tests`-style integration crates and `pnpm test`/`pnpm eslint:check` for JS; fmt is enforced by .github/workflows/fmt.yml (prettier + rustfmt.toml) and clippy lints are configured in the workspace Cargo.toml.
- Trap: `App::run_iteration` is deprecated because it busy-loops; use `run_return`. Setup-hook failures panic ("Failed to setup app") rather than returning errors.
- Trap: plugin store is locked during the `cleanup_before_exit` hook — calling `AppHandle::remove_plugin`/`plugin` inside it deadlocks, per the Plugin trait docs.
- The workspace patches crates-io `schemars_derive` to a tauri-apps fork to preserve docstring newlines in generated schemas; don't bump schemars casually.
- Safe edit boundaries: adding a CLI subcommand = new module + Commands enum arm in crates/tauri-cli/src/lib.rs; adding a JS API = packages/api/src module + index export; adding a core feature = crates/tauri/src module + feature flag in crates/tauri/Cargo.toml + docs in lib.rs header.