# Wails

> Guide Wails app setup, development, runtime APIs, and build workflows.

- Skill: `codegirl-007/wails` (Agent Skill)
- Install (CLI): `npx skillmds@latest add codegirl-007/wails`
- Raw SKILL.md: https://api.skillmd.com/api/skills/codegirl-007/wails/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: codegirl-007 (https://skillmd.com/u/codegirl-007)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/codegirl-007/wails

---


## What I do
- Set up and validate Wails prerequisites (Go, Node/NPM, platform deps)
- Create projects with `wails init` and pick templates/frameworks
- Run dev workflows with `wails dev` and explain live reload/browser mode
- Build production binaries with `wails build` and platform-specific flags
- Use runtime APIs (window, menu, dialog, events, log, browser, clipboard, screen, drag-and-drop)
- Configure `wails.json` and application options when needed
- Apply frontend script injection rules and external dev server setups
- Use guides for platform-specific packaging, signing, and troubleshooting
- Point to CLI, options, menus, project config, and runtime references

## When to use me
Use this skill for Wails app creation, local development, build issues, and CLI usage.
Ask clarifying questions if platform, template, or Wails version is unclear.

## Workflow
1. Identify the target OS and Wails version.
2. Confirm prerequisites: Go 1.21+, Node/NPM, and platform deps (xcode, WebView2, GTK/WebKit).
3. For new apps, choose a template and run `wails init -n <name> -t <template>`.
4. For dev, use `wails dev` and describe browser dev server at `http://localhost:34115`.
5. For builds, use `wails build`; on Linux with newer distros, add `-tags webkit2_41` when needed.
6. For runtime usage, use the Go runtime package `github.com/wailsapp/wails/v2/pkg/runtime` or `window.runtime` in JS.
7. For events, prefer `EventsOn`, `EventsOnce`, `EventsOnMultiple`, `EventsOff`, and `EventsEmit` to coordinate Go/JS.
8. If issues arise, run `wails doctor` and resolve missing deps.

## Architecture
- Wails is a Go app with a WebView frontend and a shared runtime library.
- Go methods are bound and exposed to JS with autogenerated `wailsjs` modules.
- Runtime methods are available in Go via `runtime` and in JS via `window.runtime`.

## Key commands
```bash
go install github.com/wailsapp/wails/v2/cmd/wails@latest
wails doctor
wails init -n myproject -t <template>
wails dev
wails build
```

## CLI highlights
- `wails init`: `-t` template (local or remote GitHub URL), `-n` name, `-d` dir, `-ide`.
- `wails dev`: `-assetdir`, `-wailsjsdir`, `-frontenddevserverurl`, `-browser`, `-loglevel`.
- `wails build`: `-platform`, `-tags`, `-obfuscated`, `-upx`, `-nsis`, `-devtools`, `-debug`.
- `wails generate module`: regenerate `wailsjs` without running dev.
- `wails generate template`: scaffold or derive templates from a frontend project.

## Runtime API map
- Events: `EventsOn`, `EventsOff`, `EventsOnce`, `EventsOnMultiple`, `EventsEmit`.
- Log: `LogTrace`, `LogDebug`, `LogInfo`, `LogWarning`, `LogError`, `LogFatal`, `LogSetLogLevel`.
- Window: title, size, position, fullscreen/maximise/minimise, show/hide, reload, exec JS.
- Dialog: open/save dialogs, message dialogs (Go only).
- Menu: set/update application menu (Go only).
- Browser: open URL in system browser.
- Clipboard: get/set text.
- Screen: list connected screens.
- Drag and Drop: `OnFileDrop`, `OnFileDropOff` (requires `EnableFileDrop`).

## Config and options
- `wails.json`: frontend dirs/build scripts, assetdir, reload dirs, dev server URL, output name, build tags, hooks, info/associations/protocols, bindings ts generation.
- App options: window size, frame, start state, background, always-on-top, menus, logging, callbacks, bindings, single-instance lock, drag-and-drop, default context menu, fraud detection.
- OS-specific options: Windows (WebView2, theme, backdrop, zoom), Mac (title bar, appearance, transparency, about), Linux (icons, GPU policy).

## Frontend integration
- Default script injection adds `/wails/ipc.js` and `/wails/runtime.js` to `index.html`.
- Use `<meta name="wails-options" content="noautoinject">` to opt out and inject manually.
- For external dev servers (example: CRA), configure `frontend:dev:watcher` and `frontend:dev:serverUrl`.

## Guides quick hits
- Angular: set `frontend:build`, `frontend:install`, `frontend:dev:watcher`, `frontend:dev:serverUrl` for `ng`.
- Routing: prefer hash-based routing (Vue hash, Angular useHash, React HashRouter, Svelte SPA router).
- Frameless: `Frameless: true`, use `--wails-draggable:drag` and `--wails-draggable:no-drag`.
- Overscroll: disable bounce with `html { height: 100%; overflow: hidden; }`.
- Dynamic assets: use `AssetServer.Handler` to serve fallback/dynamic content (watch Vite v5 warning).
- Obfuscation: `wails build -obfuscated` with optional `-garbleargs` and rely on `wailsjs` bindings.
- Single instance lock: `SingleInstanceLock` with `UniqueId` and `OnSecondInstanceLaunch`.
- Custom protocols and file associations: define `info.protocols` / `info.fileAssociations`, platform specifics.
- NSIS installer: install NSIS, build with `wails build -nsis`.
- Local dev on Wails master/PRs: `go install` from cloned repo and use `replace` in `go.mod`.
- Linux notes: distro package support, GStreamer plugin for media, NixOS font-size workaround.
- IDEs: `-ide vscode` or `-ide goland`; adjust VS Code tasks for frontend builds.
- Tutorials: Hello World and Dogs API show basic init/build/dev flows.

## Step-by-step playbooks
### Angular dev server
1. Set `frontend:build` to `npx ng build` and `frontend:install` to `npm install` in `wails.json`.
2. Add `frontend:dev:watcher` = `npx ng serve` and `frontend:dev:serverUrl` = `http://localhost:4200`.
3. Run `wails dev`.

### SvelteKit integration
1. `wails init -n <name> -t svelte`.
2. Delete `frontend/`, then `npx sv create frontend`.
3. In `wails.json` add `"wailsjsdir": "./frontend/src/lib"` and update package manager commands.
4. In `main.go` change `//go:embed all:frontend/dist` to `//go:embed all:frontend/build`.
5. Update `.gitignore` from `frontend/dist` to `frontend/build`.
6. In `frontend/`, install deps, replace adapter with `@sveltejs/adapter-static`.
7. Add `src/routes/+layout.ts` with `export const prerender = true` and `export const ssr = false`.
8. Run `wails dev`.

### Frameless window drag zones
1. Set `Frameless: true` in `options.App`.
2. Use `--wails-draggable:drag` on the container.
3. Use `--wails-draggable:no-drag` on interactive elements.
4. If CSS variables are unavailable, set `CSSDragProperty` and `CSSDragValue` in options.

### Dynamic assets
1. Configure `AssetServer.Handler` in `options.App`.
2. Serve missing assets or handle non-GET requests in the handler.
3. Avoid exposing arbitrary filesystem paths without authorization checks.

### Obfuscated builds
1. Build with `wails build -obfuscated` (optional `-garbleargs`).
2. Ensure frontend calls use generated `wailsjs` bindings (not `window.go` names).

### Single instance lock
1. Add `SingleInstanceLock` with a UUID `UniqueId`.
2. Use `OnSecondInstanceLaunch` to process args and bring window forward.
3. Treat second-instance data as untrusted input.

### Custom protocols
1. Add `info.protocols` in `wails.json` with `scheme`, `description`, `role`.
2. macOS: handle `Mac.OnUrlOpen`.
3. Windows: use NSIS installer; parse command-line args or use single instance lock.
4. Linux: create `.desktop` and mime entries via packaging (eg. nfpm).

### File associations
1. Add `info.fileAssociations` in `wails.json` with `ext`, `name`, `iconName`, `description`, `role`.
2. macOS: handle `Mac.OnFileOpen`.
3. Windows: use NSIS installer; parse args or use single instance lock.
4. Linux: create mime files, desktop entry, icons, and package scripts.

### NSIS installer
1. Install NSIS (scoop/winget/choco/brew).
2. Configure `build/windows/installer` info from `wails.json`.
3. Run `wails build -nsis` and use `build/bin` output.

### Local development against Wails master/PR
1. Clone `github.com/wailsapp/wails`, checkout target branch/PR.
2. `cd v2/cmd/wails && go install`.
3. Add `replace github.com/wailsapp/wails/v2 => <clonedir>/wails/v2` in your app `go.mod`.
4. Revert by reinstalling CLI from `@latest` and removing replace.

## Extended guides
### Code signing (Windows)
1. Base64-encode your .pfx/.p12 certificate and store as GitHub Actions secrets.
2. Build the app in CI, then use `signtool.exe` with `/fd sha256` and timestamp server.
3. If using Actions, ensure the signing step runs after `wails build`.

### Code signing (macOS)
1. Export your Apple Developer cert (.p12) and base64-encode it.
2. Use `gon` for signing + notarization; configure `build/darwin/gon-sign.json` and entitlements.
3. Import certs via `Apple-Actions/import-codesign-certs@v1`, then run `gon`.

### Mac App Store submission
1. Create App ID, certs, provisioning profile, and App Store Connect entry.
2. Add `build/darwin/entitlements.plist` with App Sandbox settings.
3. Build and sign with `wails build -platform darwin/universal`, then `codesign` and `productbuild`.
4. Upload via Transporter and attach build in App Store Connect.

### GitHub Actions cross-platform builds
1. Use a matrix for `linux/amd64`, `windows/amd64`, `darwin/universal`.
2. Cache node and Go deps; set `NODE_OPTIONS=--max-old-space-size=4096` if needed.
3. Run `wails build` (or `dAppServer/wails-build-action`) and upload `build/bin/*`.

### WebView2 strategies (Windows)
1. Use `wails build -webview2 <download|embed|browser|error>`.
2. For fixed runtime, set `WebviewBrowserPath` and bundle the runtime.
3. If running as admin, set `WebviewUserDataPath` to a shared location.

### Manual build process (decomposed)
1. Install frontend deps (unless `-s` or no `frontend:install`).
2. Build frontend (unless `-s` or no `frontend:build`).
3. Generate assets/icons (Windows uses winicon + winres).
4. Compile Go (`-tags dev` with `-gcflags` for dev, `-tags desktop,production` for prod).
5. Optional UPX compression (`-upx`).

### Templates
1. `wails generate template -name <name>` to scaffold a template.
2. For existing frontend, use `-frontend` path and update template files.
3. Test with `wails init -t <path>` then `wails build`.
4. Publish to GitHub and submit to Community Templates.

### IDE setup
1. Use `wails init -ide vscode` or `-ide goland`.
2. For VS Code, update `.vscode/tasks.json` to include frontend install/build steps.
3. For Vue + Vetur, add `vetur.config.js` pointing at `frontend/`.

### Troubleshooting highlights
1. White screen: verify `//go:embed all:frontend/dist` and assets in `frontend/dist`.
2. macOS blank screen: add `NSAllowsLocalNetworking` to `Info.plist`.
3. Windows icon cache: delete `%LOCALAPPDATA%/IconCache.db`.
4. Variadic args: pass array without spread to backend.
5. Stuck on bindings: ensure app exits after `wails.Run()`.
6. macOS compile errors: update Xcode CLI tools or switch toolchain path.
7. WebView2 missing: install correct architecture runtime.

### Routing patterns
1. Vue: `createWebHashHistory()`.
2. Angular: `RouterModule.forRoot(routes, { useHash: true })`.
3. React: `HashRouter`.
4. Svelte: `svelte-spa-router`.

### Mouse buttons (frameless apps)
1. Use `mousedown` listener and inspect `event.button` for button index.

### NixOS font-size bug
1. Add `XDG_DATA_DIRS` and `GIO_MODULE_DIR` to your `devShell` hook.

## Notes
- Wails generates Go bindings and TypeScript models for frontend calls.
- Project layout includes `main.go`, `frontend/`, `build/`, and `wails.json`.
- Runtime methods need a context from `OnStartup` or `OnDomReady`.
- Events can be emitted from Go or JavaScript with optional data payloads.
- Manual builds follow install -> build frontend -> generate assets -> compile -> optional UPX.
- Windows WebView2 can be handled via `-webview2` strategies or fixed runtime.
- Use guides for code signing, Mac App Store submission, and GitHub Actions builds.
- Use CLI, options, menus, project config, and runtime references for details.

