Skip to content

Create a React app from packages

Use the NetWiv CLI to create a desktop application with a React frontend and C# backend. Use the packages/ directory from a published Release bundle, a separately supplied NuGet feed, or one built from source. Release availability depends on maintainer publication; cloning the repository does not provide a prebuilt package feed. To create packages yourself, see framework development. Full TAURI® compatibility and release validation remain incomplete. For a shared Razor UI with managed desktop development and deployment, optional experimental NativeAOT Hybrid or WebAssembly execution, see the optional NetWiv.BlazorHybrid guide. With the package feed below, select that layout using netwiv new MyBlazorApp -t blazor-hybrid --source $feed, then run dotnet run --project src-netwiv from the new directory. Its Debug mode uses managed Hybrid on the supported desktop platforms in both Debug and Release. Set NetWivBlazorTargetFramework in the generated Directory.Build.props to net9.0 or net10.0 to change the default .NET 8 target and matching component packages together. Choose WebAssembly with --blazor-mode WebAssembly. Experimental NativeAOT Hybrid requires netwiv build --no-bundle --aot --blazor-mode Hybrid --experimental-blazor-aot.

  • Windows: .NET 8 or later SDK, WebView2 Runtime and a Node.js version supported by the template. The React template declares Node.js ^20.19.0 || >=22.12.0.
  • Windows NativeAOT builds: Visual Studio C++ Build Tools and Windows SDK.
  • Linux: .NET 8 or later SDK, GTK3, WebKitGTK 4.1 and Node.js; NativeAOT additionally needs its native build dependencies. Build Linux distributions on a Linux host. See Linux X11 and Wayland for desktop-session requirements and platform limits.
  • macOS 12+: .NET 8 or later SDK and the template’s Node.js version. NativeAOT additionally needs Xcode Command Line Tools. WKWebView/AppKit are supplied by macOS. Use SDK and native package assets for the Mac’s architecture; see the macOS guide.
  • A feed containing matching versions of NetWiv.Cli, the SDK and native runtime packages. Ordinary React app development does not require Cargo.

The following example uses PowerShell. Replace $feed and $version with your actual package directory and version, then run from the parent directory in which you want to create the project. PACKAGE_VERSION is a placeholder, not an installable version.

Terminal window
$feed = 'C:\path\to\packages'
$version = 'PACKAGE_VERSION'
dotnet tool install --global NetWiv.Cli --version $version --add-source $feed
netwiv new MyNetWivApp --template react --source $feed
Set-Location MyNetWivApp
npm ci
npm run desktop:dev

If the global tool is already installed, use update instead of install. The generated JS/TS app includes vendor/netwiv-api; npm ci installs it as @netwiv/api with its privately bundled implementation; it does not install separate Tauri core or plugin guest packages. Generated command bindings and new desktop frontend calls use this facade. See frontend SDK usage and migration.

On Linux/macOS, the same PowerShell commands work with the corresponding feed path. For macOS Terminal (zsh), use:

Terminal window
feed='/absolute/path/to/packages'
version='PACKAGE_VERSION'
dotnet tool install --global NetWiv.Cli --version "$version" --add-source "$feed"
export PATH="$HOME/.dotnet/tools:$PATH"
netwiv new MyNetWivApp --template react --source "$feed"
cd MyNetWivApp
npm ci
npm run desktop:dev

netwiv new configures SDK references, the version in .config/dotnet-tools.json and the NuGet feed. See creation options to change the name, output directory or identifier.

desktop:dev restores the local CLI, generates bindings, starts Vite and launches the app. React edits update the frontend; C# edits regenerate bindings and restart the backend. Press Ctrl+C in the starting terminal to stop the session.

[Command] methods in src-netwiv/Program.cs implement the backend. .InvokeHandler("greet") selects the exposed command. React calls the generated function:

import { commands } from './generated/commands.js';
const result = await commands.greet({ name: 'NetWiv' });

src/generated/commands.js and commands.d.ts are generated during the build; do not edit them manually. When adding a JSON DTO, add JsonSerializable to the C# AppJsonContext. Unsupported custom serialization produces a build error rather than a guessed type.

TypeScript names such as GreetingOutput derive from C# type names. See the generator reference for serialization support and DTO naming. Permissions, command cancellation and resource ownership are described in the C# SDK.

The generated MyNetWivApp.sln includes the C# project and a .Frontend.esproj. Use the C# project as the IDE launch target. See using the generated app for build integration and development-server workflows. Actual Rider/Visual Studio solution loading and debugging validation remain incomplete.

Consumer apps use regular .NET by default. NativeAOT is optional: pass --aot to netwiv build, or -p:PublishAot=true to dotnet publish. See deployment modes for runtime requirements and existing-app migration.

Run from the project root:

Terminal window
npm run build
dotnet publish src-netwiv -c Release -r win-x64 --self-contained true -p:PublishAot=false -p:PublishTrimmed=false -o publish/win-x64
& ./publish/win-x64/MyNetWivApp.exe

Distribute the complete publish directory, including the executable and native DLL/SO/dylib files. On Linux, publish for linux-x64 and use that output’s executable. On macOS, publish for osx-arm64 on Apple Silicon. Keep the generated synchronous Main entry point: AppKit’s event loop must run on the process main thread.

For a macOS app bundle and disk image, use the CLI from the project root:

Terminal window
dotnet tool restore
dotnet tool run netwiv -- build --target osx-arm64 --bundles app,dmg --no-sign

The outputs are under target/osx-arm64/release/bundle/. --no-sign still renews the required ad-hoc executable signature; it does not provide Developer ID trust. Read the signing and distribution limits before distribution.

The deployed app does not need Node.js or Vite, but still requires the OS WebView dependencies. See support and validation for installer and signing coverage.


TAURI® is a trademark of The Tauri Programme within the Commons Conservancy.

NetWiv is an independent project. Its framework, plugins and templates are not affiliated with, endorsed by, or officially approved by The Tauri Programme within the Commons Conservancy.