223 lines
5.9 KiB
Text
223 lines
5.9 KiB
Text
|
|
---
|
|||
|
|
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/<id>/`.
|
|||
|
|
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/<id>/**` | 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 <id>` 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!
|