@tauri-apps/cli-v2.12.0

tauri-apps/tauri@tauri-apps/cli-v2.12.0Sep 26, 2026by github-actions[bot]

Upgrading?

AI Summary

This CLI release adds support for non-square icons via the `--fit` flag, improves capability and permission creation with the `--out` path option, and makes the CLI more CI-friendly by auto-skipping prompts.

Key Highlights

  • Added `--fit` option to `tauri icon` for non-square source images
  • `tauri capability new` and `tauri permission new` now accept an `--out` path
  • `tauri init` automatically skips prompts in non-interactive environments
  • `tauri add` now honors `--tag`, `--rev`, and `--branch`
  • Migrated Android Gradle scripts to `compilerOptions` DSL

New Features

  • `--fit` option for icons
  • `--out` path for capabilities/permissions
  • `--tag/--rev/--branch` in tauri add
  • auto-skip prompts in CI
  • Kotlin DSL migration to compilerOptions

Full Release Notes

## [2.12.0]

### New Features

- [`f6c1eb253`](https://www.github.com/tauri-apps/tauri/commit/f6c1eb2533a0445e081c334931d67fee3e354c6f) ([#15401](https://www.github.com/tauri-apps/tauri/pull/15401)) Added `bundle.windows.bundleVCRuntime` to copy the Visual C++ runtime DLLs into Windows MSI and NSIS installers. The bundler locates the runtime through `VCTOOLS_REDIST_DIR` or the bundled `vswhere.exe`.
- [`f76b1d3ae`](https://www.github.com/tauri-apps/tauri/commit/f76b1d3ae70d0ba0f0eba80b94b867593aa5ca8b) ([#15644](https://www.github.com/tauri-apps/tauri/pull/15644)) The bundler now prints the size of each generated bundle next to its path in the `Finished N bundles at:` output (directories such as macOS `.app` bundles are measured recursively).
- [`af465eae1`](https://www.github.com/tauri-apps/tauri/commit/af465eae1ad99d7b16b8fdbf9aa96bf76d6b9a76) ([#15619](https://www.github.com/tauri-apps/tauri/pull/15619)) Add a `--no-binary-patching` flag to `tauri build` and `tauri bundle`. When set, the bundler skips patching the main executable with bundle type information (and the subsequent re-signing), leaving an already-signed binary untouched. Patching is only required when shipping multiple bundle types per platform that should each update with their own installer format.
- [`0646cc162`](https://www.github.com/tauri-apps/tauri/commit/0646cc1623608dfdaec8d1adbc08d0159b9c2369) ([#15620](https://www.github.com/tauri-apps/tauri/pull/15620)) Add a `--fit` option to `tauri icon` to accept non-square source images. `--fit cover` center-crops the source to a square (clipping the longer side) and `--fit contain` pads the shorter side with transparency. Non-square sources without `--fit` keep erroring, now with a hint pointing to the flag.
- [`f6c1eb253`](https://www.github.com/tauri-apps/tauri/commit/f6c1eb2533a0445e081c334931d67fee3e354c6f) ([#15401](https://www.github.com/tauri-apps/tauri/pull/15401)) Added `build.windows.staticVCRuntime` to control MSVC static runtime linking. The `STATIC_VCRUNTIME` environment variable is now deprecated and emits a migration warning when used.
- [`f45ec0dcf`](https://www.github.com/tauri-apps/tauri/commit/f45ec0dcf83c139c8fdde5e61923a0e82836f756) Record the app version in the trusted comment of updater signatures, so a signed artifact is bound to the version it was released as.
    
    An update endpoint response is not signed, and the signature only covers the downloaded artifact, so the announced `version` on its own does not prove which release the `url` and `signature` point at. minisign covers the trusted comment with its global signature, which lets the updater plugin compare the two and reject a response that pairs a version number with a different release. Enable `requireSignedVersion` in the updater plugin configuration to enforce this.
    
    `tauri build` fills the version in automatically, and `tauri plugin add updater` now enables `requireSignedVersion` for the project it is adding the plugin to. `tauri signer sign` gains an `--app-version` flag for signing updater artifacts by hand, and warns when it is omitted.

### Enhancements

- [`e19121427`](https://www.github.com/tauri-apps/tauri/commit/e19121427332c8a14165999251cce415707a62fc) ([#15993](https://www.github.com/tauri-apps/tauri/pull/15993)) Don't always rewrite `Cargo.toml` file from CRLF line endings to LF
- [`aebf38c84`](https://www.github.com/tauri-apps/tauri/commit/aebf38c845b57bc5653eca677e2e2e044528ea73) ([#15694](https://www.github.com/tauri-apps/tauri/pull/15694)) Migrate the Android Gradle scripts from the deprecated `kotlinOptions` DSL to `compilerOptions`, which is accepted by both Kotlin Gradle Plugin 1.9.x and 2.x. This lets projects move to Kotlin 2.x without hitting the hard error that 2.3+ raises on the old DSL.
    
    This increased the minimum supported Gradle version to 8.13, if your `gradle` is on an earlier version, delete `src-tauri/gen/android/gradle/wrapper/gradle-wrapper.properties` and re-run `tauri android init` to update it.
- [`d89d8fa62`](https://www.github.com/tauri-apps/tauri/commit/d89d8fa62302bd3553b66fd47ecfa046b2fc84ef) ([#15780](https://www.github.com/tauri-apps/tauri/pull/15780)) Warn during Android commands (`init`/`dev`/`build`) when the active Java version is too new for the Gradle version the project uses (e.g. Java 27 against the Gradle 9.6.1 the template ships, or Java 25 against a project still on Gradle 8.14), instead of letting the build fail later with a cryptic error. The warning points to the Gradle/Java compatibility matrix and suggests a supported JDK.
- [`c3d21bd60`](https://www.github.com/tauri-apps/tauri/commit/c3d21bd60c3355b284b23dee1a181c3423231182) ([#15730](https://www.github.com/tauri-apps/tauri/pull/15730)) Use `Theme.Material3.DayNight.NoActionBar` instead of `Theme.MaterialComponents.DayNight.NoActionBar` when running `tauri android init`
- [`f654f470c`](https://www.github.com/tauri-apps/tauri/commit/f654f470c122e925e425424cea733f13d3306412) ([#15862](https://www.github.com/tauri-apps/tauri/pull/15862)) Update template to use `targetSdk = 37`
- [`cdaf7eab6`](https://www.github.com/tauri-apps/tauri/commit/cdaf7eab6c5fccc2a4812af18f58fd3530f3eedd) ([#15765](https://www.github.com/tauri-apps/tauri/pull/15765)) Clarify that the `tauri init` frontend commands run before `tauri dev` and `tauri build`, and can be left empty when they are not needed.
- [`d0f38df06`](https://www.github.com/tauri-apps/tauri/commit/d0f38df06a2f4406b388a336694aa18b3c6bf1a9) ([#15997](https://www.github.com/tauri-apps/tauri/pull/15997)) When stdin is not a terminal, `tauri init` now automatically skips prompts, avoiding IO errors in CI and scripts. This eliminates the need to pass `--ci` explicitly in non-interactive environments.
- [`ca160ad48`](https://www.github.com/tauri-apps/tauri/commit/ca160ad4808f477380cb0865a08a8ae781e37f85) ([#15895](https://www.github.com/tauri-apps/tauri/pull/15895)) `tauri build` now warns when `productName` is still set to the default `tauri-app`, since it names the generated bundles and is written into install paths and metadata that are expected to be unique to your application. The config documentation for `productName` now lists what the field controls on each platform, and `identifier`'s documentation notes that the default value is rejected.
- [`010f06bae`](https://www.github.com/tauri-apps/tauri/commit/010f06baecd499c41321da3130e20147c50025f7) ([#15737](https://www.github.com/tauri-apps/tauri/pull/15737)) Document the `TAURI_SIGNING_PRIVATE_KEY_PATH` environment variable and clarify that `TAURI_SIGNING_PRIVATE_KEY` accepts a string or a path for the `build` and `bundle` command but must be the literal key string for the `signer sign` command, both in `ENVIRONMENT_VARIABLES.md` and in the `signer generate` command output.

### Bug Fixes

- [`9bad06b9f`](https://www.github.com/tauri-apps/tauri/commit/9bad06b9f61996faed1c33709f1b8dd196602793) ([#16096](https://www.github.com/tauri-apps/tauri/pull/16096)) `tauri capability new` and `tauri permission new` now accept an `--out` path to a file that does not exist yet, trim comma-separated prompt answers (so `fs:default, core:default` works), report invalid permissions as errors instead of panicking, and reject identifiers that are not valid file names (such as `../../x`), which previously let them write outside of the capabilities or permissions directory.
- [`9642b3087`](https://www.github.com/tauri-apps/tauri/commit/9642b30879eda8bde35fa3c7606718ca0d364f2e) ([#16117](https://www.github.com/tauri-apps/tauri/pull/16117)) `tauri add` now honors `--tag`, `--rev` and `--branch` for official plugins instead of silently installing the registry version, and rejects passing more than one of them. With npm, the JS package requirement is now `~<version>` like the other package managers, instead of `>=<version>` which allowed a later major version.
- [`cada1cd4f`](https://www.github.com/tauri-apps/tauri/commit/cada1cd4f3e59efb48b2c7a176d240846f55ad0d) ([#16105](https://www.github.com/tauri-apps/tauri/pull/16105)) Fix Android dev server port forwarding: `adb reverse --list` is now matched on the exact port (so `tcp:80` no longer matches `tcp:8080`), stale forwards on other connected devices are actually removed, and the forward verification gives up with a warning after a few attempts instead of retrying forever.
- [`d5bd04658`](https://www.github.com/tauri-apps/tauri/commit/d5bd046583d066024ba073840007f4476e52a5fb) ([#16111](https://www.github.com/tauri-apps/tauri/pull/16111)) Fix `bundle > android > debugApplicationIdSuffix` being written to the `signingConfigs` debug block instead of the `buildTypes` one, and keep the existing content of single-line debug blocks such as `getByName("debug") { isDebuggable = true }` instead of dropping it.
- [`ba17da2e5`](https://www.github.com/tauri-apps/tauri/commit/ba17da2e55184fe74990db64496b0d02e79cce09) ([#16101](https://www.github.com/tauri-apps/tauri/pull/16101)) `tauri icon` now generates 72x72 Android `hdpi` launcher icons (previously 49x49) and writes the Android launcher background color in `#RRGGBB`/`#AARRGGBB` notation instead of the raw CSS color string, which Android rejected or misread. Invalid SVG sources and `--png 0` now return an error instead of panicking.
- [`272842a57`](https://www.github.com/tauri-apps/tauri/commit/272842a571a56401649db7aaa93ea400561a1661) ([#16128](https://www.github.com/tauri-apps/tauri/pull/16128)) Fix error messages that printed placeholders such as `{t}` literally instead of the value, e.g. "Could not find an Android device matching {t}".
- [`10ad4e54e`](https://www.github.com/tauri-apps/tauri/commit/10ad4e54e2f1272ee7bb08418dc386058532a5e8) ([#16127](https://www.github.com/tauri-apps/tauri/pull/16127)) The Bash completions generated by `tauri completions` no longer replace the completions of `cargo`, `npm`, `pnpm`, `yarn`, `bun` and `deno`. They now define a `_tauri_cli` function registered only for the `tauri` and `cargo-tauri` commands. Generating completions when running the `cargo-tauri` binary directly no longer panics.
- [`0e4ded72a`](https://www.github.com/tauri-apps/tauri/commit/0e4ded72a6a617fa16dff196e7fbd3716997e66f) ([#16107](https://www.github.com/tauri-apps/tauri/pull/16107)) Fix binaries in `src/bin` and `src/main.rs` being left out of bundles when `Cargo.toml` declares a `[[bin]]` target without a `path`.
- [`8e0fa2e2f`](https://www.github.com/tauri-apps/tauri/commit/8e0fa2e2f8859cdd38dc07cfc24a1b012ef29fc3) ([#16097](https://www.github.com/tauri-apps/tauri/pull/16097)) Fix the bundler using the host target triple when `--target` is not passed but `build.target` is set in `.cargo/config.toml`. The CLI now also accepts `build.target` as an array and honors the `CARGO_BUILD_TARGET` environment variable.
- [`7bb0a5421`](https://www.github.com/tauri-apps/tauri/commit/7bb0a542179bd4ccb17e0baf0dca2c3b2f3f7721) ([#16120](https://www.github.com/tauri-apps/tauri/pull/16120)) Fix the Cargo.toml feature rewrite corrupting a string dependency version that has a trailing comment or uses single quotes (e.g. `tauri = "2" # pin` became `"2#pin"`). The version value is now kept as-is and the comment is preserved.
- [`e4630258e`](https://www.github.com/tauri-apps/tauri/commit/e4630258e3184fceb60e6c548a7ec61fb81f885d) ([#16114](https://www.github.com/tauri-apps/tauri/pull/16114)) Fix the CLI's working directory being left changed to the config directory when the Tauri configuration fails to parse, for example when `tauri dev` reloads an invalid config.
- [`1b91b7b7b`](https://www.github.com/tauri-apps/tauri/commit/1b91b7b7b3dad8b77bcaeadc6653250e04f0cb7b) ([#16102](https://www.github.com/tauri-apps/tauri/pull/16102)) `tauri info` now logs a warning when it cannot check the latest crate version on crates.io instead of silently ignoring the failure, and no longer panics if crates.io returns a version it cannot parse.
- [`1b91b7b7b`](https://www.github.com/tauri-apps/tauri/commit/1b91b7b7b3dad8b77bcaeadc6653250e04f0cb7b) ([#16102](https://www.github.com/tauri-apps/tauri/pull/16102)) `tauri info` now lists every locked version of a Rust crate when `Cargo.lock` contains more than one, and no longer panics when the crates.io response cannot be parsed.
- [`6507d0b8b`](https://www.github.com/tauri-apps/tauri/commit/6507d0b8b360a41615139619eb39680e60df7732) ([#16124](https://www.github.com/tauri-apps/tauri/pull/16124)) `tauri dev` now reports an error instead of panicking when the `beforeDevCommand` cannot be spawned or the `devUrl` host cannot be resolved, and no longer risks stopping the `beforeDevCommand` process tree twice when Ctrl+C and the app exit race.
- [`c1ea96ad6`](https://www.github.com/tauri-apps/tauri/commit/c1ea96ad6b433524c5cb570f55bbbe1fd72cca1e) ([#16110](https://www.github.com/tauri-apps/tauri/pull/16110)) Fix `tauri dev` not reacting to the app exiting when a process spawned by the app kept its stderr open, and stop keeping the whole app stderr output in memory. Also fix command output capture that could return empty output when the command finished before its output was read.
- [`d61fbdc3e`](https://www.github.com/tauri-apps/tauri/commit/d61fbdc3e825749261c76b7a37454dd3c4483619) ([#16109](https://www.github.com/tauri-apps/tauri/pull/16109)) Fix Cargo.toml feature injection and the v1 migration only updating either `[dependencies]` or `[target.'cfg(..)'.dependencies]`, whichever came first in the file. Both the main and all target-specific dependency tables are now updated.
- [`5d995ed35`](https://www.github.com/tauri-apps/tauri/commit/5d995ed35b029cecd780fdbe614dc6023a89b81b) ([#16017](https://www.github.com/tauri-apps/tauri/pull/16017)) Normalize `gen/android/gradlew` CRLF line endings to LF on all host platforms, not only Unix. A `gradlew` checked out with CRLF broke `sh ./gradlew` on Windows hosts using Git Bash. The rewrite only runs when a CRLF is actually present. A failure to rewrite aborts on Unix, where the script is executed directly; on Windows the CLI invokes `gradlew.bat`, so failures there only warn.
- [`6d943c420`](https://www.github.com/tauri-apps/tauri/commit/6d943c420454e75636af968b435efb9167818d22) ([#16065](https://www.github.com/tauri-apps/tauri/pull/16065)) Fix the `tauri capability new` command description, which said "Create a new permission file", and the `--skip-stapling` help text on `tauri build` and `tauri bundle`, whose first line described the opposite of what the flag does.
- [`b8be924d3`](https://www.github.com/tauri-apps/tauri/commit/b8be924d39c87eaecb9ba6f893e1a7be94d7bd68) ([#16106](https://www.github.com/tauri-apps/tauri/pull/16106)) `tauri init` no longer panics when the app name, window title, frontend dist, dev URL or before dev/build commands contain quotes or backslashes (e.g. `-D ..\dist` or `vite --host "0.0.0.0"`); the values are now JSON-escaped in the generated `tauri.conf.json`.
- [`b9b32a259`](https://www.github.com/tauri-apps/tauri/commit/b9b32a259fb00524808e84b4da0f7904a51be06c) ([#16108](https://www.github.com/tauri-apps/tauri/pull/16108)) Fix `PRODUCT_BUNDLE_IDENTIFIER` in the iOS Xcode project being set to the raw `identifier` (with underscores) instead of the sanitized iOS bundle identifier used by the Xcode project template and the export options provisioning profiles.
- [`4f51a2f06`](https://www.github.com/tauri-apps/tauri/commit/4f51a2f06248f231fc6a9160c95c026634356ba5) ([#16115](https://www.github.com/tauri-apps/tauri/pull/16115)) Fix `tauri ios run --features` being ignored, and `tauri ios dev --release` still building the app in debug mode.
- [`59e077457`](https://www.github.com/tauri-apps/tauri/commit/59e077457ac87ffd43db4c557ca2987d2fa6d37e) ([#16075](https://www.github.com/tauri-apps/tauri/pull/16075)) `tauri ios build` for a simulator target no longer fails with "failed to rename app: Directory not empty" when the output `.app` from a previous build exists.
- [`fe1aa30d2`](https://www.github.com/tauri-apps/tauri/commit/fe1aa30d2b1743325cdd882fe36604daf62c2440) ([#16113](https://www.github.com/tauri-apps/tauri/pull/16113)) Quote the Tauri CLI path and the Xcode variables in the iOS "Build Rust Code" build phase, fixing builds when Xcode or the CLI is installed in a path containing spaces (requires regenerating the Xcode project with `tauri ios init`). Also fixes `CXXFLAGS` not being set for iOS targets in `tauri ios xcode-script`.
- [`aa0a801c3`](https://www.github.com/tauri-apps/tauri/commit/aa0a801c3acb6cc1f9d0afbae6cbfa144a5ea7fb) ([#16116](https://www.github.com/tauri-apps/tauri/pull/16116)) Fix Java version detection for the Android Java/Gradle compatibility warning when `JAVA_HOME` is not set: the `java` binary on `PATH` is now resolved through symlinks (e.g. Linux alternatives and Homebrew), and on macOS the `/usr/bin/java` stub falls back to `/usr/libexec/java_home`.
- [`1aafaa4e3`](https://www.github.com/tauri-apps/tauri/commit/1aafaa4e3cafc779d4d825c95c3604a7da661092) ([#16103](https://www.github.com/tauri-apps/tauri/pull/16103)) When rewriting a localhost `devUrl` to the network address for mobile development, the query string and fragment are now preserved, and the IPv6 loopback (`[::1]`) and unspecified (`[::]`) addresses are now treated as localhost.
- [`022932dd5`](https://www.github.com/tauri-apps/tauri/commit/022932dd596e38d27a0bafebf26ea9df2ec2cff3) ([#16123](https://www.github.com/tauri-apps/tauri/pull/16123)) Fix iOS Xcode project synchronization corrupting `project.pbxproj` when several build settings were added to the same configuration, when an added setting was changed again, or when a multi-line setting was overwritten. Product names, signing identities and other values written to the project are now properly escaped.
- [`a4099d819`](https://www.github.com/tauri-apps/tauri/commit/a4099d819bdc33385adcc11b7830fc5fdda410d2) ([#16098](https://www.github.com/tauri-apps/tauri/pull/16098)) `tauri permission add` (and `tauri add`) no longer overwrites an existing `capabilities/desktop.json` or `capabilities/mobile.json` when adding a desktop-only or mobile-only plugin permission and no platform-restricted capability exists; the new capability now gets an unused file name and identifier (e.g. `desktop-2.json`). An explicitly passed capability is now used even if its platforms do not match the plugin, with a warning, instead of being silently ignored.
- [`e49d1b474`](https://www.github.com/tauri-apps/tauri/commit/e49d1b47429acaf34de9e9edc251f71163990783) ([#16100](https://www.github.com/tauri-apps/tauri/pull/16100)) `tauri permission rm <plugin>:*` and `tauri remove` no longer strip unrelated permissions whose identifier merely contains the plugin name (e.g. `tauri remove os` removing `positioner:default`). Local permission files are now looked up in the Tauri directory, like `tauri permission new`, and an unparsable permission file is skipped with a warning instead of aborting the command.
- [`efa82f5ed`](https://www.github.com/tauri-apps/tauri/commit/efa82f5ed989f84b076b6ee6d2f0e1e6dd0aadbf) ([#16125](https://www.github.com/tauri-apps/tauri/pull/16125)) Fix plugin scaffolding for names like `my-plugin`: the default Android package ID now uses a snake_case segment (`com.plugin.my_plugin`) and user-provided IDs are validated, iOS Xcode folders use the same kebab-case name as the project file, and the `plugin ios init`/`plugin android init` code snippets now match the generated bindings and the `setup(|app, api| ..)` API. `plugin init` into a non-empty directory no longer creates a `permissions` folder after skipping the template.
- [`db6804d80`](https://www.github.com/tauri-apps/tauri/commit/db6804d80223aabc6b338e94d192a5ad6dd6220b) ([#16126](https://www.github.com/tauri-apps/tauri/pull/16126)) Fix `--release` being added to the cargo command when a custom profile is passed as `--profile=<name>`, which made cargo reject the build.
- [`8310461f6`](https://www.github.com/tauri-apps/tauri/commit/8310461f6453ce478d2092a4744d42e3468e0bb0) ([#16104](https://www.github.com/tauri-apps/tauri/pull/16104)) Fix `tauri init` and `tauri info` detecting SvelteKit projects as plain Svelte; `tauri init` suggested the wrong dev server URL and frontend dist directory.
- [`eaf96690d`](https://www.github.com/tauri-apps/tauri/commit/eaf96690db2439445fe16da24031bf3294ada605) ([#15804](https://www.github.com/tauri-apps/tauri/pull/15804)) On Linux, do not bundle xdg-open and xdg-utils in the AppImage anymore. This rarely worked and usually requires host system support anyway.
- [`2b7c1f8b6`](https://www.github.com/tauri-apps/tauri/commit/2b7c1f8b63619c6f4c16380d0c4a3358e694fb11) ([#16003](https://www.github.com/tauri-apps/tauri/pull/16003)) Fix `tauri add` / `tauri remove` installing npm plugin packages into `src-tauri` instead of the frontend directory.
- [`c735ba32b`](https://www.github.com/tauri-apps/tauri/commit/c735ba32b36d505cbf9eabfb4a33005ca31edbdd) ([#15241](https://www.github.com/tauri-apps/tauri/pull/15241)) Fix broken child window icons in Task Manager, you'll need to re-run `tauri icon` to generate the fixed icons
- [`adf5acf6f`](https://www.github.com/tauri-apps/tauri/commit/adf5acf6fbc0ef26de6b1eb30c47bb701c256954) ([#15651](https://www.github.com/tauri-apps/tauri/pull/15651)) Fix MSI bundling when an external binary filename starts with a digit.
- [`11012a13f`](https://www.github.com/tauri-apps/tauri/commit/11012a13f55ab55ec5ed12ca3ac95338ae1731c3) ([#15681](https://www.github.com/tauri-apps/tauri/pull/15681)) Fix WiX bundler doesn't respect the resource's target file name.
- [`59e077457`](https://www.github.com/tauri-apps/tauri/commit/59e077457ac87ffd43db4c557ca2987d2fa6d37e) ([#16075](https://www.github.com/tauri-apps/tauri/pull/16075)) Detect pnpm from `npm_config_user_agent` when generating the mobile projects. pnpm's native binary (pnpm 11+) runs package scripts without setting `PNPM_PACKAGE_NAME`, and when installed through corepack the binary is named `pnpm-native`, so `tauri android init` recorded `pnpm-native` as the command for Gradle to run and the Android build failed with "A problem occurred starting process 'command 'pnpm-native''".
- [`6a298ee12`](https://www.github.com/tauri-apps/tauri/commit/6a298ee12e7ffde115175d43ac63a2fdcba51c3e) ([#15713](https://www.github.com/tauri-apps/tauri/pull/15713)) Fix `tauri info` reporting the Rust-only plugins (`localhost`, `persisted-scope` and `single-instance`) as missing their `@tauri-apps/plugin-*` JavaScript package, which is never published for those plugins.
- [`33b3ea582`](https://www.github.com/tauri-apps/tauri/commit/33b3ea582340ce8fe799929472595789319d0826) The bundled `vswhere.exe` is now written to a new, uniquely named temporary file on each use and removed afterwards, instead of running any existing `%TEMP%\vswhere.exe`.

### What's Changed

- [`2e6e33c85`](https://www.github.com/tauri-apps/tauri/commit/2e6e33c8501c66c9a49aad861048d39345cfb26f) ([#16029](https://www.github.com/tauri-apps/tauri/pull/16029)) Moved to edition 2024 for the `tauri init`/`tauri plugin init` templates
- [`ce3f13b91`](https://www.github.com/tauri-apps/tauri/commit/ce3f13b91a75cb723f229f56a3e82eb5f2d3f644) ([#15887](https://www.github.com/tauri-apps/tauri/pull/15887)) Lock unstable tauri crates to minor versions.

### Security fixes

- [`98918df64`](https://www.github.com/tauri-apps/tauri/commit/98918df6416f7ac6849962141a41bbd210131067) ([#16112](https://www.github.com/tauri-apps/tauri/pull/16112)) `tauri add` no longer installs the npm package `tauri-plugin-<name>-api` for community plugins. npm and crates.io are separate namespaces, so that package may be unowned or squatted; the CLI now asks you to install the plugin's JavaScript bindings yourself. `tauri remove` only removes the plugin's JS package when `package.json` lists it, and a failure there no longer skips the capability cleanup.
- [`cc9d522c6`](https://www.github.com/tauri-apps/tauri/commit/cc9d522c64329b8dab84ecbd38c76928ad31cb43) ([#16095](https://www.github.com/tauri-apps/tauri/pull/16095)) The built-in dev server now rejects requests whose `Host` header is not the address it serves on, which blocks DNS rebinding attacks, and rejects cross-site `Origin`s on its reload WebSocket. The `index.html` fallback now goes through the same path scope check as other files, and the reload WebSocket no longer closes when the client sends a message.
- [`dacddfe9f`](https://www.github.com/tauri-apps/tauri/commit/dacddfe9ff1f28b53e2c0324498e3a666a8041fa) ([#16094](https://www.github.com/tauri-apps/tauri/pull/16094)) The CLI no longer writes its default ignore rules to shared files in the system temporary directory (`.gitignore` and `.tauri/.gitignore`) and reads them back, which let other local users change which files the project lookup and the dev watcher skip. The rules are now applied in memory. `TAURI_CLI_WATCHER_IGNORE_FILENAME` is now consistently treated as an ignore file name looked up in each directory, as documented.
- [`fdd56da19`](https://www.github.com/tauri-apps/tauri/commit/fdd56da19e40962cb2db613a0b87a38a21f571e4) ([#16099](https://www.github.com/tauri-apps/tauri/pull/16099)) Secure the local server that `tauri android|ios dev|build` uses to pass options to the Android Studio and Xcode build scripts: requests now need a random per-session token, WebSocket connections from web pages (with an `Origin` header) are rejected, and variables whose name contains `TOKEN`, `PASSWORD`, `SECRET` or `CREDENTIAL` are no longer sent. The connection details are now written with owner-only permissions to `gen/<android|apple>/.tauri/cli-options-server.json` (instead of the shared temp directory) and removed when the command exits. The IDE build scripts now report a clear error when the Tauri CLI command is not running.
- [`ff7cd8d86`](https://www.github.com/tauri-apps/tauri/commit/ff7cd8d863061aaa1c5932062b071db6b17af36e) ([#16118](https://www.github.com/tauri-apps/tauri/pull/16118)) `tauri signer generate --write-keys` now creates the private key with owner-only permissions (0600) on Unix and refuses to overwrite either the private or the public key file without `--force`. Updater signing now rejects file names containing tabs or newlines (which would corrupt the signature's trusted comment) and assumes an empty password instead of prompting when no password is given and stdin is not a terminal. `tauri signer` reports errors instead of panicking.
- [`51aa20388`](https://www.github.com/tauri-apps/tauri/commit/51aa20388e01c9d03f33992647b14dcf7800c540) ([#16119](https://www.github.com/tauri-apps/tauri/pull/16119)) On Windows, package manager commands (`npm`, `pnpm`, `yarn`, `bun`, `deno`, `node`) are now executed directly instead of through `cmd /c`, so arguments such as `@tauri-apps/plugin-fs@>=2` are escaped properly and can no longer be interpreted as shell redirections or command separators.

### Dependencies

- Upgraded to `tauri-cli@2.12.0`
- [`e2e585ad1`](https://www.github.com/tauri-apps/tauri/commit/e2e585ad1196c9572f86ef39aae01ef4c3b1a762) ([#15828](https://www.github.com/tauri-apps/tauri/pull/15828)) On Android, fix missing `consumer-rules.pro` file in the template.
    
    **IMPORTANT**: For plugin authors, update your `build.gradle.kts` file to remove the
    
    ```kotlin
        buildTypes {
            release {
                isMinifyEnabled = false
                proguardFiles(
                    getDefaultProguardFile("proguard-android-optimize.txt"),
                    "proguard-rules.pro"
                )
            }
        }
    ```
    
    section and rename your `proguard-rules.pro` to `consumer-rules.pro` to match the `consumerProguardFiles("consumer-rules.pro")` in the template.
- [`e2e585ad1`](https://www.github.com/tauri-apps/tauri/commit/e2e585ad1196c9572f86ef39aae01ef4c3b1a762) ([#15828](https://www.github.com/tauri-apps/tauri/pull/15828)) On Android, updated the template to use Gradle v9.6.1 (`com.android.tools.build:gradle` v9.3.1) and Kotlin v2.2. Use `tauri android init` to apply the change.
- [`9e9a54dea`](https://www.github.com/tauri-apps/tauri/commit/9e9a54dea26ae66de63800cabbccf980902a1cd3) ([#15890](https://www.github.com/tauri-apps/tauri/pull/15890)) Update the generated iOS Xcode project to build with Xcode 27. The scenes lifecycle is **not** enabled by default: to opt in, add the `UIApplicationSceneManifest` key to your `src-tauri/Info.ios.plist`.
- [`b6660a041`](https://www.github.com/tauri-apps/tauri/commit/b6660a041db44729893dae7991a9be61cf8c2ed5) ([#15954](https://www.github.com/tauri-apps/tauri/pull/15954)) Update typescript to v7 in `tauri plugin init` template. Also fixes the default `rootDir` in the template `tsconfig.json`
- [`9e9a54dea`](https://www.github.com/tauri-apps/tauri/commit/9e9a54dea26ae66de63800cabbccf980902a1cd3) ([#15890](https://www.github.com/tauri-apps/tauri/pull/15890)) Update cargo-mobile2 and change the default minimum iOS version to 15.0 to support Xcode 27.


Related Repositories