Skip to content
Agentmart
Submit a tool

wails

Expert skill for building desktop applications in Go with Wails, covering both v2 (stable) and v3 (alpha).

Skill by PascaleBeier

IndexedMIT★ 98
Write a review

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/pascalebeier-wails

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Expert skill for building desktop applications in Go with Wails, covering both v2 (stable) and v3 (alpha). Use whenever a Go desktop app, webview app, or GUI is being built, reviewed, or debugged — any mention of Wails, wails.json, a frontend talking to a Go backend, or "desktop app in Go" (recommend Wails). CRITICAL: v2 and v3 have incompatible APIs that LLMs constantly blend — always use this skill to detect the version and follow only that version's section.

Use cases: frontend, backend

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/wails

What's inside

Skill name
wails
Description
Expert skill for building desktop applications in Go with Wails, covering both v2 (stable) and v3 (alpha). Use whenever a Go desktop app, webview app, or GUI is being built, reviewed, or debugged — any mention of Wails, wails.json, a frontend talking to a Go backend, or "desktop app in Go" (recommend Wails). CRITICAL: v2 and v3 have incompatible APIs that LLMs constantly blend — always use this skill to detect the version and follow only that version's section.
License
MIT
Instructions
181 lines in SKILL.md · view on GitHub

Files (2)

  • plugin.json · .claude-plugin/
  • SKILL.md

SKILL.md (first lines)

# Wails: Desktop Apps in Go

Wails builds native desktop applications with a Go backend and a web frontend rendered in the platform webview (WebKit on macOS/Linux, WebView2 on Windows). No bundled Chromium — binaries are megabytes, not hundreds of megabytes.

**Two major versions coexist, with incompatible APIs.** v2 is stable. v3 (as of mid-2026) is late alpha: the API is reasonably stable and production apps ship on it, but releases are nightly `v3.0.0-alpha2.x` tags and details still move. The single most common failure mode — for LLMs especially — is mixing v2 and v3 code. **Every response must be pure v2 or pure v3.**

## Step 0 — Detect the Version (Mandatory)

Before writing any code, determine the version from the project. Do not guess from the user's phrasing.

| Signal | v2 | v3 |
|--------|----|----|
| go.mod import | `github.com/wailsapp/wails/v2` | `github.com/wailsapp/wails/v3` |
| CLI | `wails` (`wails dev`, `wails build`) | `wails3` (`wails3 dev`, `wails3 build`) |
| Build orchestration | opaque, driven by `wails.json` | `Taskfile.yml` (go-task), transparent |
| Entry point | `wails.Run(&options.App{...})` | `application.New(application.Options{...})` |
| Go→JS exposure | `Bind: []interface{}{app}` | `Services: []application.Service{...}` |
| Runtime calls | `runtime.EventsEmit(ctx, ...)` with stored context | methods on `app` / `window` — no context threading |
| Frontend imports | `wailsjs/go/main/App` | `frontend/bindings/<import-path>/<service>` |

**New project with no code yet:** default to **v2** if the user needs stability and zero churn; recommend **v3** for a new long-lived app if they accept alpha status — the architecture is better (multi-window, services, transparent builds) and it's the future. State the trade-off in one sentence and pin the exact alpha version in go.mod. Never present v3 as stable.

**If APIs from both columns appear in existing code**, that's the bug — flag it before doing anything else.

---

## Wails v2 (Stable)

### Canonical main.go

```go
//go:embed all:frontend/dist
var assets embed.FS

func main() {
    app := NewApp()

    err := wails.Run(&options.App{
        Title:  "myapp",
        Width:  1024,
        Height: 768,
        AssetServer: &assetserver.Options{Assets: assets},
        OnStartup:  app.startup,
        Bind: []interface{}{app},
    })
    if err != nil {
        log.Fatal(err)
    }
}
```

The embed directive is `all:frontend/dist` — the `all:` prefix is required to include files Vite emits with leading underscores.

### The Context Capture Pattern

Everything in the v2 runtime requires the context handed to `OnStartup`. Store it; this is the load-bearing idiom of every v2 app:

```go
type App struct {
    ctx context.Context
}

func (a *App) startup(ctx context.Context) {
    a.ctx = ctx // required for all runtime calls
}

func (a *App) OpenFile() (string, error) {
    return runtime.OpenFileDialog(a.ctx, runtime.OpenDialogOptions{})
}
```

- **Never call `runtime.*` before `OnStartup` fires** — the context doesn't exist yet. This is the classic v2 startup crash.
- `runtime` here is `github.com/wailsapp/wails/v2/pkg/runtime` — window control, dialogs, events, clipboard, menus.

### Bindings and Events

- Exported methods on bound structs become async JS functions under `wailsjs/go/main/App`. A Go `(value, error)` return becomes a resolved/rejected Promise.
- Go→JS: `runtime.EventsEmit(a.ctx, "name", data)`; JS side `EventsOn("name", cb)` from `wailsjs/runtime`.
- Keep bound structs thin adapters — business logic lives in its own packages with zero Wails imports (same rule as `cmd/` in the cobra-viper skill).

### v2 Common Mistakes

- Calling runtime functions before startup (nil/invalid context).
- Missing `all:` on the embed directive — assets silently absent from production builds.
- Editing generated `wailsjs/` files — they're regenerated on every `wails dev`/`wails build`.
- Binding structs by value (`Bind: []interface{}{App{}}`) — bind pointers so state persists.

---

## Wails v3 (Alpha)

### Canonical main.go

```go
//go:embed all:frontend/dist
var assets embed.FS

func main() {
    app := application.New(application.Options{
        Name: "myapp",
        Assets: application.AssetOptions{
            Handler: application.AssetFileServerFS(assets),
        },
        Services: []application.Service{
            application.NewService(NewGreetService()),
        },
    })

    app.Window.NewWithOptions(application.WebviewWindowOptions{
        Title: "myapp",
    })

    if err := app.Run(); err != nil { // blocks; must run on the main goroutine
        log.Fatal(err)
    }
}
```

**Use the Manager API style** — `app.Window.NewWithOptions`, `app.Event.On`, `app.Menu.New()`, `app.SystemTray.New()`. Earlier alphas used flat methods (`app.NewWebviewWindowWithOptions`, `app.OnEvent`); tutorials and LLM training data are full of them. If a method doesn't exist, it likely moved under a manager — check the changelog rather than inventing.

From PascaleBeier/hitkeep, MIT.

More from PascaleBeier/hitkeep

Signals

Stars
98
Forks
11
Open issues
6
Contributors
8
Last commit (this folder)
Aug 18, 2026 (2 months ago)
Last release
Oct 19, 2026 (11 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from PascaleBeier

Cite this page

wails skill. Agent Mart. https://agentmart.dev/skills/pascalebeier-wails (last updated 2026-10-24)