Skip to content

Building from source code

Wesley edited this page Aug 24, 2026 · 16 revisions

Building from source

Normal users should install signed builds from Releases. Build from source if you are developing, auditing, or testing local changes.

Stack

Area Tooling
Backend Go, version from go.mod
Desktop shell Wails v3
Frontend Svelte, Vite, TypeScript
Task runner Task, bundled inside the Wails CLI

The production build embeds frontend/dist, Platforms.json, GameStats.json, the app icon, and updater-key.pub.

Prerequisites

  • Go, matching go.mod
  • Node.js LTS
  • pnpm, via Corepack or npm i -g pnpm
  • Wails v3 CLI, via go install github.com/wailsapp/wails/v3/cmd/wails3@latest
  • Optionally Task, via go install github.com/go-task/task/v3/cmd/task@latest

Windows builds also need WebView2 Runtime to run. Visual Studio Build Tools may be needed for CGO paths.

Running project tasks

Every build command on this wiki is a Task target, and the Wails CLI has Task built in, so wails3 task <name> always works once wails3 is installed. That is why the commands are written that way.

Installing Task separately is optional and only lets you drop the prefix - task dev and wails3 task dev run the same thing. wails3 task --list prints every target the project defines.

Development

From the repo root:

cd frontend
pnpm install
cd ..
wails3 task dev

wails3 task dev runs wails3 dev -config ./build/config.yml -port 9245. Set WAILS_VITE_PORT to use another port.

Build commands

Command What it does
wails3 task build Production build for the current OS
wails3 task windows:build Windows exe
wails3 task linux:build Linux binary
wails3 task darwin:build macOS binary
wails3 task package OS package or installer
wails3 task test Go tests and frontend tests

Windows output: bin/TcNo-Acc-Switcher.exe.

Unix output: bin/TcNo-Acc-Switcher.

Cross-compile Windows from Linux/macOS:

wails3 task setup:docker
wails3 task windows:build

Linux and macOS need CGO and their own toolchains: Building on Linux covers building, installing, running and debugging there, and cross-compiling both targets from Windows.

Project layout

main.go                 Wails app setup
Platforms.json          Platform catalog
GameStats.json          Game-stat definitions
internal/platform/      Settings, catalog updates, user data
internal/steam/         Steam switcher
internal/basic/         Templated platform switcher
internal/cli/           CLI and protocol parsing
internal/shortcuts/     Shortcut scanning
internal/tray/          System tray
frontend/src/pages/     Svelte pages
frontend/src/styles/    Themes and shared styles
build/                  Wails, NSIS, nfpm, and OS build config

Test commands

wails3 task test
go test -race -count=1 ./internal/... ./cmd/...
cd frontend && pnpm run test
cd frontend && pnpm run check

Environment variables

Running the app

wails3 task dev cannot forward arguments to the app, so anything a CLI flag would do has to arrive as an environment variable instead.

Variable Effect
WAILS_VITE_PORT Vite dev-server port. wails3 task dev defaults to 9245.
TCNO_ALLOW_STEAMGUARD_CAPTURE Lets Steam Guard windows be screenshotted and recorded, so you can capture the feature while working on it. Equivalent to --allow-steamguard-capture.
TCNO_STEAMGUARD_CONFIRMATION_DUMP Writes each opened confirmation's payload to {UserData}\SteamGuard\diagnostics\.

Both TCNO_ switches count as set for any value other than empty, 0 or false, are read once at startup, and are described in full under Environment variables.

$env:TCNO_ALLOW_STEAMGUARD_CAPTURE=1; wails3 task dev

Live probes and fixtures

A few tests talk to Steam or read a captured page instead of a synthetic fixture. They are all opt-in and skip when their variable is unset, so an ordinary go test ./internal/... never touches the network or your vault.

Variable Used by
TCNO_GCPD_SPIKE=1 Enables TestGCPDSpike — a live authenticated GCPD read
TCNO_OWNED_SPIKE=1 Enables TestOwnedAppsSpike — a live owned-apps read
TCNO_VAULT_PASSWORD Vault password, required by both probes
TCNO_DATA_ROOT Where the vault lives, when it is not under the default data root. Portable installs are found by walking up from the package directory, so this is usually unnecessary
TCNO_SPIKE_LIST=1 List the vault's accounts and stop, instead of probing one
TCNO_SPIKE_ACCOUNT / TCNO_SPIKE_STEAMID Pick one account out of several, by login name or SteamID64
TCNO_SPIKE_DUMP / TCNO_SPIKE_DUMP_DIR Keep the response bodies for later parsing
TCNO_GCPD_FIXTURE Path to a dumped GCPD .html; runs the cooldown parser over a page Steam actually served
TCNO_STORE_FIXTURE Path to a dumped store .html; same, for the Prime status parser
$env:TCNO_GCPD_SPIKE=1; $env:TCNO_VAULT_PASSWORD='...'; go test ./internal/steamguard/ -run TestGCPDSpike -v

The probes use a real session against a real account. They are for confirming what Steam serves today, not for routine test runs — a stored token is short-lived, so they deliberately probe one account rather than sweeping the vault.

Local platform and stat edits

Edit the repo files and rebuild, or test without rebuilding through user data overlays:

  • {UserData}/Platforms.custom.json
  • {UserData}/GameStats.custom.json

Release signing

Official Windows releases are signed through SignPath. Local builds are unsigned unless you configure your own signing flow.

Clone this wiki locally