docs/src/content/docs/contributing/codebase-layout.mdx
Wails v3 lives in a monorepo that contains the framework runtime, CLI,
examples, documentation, and build tool-chain.
This page walks through the directory structure that matters to anyone digging
into the internals.
wails/
├── v3/ # ⬅️ Everything specific to Wails v3 lives here
├── v2/ # Legacy v2 implementation (can be ignored for v3 work)
├── docs/ # Astro-powered v3 docs site (this page!)
├── website/ # Docusaurus v2 site and marketing pages (main site)
├── scripts/ # Misc helper scripts (e.g. sponsor image generator)
└── *.md # Project-wide meta files (CHANGELOG, LICENSE, …)
From here on, we zoom into the v3/ tree.
v3/ Rootv3/
├── cmd/ # Compilable commands (currently only the wails3 CLI)
├── internal/ # Framework implementation (not public API)
├── pkg/ # Public Go packages — the API surface
├── tasks/ # Taskfile-based release / generation utilities
├── wep/ # RFC-style proposals (Wails Enhancement Proposals)
├── tests/ # Integration test harness
├── go.mod
└── go.sum
Project templates ship under
internal/templates/(one folder per framework stack plusbase/,_common/, andios/). There is nov3/templates/directory at the top level.
pkg/ exposes what application developers importinternal/ contains how the magic is implementedcmd/wails3 drives project lifecycle & buildsEverything else supports those three pillars.
cmd/ – Commands| Path | Notes |
|---|---|
v3/cmd/wails3 | The CLI entrypoint. A tiny main.go delegates all logic to packages in internal/commands. |
internal/commands/* | Sub-commands (init, dev, build, doctor, …). Each lives in its own file for easy discoverability. |
internal/commands/task_wrapper.go | Bridges between CLI flags and the Taskfile build pipeline. |
The CLI owns:
init, template generation)dev, live-reload)build, package, platform wrappers)doctor)internal/ – The Engine Roominternal/
├── assetserver/ # Serving & embedding web assets
├── buildinfo/ # Reproducible build metadata
├── commands/ # CLI mechanics (see above)
├── runtime/ # Build-tag glue + embedded JS runtime sources
├── generator/ # Static analysis & binding generator
├── templates/ # Project templates (frontend stacks)
├── packager/ # nfpm wrapper used by `wails3 tool package`
├── capabilities/ # Host OS capability probing
├── dbus/ # Generic D-Bus helper
├── service/ # Service-template scaffolding (`wails3 generate service`)
└── ... # [other helper sub-packages: flags, hash, term, …]
| Package | Responsibility | Where It Connects |
|---|---|---|
runtime | Houses the small runtime{,_darwin,_linux,_windows,_android,_dev,_prod}.go build-tag glue plus the embedded JS runtime under runtime/desktop/. The actual per-OS window/clipboard/dialog/tray code lives in pkg/application/*_{darwin,linux,windows}.go. | Imported indirectly via pkg/application. |
assetserver | Dual-mode file server: | |
• Dev: serves from disk & proxies Vite (build_dev.go) | ||
• Prod: embeds assets via go:embed (build_production.go) | Initialized by pkg/application during startup. | |
generator | Parses Go source to build binding metadata which later produces TypeScript/JS stub files and event constants. Entry points: generator.Generate / generator.Generator over collect/ + render/. | Triggered by wails3 generate bindings. |
packager | nfpm wrapper used to emit Linux deb/rpm/archlinux artifacts (driven by myapp.DEB/.RPM/.ARCHLINUX nfpm configs under internal/commands/). | Invoked by wails3 tool package. macOS DMG / Windows MSIX live under internal/commands/{dmg,msix.go,webview2/}. |
Supporting utilities (eg. s/, hash/, flags/) keep internal concerns decoupled.
pkg/ – Public APIpkg/
├── application/ # Core API: App, windows, menus, dialogs, events, managers
├── events/ # Event constants (Common/Mac/Windows/Linux) + generator
├── services/ # Optional built-in services (notifications, kvstore, …)
├── doctor-ng/ # New-style `wails3 doctor-ng` checks
├── errs/ # Shared error types
├── icons/ # Default platform icons
├── mac/ # macOS-only helpers
└── w32/ # Windows Win32 helpers
There is no
pkg/runtime/,pkg/options/orpkg/menu/package. Window/menu options live alongsidepkg/application(e.g.WebviewWindowOptions,Menu,MenuItem), andassetserver/is underinternal/.
pkg/application bootstraps a Wails program:
func main() {
app := application.New(application.Options{
Name: "MyApp",
Assets: application.AssetOptions{
Handler: application.AssetFileServerFS(assetsFS),
},
})
window := app.Window.New()
window.SetTitle("Hello").SetSize(1024, 768)
_ = app.Run()
}
Under the hood it:
internal/runtime build-tag glue and per-OS code in pkg/application/internal/assetserver instanceinternal/templates/ – Scaffolding Blueprintsinternal/templates/ ships base templates (Go layout under base/,
_common/, ios/) and frontend skins (vanilla[-ts], react[-ts],
react-swc[-ts], lit[-ts], preact[-ts], qwik[-ts], solid[-ts],
svelte[-ts], sveltekit[-ts], vue[-ts]).
At wails3 init -t react, the CLI:
_common Go filesgo mod tidy (skippable with --skipgomodtidy)Editing templates does not affect existing apps, only future inits. The
public examples live under v3/examples/; they are not a substitute for the
automated test suites described in the contributor documentation.
tasks/ – Release AutomationTaskfiles wrap complex cross-compilation, version bumping, and changelog
generation. They are consumed programmatically by internal/commands/task.go
so the same logic powers CLI and CI.
direction: down
CLI: "wails3 CLI"
Generator: "internal/generator"
AssetDev: "assetserver (dev)"
Packager: "internal/packager"
AppRuntime: {
label: "App runtime"
ApplicationPkg: "pkg.application"
InternalRuntime: "internal.runtime"
OSAPIs: "OS APIs"
}
CLI -> Generator: "build / generate"
CLI -> AssetDev: "dev"
CLI -> Packager: "package"
Generator -> ApplicationPkg: "bindings"
ApplicationPkg -> InternalRuntime
InternalRuntime -> OSAPIs
ApplicationPkg -> AssetDev
CLI → generator → runtime forms the core path from source to running desktop app.
| Need to understand… | Look at… |
|---|---|
| Platform shims | pkg/application/*_darwin.go, *_linux.go, *_windows.go (window, clipboard, dialogs, systray, mainthread, events_common). Linux cgo: pkg/application/linux_cgo*.go. |
| Bridge protocol | pkg/application/messageprocessor*.go |
| Asset workflow | internal/assetserver/ (build_dev.go vs build_production.go) |
| Packaging flow | internal/commands/{appimage,msix,dot_desktop,dmg/}.go, internal/packager/ |
| Template engine | internal/templates/ (templates.Install, templates.GetDefaultTemplates) |
| Static analysis | internal/generator/{generate.go,collect/,render/} |
You now have a mental map of the repository.
Use it with ripgrep, your IDE’s “Go to File/Symbol”, and the example apps to
navigate deeper into any feature. Happy hacking!