Skip to Content

Tauri

Tauri’s shell is Rust. 3va can only take over the frontend toolchain (dev server, bundler, tests), and today only partly. See example 13 for a frontend built entirely with 3va.

What we tried

3va create tauri-app tauri-app -- --template vanilla-ts --manager npm --yes cd tauri-app 3va install --allow-net=registry.npmjs.org

The template installs @tauri-apps/api, @tauri-apps/cli, Vite 8 and TypeScript, with src-tauri/tauri.conf.json pointing at npm run dev and npm run build.

1. The install passes the scanner, and the Tauri CLI’s native binary (a platform-specific optional dependency) is installed.

2. The Tauri CLI doesn’t run under 3va:

$ 3va run node_modules/@tauri-apps/cli/tauri.js --allow-read --allow-env --allow-ffi -- --version error: unrecognized subcommand '3va'

tauri.js looks at process.argv[0]. If the runtime isn’t named node, bun or electron, it assumes it was run as a standalone binary and passes 3va on as a subcommand. Run the CLI with Node (npx tauri), or install it with Cargo, which doesn’t depend on npm at all:

cargo install tauri-cli --version "^2" cargo tauri dev

3. Vite doesn’t run under 3va (see Vite).

4. 3va dev doesn’t load @tauri-apps/api. The package’s "./*": { "import": "./*.js", "require": "./*.cjs" } export is resolved to the .cjs file. That URL then comes back as index.html with status 200, and the browser refuses it:

Failed to load module script: Expected a JavaScript-or-Wasm module script but the server responded with a MIME type of "text/html".

5. 3va bundle works. It bundles the template’s src/main.ts, including @tauri-apps/api/core. It picks the CommonJS build, which is fine inside a bundle:

$ 3va bundle src/main.ts -o dist/main.js --minify ✓ Bundle created: dist/main.js

A setup that works today

Use 3va bundle as the build step and a static index.html in dist/:

src-tauri/tauri.conf.json
{ "build": { "beforeBuildCommand": "3va bundle src/main.ts -o dist/main.js --minify", "frontendDist": "../dist" } }
dist/index.html
<!doctype html> <html> <body> <div id="app"></div> <script src="main.js"></script> </body> </html>

The bundle is a classic script (not an ES module), so load it with a plain <script> after the markup it touches. For development, keep beforeDevCommand on Vite through npm until 3va dev resolves ESM exports correctly.

Things to keep in mind

  • We couldn’t build the desktop app itself here (no Tauri CLI or WebKitGTK on the test machine). The steps above cover the JavaScript side only.
  • Test command logic in TypeScript with 3va test, mirroring your #[tauri::command] handlers (as example 13 does), and keep cargo test for the Rust side.
  • 3va create tauri-app passes everything after -- to create-tauri-app. Without --yes and a template it asks interactively.