create-wails-ui
v0.2.0
Published
Scaffolder for Wails 3 desktop apps: React + Vite + TypeScript + Tailwind + shadcn/ui with desktop defaults, interface presets, batteries and an optional OpenCode desktopizer
Maintainers
Readme
create-wails-ui
Scaffolder for Wails 3 desktop apps: React + Vite + TypeScript + Tailwind CSS + shadcn/ui, with desktop defaults, task-oriented interface presets and optional batteries.
bunx create-wails-ui@latest my-appThen:
cd my-app
wails3 dev # live development (vite + hot backend rebuild)
wails3 build # builds bin/my-appInstallation
create-wails-ui ships on npm. Node ≥ 20 or
Bun runs the CLI itself; go, wails3 and a package manager must also be on PATH when you
scaffold, because create drives them (wails3 init, the upstream shadcn CLI, wails3 build).
See Requirements for the full table, including the Linux webview stack.
Run it without installing anything:
bunx create-wails-ui@latest my-app
npx create-wails-ui@latest my-appInstall it once when you use it often:
npm install -g create-wails-ui # or: bun add -g create-wails-ui
create-wails-ui my-appTo work on the scaffolder itself, use a checkout of this repo:
bun install && bun run build
node dist/cli.js my-appEvery form takes the same commands and flags.
Requirements
| Tool | Why |
| --- | --- |
| Go ≥ 1.25 | Wails 3 toolchain and app build |
| wails3 (go install github.com/wailsapp/wails/v3/cmd/wails3@latest) | upstream scaffold, bindings, dev/build tasks |
| Node ≥ 20 or Bun | frontend toolchain (Bun is preferred when present) |
| Linux: GTK3 + WebKit2GTK 4.1 or GTK4 + WebKitGTK 6.0 | webview stack — see note below |
On Linux the generated
Taskfile.ymlpinsEXTRA_TAGS: "gtk3"automatically whenwails3 tool capabilitiesreports GTK3 as recommended (host has WebKit2GTK 4.1 but no WebKitGTK 6.0), so plainwails3 build/wails3 devwork without extra flags.
CLI
create-wails-ui <name> [options] Create a project
create-wails-ui list Batteries + installed state
create-wails-ui add <battery> Install a battery (idempotent)
create-wails-ui remove <battery> Remove a battery (idempotent)
create-wails-ui update <battery> Re-sync a battery's owned files
-i, --interface <preset> blank | utility | tool | workspace | wizard (default: blank)
--debug-panel dev-only debug panel, Ctrl/Cmd+D (default: on)
--starter starter content using the Go binding (default: off)
--workflow GitHub Actions release workflow (default: on)
--service-example second example Go service (default: off)
--desktopize desktopizer: /desktopize commands + skill (default: off)
--skip-build skip the final wails3 build verification (testing/CI)
-y, --yes non-interactive, accept defaultsWithout --skip-build, create finishes by running wails3 build and asserting that
bindings, the frontend bundle and the Go binary were really produced (spec §5).
Interactive mode prompts for the same choices when running in a TTY.
bunx create-wails-ui my-app \
--interface utility \
--debug-panel \
--workflow \
--yesInterface presets
Presets are compositions, not applications. They share one set of shadcn primitives
(button card input label separator badge progress textarea) and only the desktop patterns
their task needs — nothing is duplicated between presets.
| Preset | Shape | Patterns |
| --- | --- | --- |
| blank | clean root area, no imposed layout | — |
| utility | title · focused content · one primary action | app-shell |
| tool | toolbar · preview · inspector | app-shell, toolbar, inspector, split-pane |
| workspace | toolbar · explorer · workspace · inspector · status bar | app-shell, toolbar, inspector, split-pane, statusbar |
| wizard | progress · step content · Back/Continue | app-shell, wizard-shell |
Batteries
Small optional additions, safe to add/remove repeatedly (idempotent, marker-based patches):
| Battery | What it does |
| --- | --- |
| debug-panel | Dev-only diagnostics overlay on Ctrl/Cmd + D (app, route, window, runtime, bindings, events, screens, theme, system, build). Stripped from production bundles. |
| starter | A card calling GreetService.Greet through the generated Go → TypeScript binding |
| workflow | .github/workflows/release.yml — wails3 build on Linux/macOS/Windows for v* tags |
| service-example | Second Go service registered in main.go, exposed via bindings after the next build |
| desktopize | OpenCode layer to desktopize existing apps: /desktopize, /desktop-audit, /desktop-verify commands + the wails-desktopize skill (deterministic scripts and a thin desktop-source tool) |
Desktopize (optional battery)
--desktopize (or create-wails-ui add desktopize) prepares a generated project so
OpenCode can turn an existing application into this Wails desktop app:
bunx create-wails-ui@latest my-dsh --desktopize
cd my-dsh && opencode
> /desktopize https://github.com/deepseek-ai/deepseek-harnessSources can be a local folder, a Git repository or a web URL. The battery installs
.opencode/ assets only — no runtime code, no proprietary manifest:
| Command | What it does |
| --- | --- |
| /desktopize <source> | acquire → inspect → choose a strategy → adapt minimally → build → verify → report |
| /desktop-audit <source> | read-only analysis (stack, web surface, recommended strategy, risks, effort) |
| /desktop-verify | run the layered verification contract only (no redesign) |
Deterministic work is scripted in
.opencode/skills/wails-desktopize/scripts/ (inspect, detect, acquire,
run-command, probe-http, verify, report — dependency-free TypeScript,
runnable outside OpenCode too). The agent only decides what rules cannot:
| Strategy | When |
| --- | --- |
| embed | build produces self-contained static assets (SPA/static export) |
| adopt | the existing frontend becomes the Wails frontend (most invasive — agent decision) |
| sidecar | the UI needs its own server; Wails supervises it and navigates to its URL |
| remote | the source is a web URL wrapped in a Wails window |
Human intervention is reserved for real gates (destructive changes to the original source, credentials, elevated privileges, a genuine functional choice, distribution changes, irreversible external actions). Reversible low-risk work — installs, builds, tests, scaffold-file edits — runs without asking.
Not in scope (added only when a real need appears): code signing/notarization, auto-update, plugin marketplace, remote desktopization service, build farm, embedded browser engine, a generalized process orchestrator, automatic Docker migration, mobile, or a universal Electron→Wails converter.
What is upstream vs. what this tool owns
- Upstream:
wails3 init -t react(scaffold, build/task system, bindings),shadcnCLI (components, tokens, aliases), Vite/React/Tailwind, Wails runtime. - This tool: a small deterministic patch layer (desktop defaults, window sizing, external link guard, package-manager/gtk3 host pinning), the preset/pattern compositions, the batteries, and the patch engine that guarantees idempotent add/remove.
See ARCHITECTURE.md for the flow and extension rules.
Development
bun install
bun run typecheck # tsc --noEmit over src/ + the desktopize skill scripts
bun test tests/patches.test.ts tests/battery-ops.test.ts # fast unit layer (<1s)
bun test tests/desktopize-*.test.ts # desktopizer: inspect/detect/acquire/verify/report
bun test # default suite (~3 min): units + 1 full scaffold cycle +
# interactive TTY prompts + 5 presets with real tsc+vite builds
CWU_FULL_SMOKE=1 bun test tests/presets.test.ts # release matrix: full wails3 build,
# bindings and binary assertions for every preset (~4 min extra)
(cd tests/fixtures/sidecar-supervisor && go test ./...) # sidecar supervisor referenceThe integration tests create real projects under /tmp/opencode/create-wails-ui-tests,
run wails3 build (deps → bindings → typecheck → frontend build → Go build) and assert
battery idempotency and production stripping of the debug panel.
License
MIT
