1# Wails desktop apps
2
3Use Wails when the app is a desktop product, not merely because it has a web
4view. Go should own application logic; the frontend should render state and call
5bindings.
6
7Read `web.md` alongside this file for frontend CSS, accessibility, and semantic
8token guidance. Read `packaging.md` for every Wails setup; desktop apps need a
9packaging story from the start.
10
11## Build/tooling
12
13Start from the baseline in `mise.md`; keep its fmt, modernize, lint, vuln,
14race-enabled test, and check tasks. Then add Wails/frontend tools and tasks in
15mise, not Taskfile:
16
17```toml
18[tools]
19go = "latest"
20node = "22"
21"go:github.com/wailsapp/wails/v2/cmd/wails" = "latest"
22"go:golang.org/x/vuln/cmd/govulncheck" = "latest"
23golangci-lint = "latest"
24nfpm = "latest"
25
26[env]
27_.path = ["{{config_root}}/frontend/node_modules/.bin"]
28
29[vars]
30wails_build_args = "-tags webkit2_41 -trimpath"
31wails_ldflags = "-s -w"
32
33[tasks.dev]
34run = "wails dev -tags webkit2_41"
35
36[tasks.build]
37run = '''
38wails build {{vars.wails_build_args}} -ldflags "{{vars.wails_ldflags}}"
39'''
40```
41
42On Linux, include `-tags webkit2_41` for WebKitGTK 4.1. Missing it often fails
43late and unclearly.
44
45If the app exposes an About/version surface or release metadata, choose a
46project-owned version policy and inject the resolved value with `-X`, as in the
47CLI guidance.
48
49## Frontend stack
50
51Use the existing package manager if one exists. Ask before introducing a new
52one. Use Svelte 5 + TypeScript + Vite for Wails frontends. Tailwind and
53shadcn-svelte are optional project choices, not defaults to add blindly.
54
55Frontend checks usually split from backend checks:
56
57- backend: `golangci-lint fmt`, `golangci-lint run --fix`, `govulncheck`, tests
58- frontend: typecheck, lint, format, unit tests when present
59- combined: `mise run check`
60
61## Binding and event rules
62
63- Do not edit generated `frontend/wailsjs/` files.
64- Add Go methods/types to trigger Wails TypeScript generation.
65- Prefer explicit event names and typed payloads for async pipelines.
66- Go owns queues, cancellation, filesystem access, keyring access, and API
67 clients.
68- Svelte owns local rendering state and user interactions.
69
70## Errors
71
72For user-facing backend errors, send a structured shape the frontend can render:
73code, message, optional suggestion, optional details. Do not make the frontend
74parse arbitrary English when the backend can categorise the failure.
75
76## Packaging
77
78Read `packaging.md` for nFPM, desktop files, icons, and WebKit dependencies.