--- title: Template System description: How Wails v3 scaffolds new projects, how templates are organised, and how to build your own. sidebar: order: 7 --- Wails ships with a **template system** that lets `wails3 init` produce a ready-to-run project for **any** modern frontend stack (React, Svelte, Vue, Solid, Vanilla JS …). This page covers: 1. Template directory layout 2. How the CLI chooses & renders templates 3. Creating a new template step-by-step 4. Updating or overriding existing templates 5. Troubleshooting and best practices --- ## 1. Where Templates Live ``` v3/ └── internal/templates/ ├── _common/ # Files copied into EVERY project (main.go, .gitignore) ├── base/ # Backend-only “plain Go” template ├── react/ # React + Vite ├── react-ts/ ├── svelte/ ├── vue/ ├── ... (others) └── templates.go # Registry + helper functions ``` * **`_common/`** – universal boilerplate (Go modules, Taskfile, README stub, VS Code settings). * **Framework folders** – contain **frontend/** and any stack-specific config. * Folder names match the **template ID** you pass to the CLI (`wails3 init -t react-ts`). > The whole directory is compiled into the CLI binary via `go:embed`, so users > can scaffold projects offline. --- ## 2. How `wails3 init` Uses Templates Call chain: ``` cmd/wails3/init.go │ ▼ internal/commands/init.go ← parses flags, target dir │ ▼ internal/templates.Load() ← templates.go │ ▼ Template.CopyTo(dest) ← filesystem copy + text substitutions ``` ### Substitutions Placeholders wrapped in `{{ }}` are replaced at copy time: | Placeholder | Example | Source | |-------------|---------|--------| | `{{ProjectName}}` | `myapp` | CLI flag/dir name | | `{{ModulePath}}` | `github.com/me/myapp` | if `--module` provided | | `{{WailsVersion}}`| `v3.0.0` | compiled constant | You can add **any** placeholder; just ensure it gets a value in `internal/commands/init.go`. ### Post-Copy Hooks Each template may ship a **Taskfile** with a `deps` task. After copy, the CLI runs: ``` task --taskfile Taskfile.yml deps ``` Typical work: * `go mod tidy` * `npm install` * git init & initial commit (optional) Hook behaviour defined in `_common/Taskfile.yml` but override-able per template. --- ## 3. Creating a New Template > Example: Add **Qwik-TS** template ### 3.1 Folder & ID ``` internal/templates/qwik-ts/ ``` The folder name = template ID. Keep it **kebab-case**. ### 3.2 Minimal File Set ``` qwik-ts/ ├── README.md # Shown in CLI with -list ├── frontend/ # Your web project │ ├── src/ │ ├── package.json │ └── vite.config.ts ├── Taskfile.yml # deps & dev tasks └── go/ # Optional extra Go files ``` Start by copying `react-ts` and pruning files. ### 3.3 Update Placeholders Search/replace: * `myapp` → `{{ProjectName}}` * `github.com/you/myapp` → `{{ModulePath}}` ### 3.4 Register (optional) If the folder exists, **templates.go auto-detects it** via `embed`. Only add explicit code if you need **custom validation**: ```go func (t *Template) Validate() error { // check Node ≥ 20 for this template } ``` ### 3.5 Test ```bash wails3 init -n demo -t qwik-ts cd demo wails3 dev ``` Ensure: * Dev server starts * `wailsjs` bindings generate * Hot-reload works --- ## 4. Modifying Existing Templates 1. Edit files under `internal/templates//`. 2. Run `go generate ./v3/...` **or** just `go run ./v3/cmd/wails3 –help`; the embed directive recompiles automatically. 3. Bump any **dependency versions** in `frontend/package.json` & `Taskfile.yml`. 4. Update `README.md` inside the template — users see it via `wails3 init -t react --help`. ### Common Tweaks | Task | Where | |------|-------| | Change dev server port | `frontend/Taskfile.yml` (`vite dev --port {{DevPort}}`) | | Add environment variables | same Taskfile or `.env` | | Replace JS package manager | Switch `npm` → `pnpm` in Taskfile | --- ## 5. Template Authoring Tips * **Keep frontend generic** – avoid referencing Wails-specific globals; runtime is injected automatically. * **No compiled artefacts** – exclude `node_modules`, `dist`, `.DS_Store` via `.tmplignore`. * **Document prerequisites** – Node version, extra CLI tools, etc. * **Avoid breaking changes** – create a *new* template ID if overhaul is big. --- ## 6. Troubleshooting | Symptom | Cause | Fix | |---------|-------|-----| | `unknown template id` | Folder name mismatch | Check `wails3 init -list` | | Placeholders not replaced | Missing entry in `Data` map | Edit `internal/commands/init.go` | | Dev server opens blank page | Wrong `DevPort` env | Ensure Taskfile echoes port to stdout | | Frontend fails to build in prod | Forgotten vite `base` path | Set `base: "./"` in `vite.config.ts` | Add `--verbose` to `wails3 init` to print every copied file and substitution. --- ## 7. Key Source File Map | File | Responsibility | |------|----------------| | `internal/templates/templates.go` | Embeds template FS, returns `[]Template` | | `internal/templates//**` | Actual template content | | `internal/commands/init.go` | CLI glue: picks template, fills placeholders | | `internal/commands/generate_template.go` | Utility to *export* a live project back into a template (handy for updates) | --- ## 8. Recap * Templates live in **`internal/templates/`** and are baked into the CLI. * `wails3 init -t ` copies `_common` + selected template, performs substitutions, then runs a **deps** Taskfile hook. * Creating a template is as simple as **making a folder**, adding files, and using placeholders. * The system is **extensible** and **self-contained** — perfect for sharing custom stacks with your team or the community. Happy templating!