Tamp.Tauri.V2 0.2.1

Prefix Reserved
dotnet add package Tamp.Tauri.V2 --version 0.2.1
                    
NuGet\Install-Package Tamp.Tauri.V2 -Version 0.2.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Tamp.Tauri.V2" Version="0.2.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Tamp.Tauri.V2" Version="0.2.1" />
                    
Directory.Packages.props
<PackageReference Include="Tamp.Tauri.V2" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Tamp.Tauri.V2 --version 0.2.1
                    
#r "nuget: Tamp.Tauri.V2, 0.2.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Tamp.Tauri.V2@0.2.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Tamp.Tauri.V2&version=0.2.1
                    
Install as a Cake Addin
#tool nuget:?package=Tamp.Tauri.V2&version=0.2.1
                    
Install as a Cake Tool

Tamp.Tauri.V2

Wrapper for the Tauri 2.x CLI (@tauri-apps/cli) plus typed path helpers for the externalBin sidecar contract. Pairs with Tamp.Cargo for the canonical Rust + Tauri build chain.

Package Status
Tamp.Tauri.V2 0.1.0 (initial)

Why this exists

Tauri's externalBin contract requires sidecar binaries to land at a specific path: <src-tauri>/binaries/<name>-<target-triple>[.exe]. Many shipped Tauri apps have a class of bug where the sidecar is in the wrong directory, the wrong target-triple, or missing the .exe suffix — the user installs the app and gets a "service not running" dialog because Tauri's runtime sidecar resolver can't find the file.

The pattern is universal: the file-copy step that puts the Rust binary at the externalBin path lives in human memory (or a memo, or a bash script comment), not the build graph. Tamp.Tauri.V2.ExternalBinPath(...) makes that path a typed value flowing through the build script — so the step is part of the dependency graph, not a tribal-knowledge step that drifts from reality.

Install

dotnet add package Tamp.Tauri.V2

Multi-targets net8 / net9 / net10. Requires Tauri 2.x CLI on PATH or in node_modules/.bin/ (the typical install path).

Quick start — Rust + Tauri chain end-to-end

using Tamp;
using Tamp.Cargo;
using Tamp.Tauri.V2;

class Build : TampBuild
{
    public static int Main(string[] args) => Execute<Build>(args);

    [FromPath("cargo")] readonly Tool CargoBin = null!;
    [FromNodeModules("tauri")] readonly Tool TauriCli = null!;

    AbsolutePath ServiceCrate => RootDirectory / "dasbook-service";
    AbsolutePath SrcTauri => RootDirectory / "src-tauri";

    const string TargetTriple = "x86_64-pc-windows-msvc";

    Target BuildService => _ => _
        .Description("[Build] Compile dasbook-service for the Tauri sidecar slot")
        .Executes(() => Cargo.Build(CargoBin, s => s
            .SetWorkingDirectory(ServiceCrate)
            .SetRelease()
            .SetTarget(TargetTriple)
            .SetLocked()));

    Target StageSidecar => _ => _
        .DependsOn(nameof(BuildService))
        .Description("[Build] Stage the compiled service into Tauri's externalBin slot")
        .Executes(() =>
        {
            var built = ServiceCrate / "target" / TargetTriple / "release" / "dasbook-service.exe";
            var sidecar = Tauri.ExternalBinPath(SrcTauri, "dasbook-service", TargetTriple);
            Directory.CreateDirectory(sidecar.Parent!.Value);
            File.Copy(built.Value, sidecar.Value, overwrite: true);
            // The path that used to live in a memo is now a typed expression in the build graph.
        });

    Target BuildDesktop => _ => _
        .DependsOn(nameof(StageSidecar))
        .Description("[Build] Bundle the Tauri desktop app (msi + nsis)")
        .Executes(() => Tauri.Build(TauriCli, s => s
            .SetWorkingDirectory(RootDirectory)
            .AddBundles("msi", "nsis")
            .SetTarget(TargetTriple)));
}

The sidecar staging step that was previously documented in BUILD_NOTES.md and lived in human memory is now part of the dependency graph: BuildDesktop ← StageSidecar ← BuildService. Drift between docs and reality stops being possible because there are no docs to drift from.

Verb surface

Tamp method tauri command Notes
Tauri.Build(...) tauri build --bundles msi,nsis,..., --target, --no-bundle, --debug, --features, --bin, --runner.
Tauri.Info(...) tauri info Diagnostic snapshot of toolchain — useful in CI logs.
Tauri.Icon(...) tauri icon <png> [--output dir] Generate platform icon sets from a source PNG.
Tauri.Migrate(...) tauri migrate v1 → v2 project migration.
Tauri.Raw(...) tauri <anything> Escape hatch — covers plugin, init, signer, etc.

--ci defaults to ON for every verb (turn off via .SetCi(false) for interactive runs).

What's deferred

tauri signer generate and tauri signer sign are not yet typed in 0.1.0 — filed as TAM-190 for a 0.2.0 wave when an adopter actually needs to sign updater artifacts. (Originally this needed Tamp.Tauri.V2 on Tamp.Core's InternalsVisibleTo list to safely Reveal() the password into TAURI_SIGNING_PRIVATE_KEY_PASSWORD; as of Tamp.Core 1.6.0 Secret.Reveal() is public and TAMP004-gated, so the deferral now is just about the unwritten verb surface.) Until then, Tauri.Raw(tool, "signer", "generate", ...) with adopter-managed env covers the case.

ExternalBinPath — the load-bearing helper

public static AbsolutePath ExternalBinPath(
    AbsolutePath srcTauriDir,
    string name,
    string targetTriple,
    bool? isWindows = null);

Computes the absolute path Tauri expects for an external binary:

<srcTauriDir>/binaries/<name>-<target-triple>[.exe]

Examples:

  • ExternalBinPath(srcTauri, "dasbook-service", "x86_64-pc-windows-msvc")…/src-tauri/binaries/dasbook-service-x86_64-pc-windows-msvc.exe
  • ExternalBinPath(srcTauri, "dasbook-service", "x86_64-unknown-linux-gnu")…/src-tauri/binaries/dasbook-service-x86_64-unknown-linux-gnu

The .exe suffix is inferred from the target-triple (any triple containing windows). Override explicitly via the isWindows parameter for unusual cases.

Empty name or targetTriple is rejected at call time — the triple is required by Tauri's contract regardless of host platform; defaulting to host would produce silently-wrong sidecar names in cross-compile scenarios.

HostTargetTriple — for the "build for the current platform" case

var triple = Tauri.HostTargetTriple();
// e.g. "x86_64-pc-windows-msvc" on Windows x64
//      "x86_64-unknown-linux-gnu" on Linux x64
//      "aarch64-pc-windows-msvc" on Windows arm64

Useful when the build script targets the host architecture and doesn't want to hard-code the triple. For cross-compile, set the triple explicitly via Cargo.Build(...)'s SetTarget(...) and pass the same value to ExternalBinPath.

Tool resolution

Tauri's CLI ships as @tauri-apps/cli via npm. Adopters typically resolve via:

[FromNodeModules("tauri")] readonly Tool TauriCli = null!;

This finds node_modules/.bin/tauri(.cmd) for npm-installed projects. Alternative resolutions:

  • [FromPath("tauri")] — globally-installed via cargo install tauri-cli (less common)
  • [FromPath("npx")] + Tauri.Raw(tool, "tauri", "build", ...) — npx-mediated invocation (slower)

The wrapper doesn't opine on which path you choose; it just invokes the resolved Tool.

Bypassing Tauri.Build()CargoBuildSettings.AsTauriShell() (0.2.1+)

tauri build is a wrapper around cargo build against the Tauri shell crate, with its own bundling step appended. Some cargo flags don't surface to tauri-cli — most notably --profile <name> (used in production when default release triggers a compiler bug like the MSVC 14.50 fat-LTO crash that hit DasBook).

When you need cargo-only knobs, the adopter pattern is to bypass Tauri.Build() and configure cargo directly:

[FromPath("cargo")] readonly Tool CargoBin = null!;

Target BuildDesktop => _ => _
    .Executes(() => Cargo.Build(CargoBin, s => s
        .SetWorkingDirectory(SrcTauri)        // run cargo against src-tauri/
        .SetProfile("fast-release")            // custom profile for the LTO-crash workaround
        .AsTauriShell()                        // adds tauri/custom-protocol idempotently
        .SetLocked()));

AsTauriShell() is the cargo-side mirror of TauriBuildSettings.EnableCustomProtocol() (from 0.2.0). Without the tauri/custom-protocol feature, the release-built binary silently runs in dev mode at runtime — compile and sign succeed, but the distributed app fails on first launch. This helper makes the feature unforgettable for adopters going the cargo-direct route.

The extension lives in Tamp.Tauri.V2 (this package) but extends a type from Tamp.Cargo. Tamp.Tauri.V2 >= 0.2.1 declares Tamp.Cargo >= 0.2.0 as a transitive dep, so it's available without a separate dotnet add package step.

Sibling packages

  • Tamp.Cargo — Rust toolchain. The canonical paired wrapper for Tauri's Rust side.
  • Tamp.Npm.V10 — for the frontend stage of a Tauri app (vite dev / vite build orchestration via npm scripts).
  • Tamp.Msix — wraps makeappx / signtool for Microsoft Store packaging downstream of tauri build.

Releasing

Releases follow the Tamp dogfood pattern: bump <Version> in Directory.Build.props, tag v<X.Y.Z>, GitHub Actions runs dotnet tamp Ci then dotnet tamp Push.

License

MIT. See LICENSE.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.2.1 96 5/13/2026
0.2.0 97 5/13/2026
0.1.0 101 5/13/2026