# Wails desktop apps

Read [baseline.md](baseline.md), [mise.md](mise.md), [web.md](web.md),
[packaging.md](packaging.md), [testing.md](testing.md), and
[preferred-libraries.md](preferred-libraries.md) before applying these Wails
specifics.

Use Wails when the app is a desktop product, not merely because it has a web
view. Go should own application logic; the frontend should render state and call
bindings.

## Build/tooling

Start from the baseline in [mise.md](mise.md); keep its fmt, modernize, lint,
vuln, race-enabled test, and check tasks. Then add Wails/frontend tools and
tasks in mise, not Taskfile:

```toml
[tools]
go = "latest"
node = "22"
"go:github.com/wailsapp/wails/v2/cmd/wails" = "latest"
"go:golang.org/x/vuln/cmd/govulncheck" = "latest"
golangci-lint = "latest"
nfpm = "latest"

[env]
_.path = ["{{config_root}}/frontend/node_modules/.bin"]

[vars]
wails_build_args = "-tags webkit2_41 -trimpath"
wails_ldflags = "-s -w"

[tasks.dev]
run = "wails dev -tags webkit2_41"

[tasks.build]
run = '''
wails build {{vars.wails_build_args}} -ldflags "{{vars.wails_ldflags}}"
'''
```

On Linux, include `-tags webkit2_41` for WebKitGTK 4.1. Missing it often fails
late and unclearly.

If the app exposes an About/version surface or release metadata, choose a
project-owned version policy and inject the resolved value with `-X`, as in the
CLI guidance.

## Frontend stack

Use the existing package manager if one exists. Ask before introducing a new one.
Use Svelte 5 + TypeScript + Vite for Wails frontends. Tailwind and shadcn-svelte
are optional project choices, not defaults to add blindly.

Frontend checks usually split from backend checks:

- backend: `golangci-lint fmt`, `golangci-lint run --fix`, `govulncheck`, tests
- frontend: typecheck, lint, format, unit tests when present
- combined: `mise run check`

## Binding and event rules

- Do not edit generated `frontend/wailsjs/` files.
- Add Go methods/types to trigger Wails TypeScript generation.
- Prefer explicit event names and typed payloads for async pipelines.
- Go owns queues, cancellation, filesystem access, keyring access, and API
  clients.
- Svelte owns local rendering state and user interactions.

## Errors

For user-facing backend errors, send a structured shape the frontend can render:
code, message, optional suggestion, optional details. Do not make the frontend
parse arbitrary English when the backend can categorise the failure.

## Packaging

Read [packaging.md](packaging.md) for nFPM, desktop files, icons, and WebKit
dependencies.
