Improve documentation clarity and reduce cognitive load

- Update Go version requirement from 1.23+ to 1.25+ across all docs
- Update installation.mdx with links to official installers and actual wails3 doctor output
- Revert first-app.mdx to simple greet app tutorial (10 mins)
- Move TODO app to dedicated tutorial at tutorials/todo-vanilla.mdx (20 mins)
- Simplify next-steps.mdx: remove 50+ links, focus on essential paths
- Simplify tutorials/overview.mdx: remove emojis, cards, verbose sections
- Add Windows 11 Dev Drive performance tips to installation guides
- Fix auto-rebuild documentation (Go code auto-rebuilds, no manual restart needed)
- Remove "What You've Learned" section emojis
- Convert cards to bullet points throughout for better readability

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Lea Anthony 2025-11-15 08:42:09 +11:00
commit 0c88fb217c
20 changed files with 3306 additions and 2867 deletions

View file

@ -9,12 +9,16 @@ vars:
tasks:
setup:
summary: Setup the project
summary: Setup the project (including D2 diagram tool)
preconditions:
- sh: '{{.PKG_MANAGER}} --version'
msg: "Looks like {{.PKG_MANAGER}} isn't installed."
- sh: 'go version'
msg: "Go is not installed. Install from https://go.dev/dl/"
cmds:
- '{{.PKG_MANAGER}} install'
- go install oss.terrastruct.com/d2@latest
- echo "✓ Setup complete. D2 installed to $(go env GOPATH)/bin/d2"
dev:
summary: Run the dev server

View file

@ -76,7 +76,6 @@ export default defineConfig({
{
label: "Quick Start",
collapsed: false,
badge: { text: "Start Here", variant: "success" },
items: [
{ label: "Why Wails?", link: "/quick-start/why-wails" },
{ label: "Installation", link: "/quick-start/installation" },
@ -385,10 +384,17 @@ export default defineConfig({
{ label: "Templates", link: "/community/templates" },
{
label: "Showcase",
autogenerate: {
directory: "community/showcase",
collapsed: true,
},
collapsed: true,
items: [
{ label: "Overview", link: "/community/showcase" },
{
label: "Applications",
autogenerate: {
directory: "community/showcase",
collapsed: true,
},
},
],
},
],
},

3239
docs/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-d2-version="v0.7.1" preserveAspectRatio="xMinYMin meet" viewBox="0 0 1343 1689"><svg class="d2-2151679045 d2-svg" width="1343" height="1689" viewBox="-101 -101 1343 1689"><rect x="-101.000000" y="-101.000000" width="1343.000000" height="1689.000000" rx="0.000000" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-d2-version="v0.7.1-HEAD" preserveAspectRatio="xMinYMin meet" viewBox="0 0 1343 1689"><svg class="d2-2151679045 d2-svg" width="1343" height="1689" viewBox="-101 -101 1343 1689"><rect x="-101.000000" y="-101.000000" width="1343.000000" height="1689.000000" rx="0.000000" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
.d2-2151679045 .text-bold {
font-family: "d2-2151679045-font-bold";
}

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Before After
Before After

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-d2-version="v0.7.1" preserveAspectRatio="xMinYMin meet" viewBox="0 0 1744 642"><svg class="d2-1050497775 d2-svg" width="1744" height="642" viewBox="-100 -101 1744 642"><rect x="-100.000000" y="-101.000000" width="1744.000000" height="642.000000" rx="0.000000" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-d2-version="v0.7.1-HEAD" preserveAspectRatio="xMinYMin meet" viewBox="0 0 1744 642"><svg class="d2-1050497775 d2-svg" width="1744" height="642" viewBox="-100 -101 1744 642"><rect x="-100.000000" y="-101.000000" width="1744.000000" height="642.000000" rx="0.000000" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
.d2-1050497775 .text-bold {
font-family: "d2-1050497775-font-bold";
}

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Before After
Before After

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Before After
Before After

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-d2-version="v0.7.1" preserveAspectRatio="xMinYMin meet" viewBox="0 0 690 1254"><svg class="d2-2857426310 d2-svg" width="690" height="1254" viewBox="-91 -101 690 1254"><rect x="-91.000000" y="-101.000000" width="690.000000" height="1254.000000" rx="0.000000" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
<?xml version="1.0" encoding="utf-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-d2-version="v0.7.1-HEAD" preserveAspectRatio="xMinYMin meet" viewBox="0 0 690 1254"><svg class="d2-2857426310 d2-svg" width="690" height="1254" viewBox="-91 -101 690 1254"><rect x="-91.000000" y="-101.000000" width="690.000000" height="1254.000000" rx="0.000000" class=" fill-N7" stroke-width="0" /><style type="text/css"><![CDATA[
.d2-2857426310 .text {
font-family: "d2-2857426310-font-regular";
}

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Before After
Before After

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Before After
Before After

View file

@ -119,7 +119,7 @@ diagrams, and references to the relevant source files.
---
:::note
Prerequisites: You should be comfortable with **Go 1.23+**, basic TypeScript,
Prerequisites: You should be comfortable with **Go 1.25+**, basic TypeScript,
and modern frontend build tools. If you are new to Go, consider skimming the
official tour first.
:::

View file

@ -133,7 +133,7 @@ Key features:
* **Matrix** over `os: [ubuntu-latest, windows-latest, macos-latest]`
* Caches Go & npm deps for speed
* Steps:
1. `setup-go` @ 1.23
1. `setup-go` @ 1.25
2. `go vet ./...`
3. `go test ./... -v -coverprofile=cover.out`
4. Build CLI + sample app (`wails3 build -skip-package`)

View file

@ -3,7 +3,7 @@ title: Build Desktop Apps with Go
description: "Native desktop applications using Go and web technologies"
banner:
content: |
Wails v3 is in BETA. <a href="/quick-start/installation">Start building →</a> | <a href="https://wails.io">v2 docs</a>
Wails v3 is in BETA. <a href="https://wails.io">v2 docs</a>
template: splash
hero:
tagline: Build beautiful, performant desktop applications using Go and modern web technologies. One codebase. Three platforms. No browsers.
@ -33,7 +33,7 @@ import { Tabs, TabItem, Card, CardGrid } from "@astrojs/starlight/components";
left: 0;
width: 200%;
height: 33.33vh;
opacity: 0.04;
opacity: 0.08;
z-index: -1;
background:
url('/showcase-images/tiny-rdm1.webp') 0px center / auto 80% no-repeat,
@ -76,9 +76,9 @@ import { Tabs, TabItem, Card, CardGrid } from "@astrojs/starlight/components";
left: 0;
width: 200%;
height: 33.33vh;
opacity: 0.04;
opacity: 0.08;
z-index: -2;
background:
background:
url('/showcase-images/portfall.webp') 0px center / auto 80% no-repeat,
url('/showcase-images/resizem.webp') 350px center / auto 80% no-repeat,
url('/showcase-images/wally.webp') 700px center / auto 80% no-repeat,
@ -104,9 +104,9 @@ import { Tabs, TabItem, Card, CardGrid } from "@astrojs/starlight/components";
left: 0;
width: 200%;
height: 33.34vh;
opacity: 0.04;
opacity: 0.08;
z-index: -2;
background:
background:
url('/showcase-images/wally.webp') 0px center / auto 80% no-repeat,
url('/showcase-images/october.webp') 350px center / auto 80% no-repeat,
url('/showcase-images/tiny-rdm1.webp') 700px center / auto 80% no-repeat,
@ -223,10 +223,6 @@ cd myapp && wails3 dev
**Your application is now running** with hot reload and type-safe Go-to-JS bindings.
<div className="small-buttons">
<a href="/quick-start/installation">Complete installation guide →</a>
</div>
## Why Wails?
@ -243,8 +239,8 @@ cd myapp && wails3 dev
- One Go codebase for all platforms
- Any web framework - React, Vue, Svelte
- Hot reload during development
- TypeScript bindings auto-generated
- No HTTP overhead or serialisation
- Auto-generated bindings to easily call Go from Javascript
- In-memory IPC. No network ports
</Card>
<Card title="Production Ready" icon="approve-check">
@ -258,9 +254,9 @@ cd myapp && wails3 dev
<Card title="Cross-Platform Native" icon="laptop">
- Single codebase for Windows, macOS, Linux
- Platform-specific features when needed
- Native look and feel on each OS
- No compromise on user experience
- Deploy to all platforms from one build
- Mobile coming soon...
</Card>
</CardGrid>

View file

@ -5,26 +5,19 @@ sidebar:
order: 3
---
import { Card, CardGrid, Tabs, TabItem, Steps } from "@astrojs/starlight/components";
import { Tabs, TabItem, Steps } from "@astrojs/starlight/components";
## What We're Building
A simple **Greet App** that demonstrates the core Wails concepts:
- Go backend with a service
Build a simple greeting application that demonstrates the core Wails concepts:
- Go backend managing logic
- Frontend calling Go functions
- Type-safe bindings
- Hot reload during development
**Time to complete:** 10 minutes
{/* VISUAL PLACEHOLDER: App Screenshot
Description: Screenshot of the finished app showing:
- Clean, modern UI with an input field labeled "Your name"
- A "Greet" button
- Output area showing "Hello, [name]!" message
- Wails logo in corner
Style: Professional screenshot with subtle shadow, showing both light and dark themes side-by-side
*/}
:::tip[Performance Tip for Windows 11 Users]
Consider using [Dev Drive](https://learn.microsoft.com/en-us/windows/dev-drive/) to store your projects. Dev Drives are optimized for developer workloads and can significantly improve build times and disk access speeds by up to 30% compared to regular NTFS drives.
:::
## Create Your Project
@ -33,14 +26,11 @@ Style: Professional screenshot with subtle shadow, showing both light and dark t
1. **Generate the project**
```bash
wails3 init -n greet-app -t vanilla
cd greet-app
wails3 init -n myapp
cd myapp
```
**What this does:**
- Creates a new project called `greet-app`
- Uses the `vanilla` template (plain HTML/CSS/JS)
- Sets up the complete project structure
This creates a new project with the default Vanilla + Vite template (plain HTML/CSS/JS with Vite bundler).
:::tip[Other Templates]
Try `-t react`, `-t vue`, or `-t svelte` for your preferred framework.
@ -50,14 +40,17 @@ Style: Professional screenshot with subtle shadow, showing both light and dark t
2. **Understand the project structure**
```
greet-app/
myapp/
├── main.go # Application entry point
├── greetservice.go # Greet service
├── frontend/ # Your UI code
│ ├── index.html # HTML entry point
│ ├── src/
│ │ ├── main.js # Frontend entry
│ │ ├── style.css # Styles
│ │ └── index.html # HTML
│ └── package.json # Frontend dependencies
│ │ └── main.js # Frontend JavaScript
│ ├── public/
│ │ └── style.css # Styles
│ ├── package.json # Frontend dependencies
│ └── vite.config.js # Vite bundler config
├── build/ # Build configuration
└── Taskfile.yml # Build tasks
```
@ -68,114 +61,98 @@ Style: Professional screenshot with subtle shadow, showing both light and dark t
wails3 dev
```
**What happens:**
- Compiles your Go code
- Builds the frontend
- Launches the app with hot reload enabled
- Opens your default browser for frontend development
:::note[First Run]
The first run takes longer (~30s) as it installs frontend dependencies.
Subsequent runs are instant.
The first run may take longer than expected as it installs frontend dependencies, generates bindings, etc. Subsequent runs are much faster.
:::
4. **See it in action**
The template app should open automatically. Try:
- Typing your name in the input field
- Clicking the "Greet" button
- Seeing the greeting appear
**Hot reload test:**
- Keep the app running
- Edit `frontend/src/style.css` (change a color)
- Save the file
- Watch the app update instantly (no restart needed)
The app opens showing a greeting interface. Enter your name and click "Greet" - the Go backend processes your input and returns a greeting.
</Steps>
## How It Works
Let's understand what's happening under the hood.
Let's understand the code that makes this work.
### The Go Backend
Open `main.go`:
Open `greetservice.go`:
```go title="main.go"
```go title="greetservice.go"
package main
import (
"github.com/wailsapp/wails/v3/pkg/application"
"fmt"
)
type GreetService struct{}
func (g *GreetService) Greet(name string) string {
if name == "" {
return "Hello, World!"
}
return "Hello, " + name + "!"
}
func main() {
app := application.New(application.Options{
Name: "Greet App",
Description: "A demo application",
Services: []application.Service{
application.NewService(&GreetService{}),
},
})
app.NewWebviewWindow()
err := app.Run()
if err != nil {
panic(err)
}
return fmt.Sprintf("Hello %s, It's show time!", name)
}
```
**Key concepts:**
1. **Service**: `GreetService` is a regular Go struct with exported methods
2. **Registration**: `application.NewService(&GreetService{})` makes it available to the frontend
3. **Window**: `app.NewWebviewWindow()` creates the UI window
4. **Run**: `app.Run()` starts the event loop
1. **Service** - A Go struct with exported methods
2. **Exported method** - `Greet` is capitalized, making it available to the frontend
3. **Simple logic** - Takes a name, returns a greeting
4. **Type safety** - Input and output types are defined
:::tip[Services vs Bindings]
- **Services**: Struct-based, auto-discovered methods, recommended for v3
- **Bindings**: Function-based, v2 compatibility mode
:::tip[Understanding Services and Bindings]
**Services** are self-contained Go modules that expose functionality to your frontend. They're just regular Go structs with exported methods that you register in the `Services` field of your application config.
[Learn more about services →](/features/bindings/services)
**Bindings** are the auto-generated TypeScript/JavaScript SDK that lets your frontend call these services. When you run `wails3 dev` or `wails3 build`, Wails analyzes your registered services and generates type-safe bindings in `frontend/bindings/`.
Think of services as your backend API, and bindings as the client library that talks to it.
:::
### Registering the Service
Open `main.go` and find the service registration:
```go title="main.go" {4-6}
err := application.New(application.Options{
Name: "myapp",
Services: []application.Service{
application.NewService(&GreetService{}),
},
// ... other options
})
```
This registers your `GreetService` with Wails, making all its exported methods available to the frontend.
### The Frontend
Open `frontend/src/main.js`:
```javascript title="frontend/src/main.js"
import { Greet } from './bindings/GreetService'
import {GreetService} from "../bindings/changeme";
document.getElementById('greetBtn').addEventListener('click', async () => {
const nameInput = document.getElementById('nameInput')
const resultDiv = document.getElementById('result')
try {
const greeting = await Greet(nameInput.value)
resultDiv.textContent = greeting
} catch (error) {
resultDiv.textContent = 'Error: ' + error
window.greet = async () => {
const nameElement = document.getElementById('name');
const resultElement = document.getElementById('result');
const name = nameElement.value;
if (!name) {
return;
}
})
try {
const result = await GreetService.Greet(name);
resultElement.innerText = result;
} catch (err) {
console.error(err);
}
};
```
**Key concepts:**
1. **Auto-generated bindings**: `./bindings/GreetService` is created automatically
2. **Type-safe calls**: `Greet()` is a typed function (TypeScript definitions included)
3. **Async by default**: All Go calls return Promises
4. **Error handling**: Errors from Go are caught in the `catch` block
1. **Auto-generated bindings** - `GreetService` is imported from generated code
2. **Type-safe calls** - Method names and signatures match your Go code
3. **Async by default** - All Go calls return Promises
4. **Error handling** - Errors from Go are caught in try/catch
:::note[Where are the bindings?]
Generated bindings are in `frontend/bindings/`. They're created automatically when you run `wails3 dev` or `wails3 build`.
@ -183,152 +160,49 @@ Generated bindings are in `frontend/bindings/`. They're created automatically wh
**Never edit these files manually**—they're regenerated on every build.
:::
### The Bridge
## Customize Your App
```d2
direction: right
Let's add a new feature to understand the workflow.
Frontend: "Frontend\n(JavaScript)" {
shape: rectangle
style.fill: "#3B82F6"
}
Bindings: "Auto-Generated\nBindings" {
shape: rectangle
style.fill: "#8B5CF6"
}
Bridge: "Wails Bridge\n(In-Memory)" {
shape: diamond
style.fill: "#10B981"
}
Service: "GreetService\n(Go)" {
shape: rectangle
style.fill: "#00ADD8"
}
Frontend -> Bindings: "import { Greet }"
Bindings -> Bridge: "JSON message"
Bridge -> Service: "Direct call"
Service -> Bridge: "Return value"
Bridge -> Bindings: "JSON response"
Bindings -> Frontend: "Promise resolves"
```
**No HTTP. No REST. No serialisation overhead.** Just direct function calls.
## Customise Your App
Let's make some changes to understand the workflow.
### Add a New Method
### Add a "Greet Many" Feature
<Steps>
1. **Edit the Go service**
1. **Add the method to GreetService**
Add a new method to `GreetService` in `main.go`:
Add this to `greetservice.go`:
```go title="main.go" {5-7}
type GreetService struct{}
func (g *GreetService) Greet(name string) string {
if name == "" {
return "Hello, World!"
```go title="greetservice.go"
func (g *GreetService) GreetMany(names []string) []string {
greetings := make([]string, len(names))
for i, name := range names {
greetings[i] = fmt.Sprintf("Hello %s!", name)
}
return "Hello, " + name + "!"
}
// Add this new method
func (g *GreetService) GetTimeOfDay() string {
hour := time.Now().Hour()
if hour < 12 {
return "Good morning"
} else if hour < 18 {
return "Good afternoon"
}
return "Good evening"
return greetings
}
```
Don't forget to import `time`:
```go
import (
"time"
"github.com/wailsapp/wails/v3/pkg/application"
)
```
2. **The app will auto-rebuild**
2. **Restart the app**
Save the file and `wails3 dev` will automatically rebuild your Go code and restart the app.
Stop the app (Ctrl+C) and run `wails3 dev` again.
:::note[Why restart?]
Go code changes require a restart. Frontend changes hot-reload automatically.
:::note[Auto-Rebuild]
Go code changes trigger an automatic rebuild and restart. Frontend changes hot-reload without restart.
:::
3. **Use the new method in frontend**
3. **Use it in the frontend**
Edit `frontend/src/main.js`:
Add this to `frontend/src/main.js`:
```javascript title="frontend/src/main.js" {1,8-10}
import { Greet, GetTimeOfDay } from './bindings/GreetService'
document.getElementById('greetBtn').addEventListener('click', async () => {
const nameInput = document.getElementById('nameInput')
const resultDiv = document.getElementById('result')
try {
const timeOfDay = await GetTimeOfDay()
const greeting = await Greet(nameInput.value)
resultDiv.textContent = `${timeOfDay}! ${greeting}`
} catch (error) {
resultDiv.textContent = 'Error: ' + error
}
})
```javascript title="frontend/src/main.js"
window.greetMany = async () => {
const names = ['Alice', 'Bob', 'Charlie'];
const greetings = await GreetService.GreetMany(names);
console.log(greetings);
};
```
4. **See the result**
The app hot-reloads automatically. Click "Greet" to see the time-based greeting.
</Steps>
### Add Error Handling
Let's add validation to demonstrate error handling:
<Steps>
1. **Update the Go method**
```go title="main.go" {1,4-6}
import (
"errors"
"time"
"github.com/wailsapp/wails/v3/pkg/application"
)
func (g *GreetService) Greet(name string) (string, error) {
if len(name) > 50 {
return "", errors.New("name too long (max 50 characters)")
}
if name == "" {
return "Hello, World!", nil
}
return "Hello, " + name + "!", nil
}
```
2. **Restart and test**
```bash
# Stop and restart
wails3 dev
```
Try entering a very long name—the error will be caught by the `catch` block in your frontend code.
Open the browser console and call `greetMany()` - you'll see the array of greetings.
</Steps>
@ -341,27 +215,27 @@ wails3 build
```
**What this does:**
- Compiles Go code with optimisations
- Compiles Go code with optimizations
- Builds frontend for production (minified)
- Creates a native executable in `build/bin/`
<Tabs syncKey="os">
<TabItem label="Windows" icon="seti:windows">
**Output:** `build/bin/greet-app.exe`
**Output:** `build/bin/myapp.exe`
Double-click to run. No dependencies needed (WebView2 is part of Windows).
</TabItem>
<TabItem label="macOS" icon="apple">
**Output:** `build/bin/greet-app.app`
**Output:** `build/bin/myapp.app`
Drag to Applications folder or double-click to run.
</TabItem>
<TabItem label="Linux" icon="linux">
**Output:** `build/bin/greet-app`
**Output:** `build/bin/myapp`
Run with `./build/bin/greet-app` or create a `.desktop` file for your launcher.
Run with `./build/bin/myapp` or create a `.desktop` file for your launcher.
</TabItem>
</Tabs>
@ -369,65 +243,27 @@ wails3 build
Want to build for other platforms? See [Cross-Platform Builds →](/guides/build/cross-platform)
:::
## What You've Learned
## What we've learned
<CardGrid>
<Card title="✅ Project Structure" icon="document">
- `main.go` for Go backend
- `frontend/` for UI code
- `Taskfile.yml` for build tasks
</Card>
**Project Structure**
- `main.go` for Go backend
- `frontend/` for UI code
- `Taskfile.yml` for build tasks
<Card title="✅ Services" icon="puzzle">
- Create Go structs with exported methods
- Register with `application.NewService()`
- Methods automatically available in frontend
</Card>
**Services**
- Create Go structs with exported methods
- Register with `application.NewService()`
- Methods automatically available in frontend
<Card title="✅ Bindings" icon="star">
- Auto-generated TypeScript definitions
- Type-safe function calls
- Async by default (Promises)
</Card>
**Bindings**
- Auto-generated TypeScript definitions
- Type-safe function calls
- Async by default (Promises)
<Card title="✅ Development Workflow" icon="rocket">
- `wails3 dev` for hot reload
- Go changes need restart
- Frontend changes hot-reload
</Card>
</CardGrid>
## Next Steps
<CardGrid>
<Card title="Explore Features" icon="open-book">
Learn what else Wails can do:
- Multiple windows
- Native menus
- File dialogs
- System tray
[Feature Overview →](/quick-start/next-steps)
</Card>
<Card title="Build Something Real" icon="rocket">
Follow a complete tutorial:
- Todo app with database
- Dashboard with charts
- File manager
[Tutorials →](/tutorials/overview)
</Card>
<Card title="Deep Dive" icon="star">
Understand how Wails works:
- Architecture
- Binding system
- Event system
[Core Concepts →](/concepts/architecture)
</Card>
</CardGrid>
**Development Workflow**
- `wails3 dev` for hot reload
- Go changes auto-rebuild and restart
- Frontend changes hot-reload instantly
---

View file

@ -11,7 +11,7 @@ import { Card, CardGrid, Tabs, TabItem, Steps } from "@astrojs/starlight/compone
:::tip[TL;DR - Experienced Developers]
```bash
# Install Go 1.23+, then:
# Install Go 1.25+, then:
go install github.com/wailsapp/wails/v3/cmd/wails3@latest
wails3 doctor # Verify installation
```
@ -25,15 +25,15 @@ If `wails3 doctor` passes, you're done. [Skip to First App →](/quick-start/fir
1. **Install Go (Required)**
Wails requires Go 1.23 or later.
Wails requires Go 1.25 or later.
<Tabs syncKey="os">
<TabItem label="Windows" icon="seti:windows">
Download from [go.dev/dl](https://go.dev/dl/) and run the installer.
Download the Windows installer from **[go.dev/dl](https://go.dev/dl/)** and run it.
**Verify installation:**
```powershell
go version # Should show 1.23 or later
go version # Should show 1.25 or later
```
**Check PATH:**
@ -46,9 +46,8 @@ If `wails3 doctor` passes, you're done. [Skip to First App →](/quick-start/fir
<TabItem label="macOS" icon="apple">
**Option 1: Official Installer**
```bash
# Download from go.dev/dl and run the .pkg installer
```
Download the macOS installer (.pkg file) from **[go.dev/dl](https://go.dev/dl/)** and run it.
**Option 2: Homebrew**
```bash
@ -57,7 +56,7 @@ If `wails3 doctor` passes, you're done. [Skip to First App →](/quick-start/fir
**Verify installation:**
```bash
go version # Should show 1.23 or later
go version # Should show 1.25 or later
echo $PATH | grep go/bin # Should show ~/go/bin
```
@ -69,10 +68,11 @@ If `wails3 doctor` passes, you're done. [Skip to First App →](/quick-start/fir
<TabItem label="Linux" icon="linux">
**Option 1: Official Tarball**
Download the Linux tarball from **[go.dev/dl](https://go.dev/dl/)**, then:
```bash
wget https://go.dev/dl/go1.23.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.23.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.25.linux-amd64.tar.gz
```
**Option 2: Package Manager**
@ -112,6 +112,10 @@ If `wails3 doctor` passes, you're done. [Skip to First App →](/quick-start/fir
- Or run `wails3 doctor` later—it will guide you
**That's it!** No other dependencies needed.
:::tip[Performance Tip for Windows 11]
Consider using [Dev Drive](https://learn.microsoft.com/en-us/windows/dev-drive/) to store your projects. Dev Drives are optimized for developer workloads and can significantly improve build times and disk access speeds by up to 30%.
:::
</TabItem>
<TabItem label="macOS" icon="apple">
@ -175,24 +179,49 @@ If `wails3 doctor` passes, you're done. [Skip to First App →](/quick-start/fir
wails3 doctor
```
**Expected output:**
**Expected output (or similar):**
```
Wails CLI v3.0.0
Scanning system - Please wait (this may take a long time)...
Wails (v3.0.0-dev) Wails Doctor
# System
OS: Windows 11
Version: 22H2
ID: windows
Go Version: go1.23.0
Platform: windows/amd64
┌──────────────────────────────────────────────────┐
| Name | MacOS |
| Version | 26.0 |
| ID | 25A354 |
| Branding | MacOS 26.0 |
| Platform | darwin |
| Architecture | arm64 |
| Apple Silicon | true |
| CPU | Apple M2 Pro |
| CPU 1 | Apple M2 Pro |
| CPU 2 | Apple M2 Pro |
| GPU | 16 cores, Metal Support: Metal 4 |
| Memory | 16 GB |
└──────────────────────────────────────────────────┘
# Build Environment
┌─────────────┬─────────────────┐
| Wails CLI | v3.0.0-alpha.40 |
| Go Version | go1.24.6 |
└─────────────┴─────────────────┘
# Dependencies
WebView2: ✅ Installed
npm: ✅ Installed (10.2.3)
✅ Your system is ready for Wails development!
┌─────────────────┬─────────────────────────────────────────────────┐
| npm | 11.6.2 |
| *NSIS | Not Installed. Install with `brew install...`. |
| Xcode cli tools | 2412 |
└─────────────────┴─────────────────────────────────────────────────┘
# Checking for issues
SUCCESS No issues found
# Diagnosis
SUCCESS Your system is ready for Wails development!
```
:::note[If `wails3` command not found]
@ -256,7 +285,7 @@ If `wails3 doctor` passes, you're done. [Skip to First App →](/quick-start/fir
## Troubleshooting
### `wails3` command not found
#### `wails3` command not found
**Cause:** `~/go/bin` (or `%USERPROFILE%\go\bin`) isn't in your PATH.
@ -295,8 +324,9 @@ If `wails3 doctor` passes, you're done. [Skip to First App →](/quick-start/fir
```
</TabItem>
</Tabs>
---
### `wails3 doctor` reports missing dependencies
#### `wails3 doctor` reports missing dependencies
**Linux:** The output tells you exactly which packages to install. Example:
```
@ -312,10 +342,10 @@ If `wails3 doctor` passes, you're done. [Skip to First App →](/quick-start/fir
```bash
xcode-select --install
```
---
#### Go version too old
### Go version too old
Wails v3 requires Go 1.23+. If you have an older version:
Wails v3 requires Go 1.25+. If you have an older version:
<Tabs syncKey="os">
<TabItem label="Windows/macOS" icon="seti:windows">
@ -323,23 +353,22 @@ Wails v3 requires Go 1.23+. If you have an older version:
</TabItem>
<TabItem label="Linux" icon="linux">
Remove old version and install new:
Download the latest tarball from [go.dev/dl](https://go.dev/dl/), then:
```bash
sudo rm -rf /usr/local/go
wget https://go.dev/dl/go1.23.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.23.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.25.linux-amd64.tar.gz
```
</TabItem>
</Tabs>
## Development Version (Advanced)
## Development Version (Bleeding Edge)
Want the latest features before release?
Want to use the absolute latest code from the main development branch? This gives you access to new features and fixes before they're released, but comes with the risk of bugs and breaking changes. Only recommended for contributors or those who need to test upcoming features.
```bash
git clone https://github.com/wailsapp/wails.git
cd wails
git checkout v3-alpha
git checkout v3
cd v3/cmd/wails3
go install
```
@ -352,25 +381,21 @@ go install
## Next Steps
<CardGrid>
<Card title="✅ Installation Complete!" icon="approve-check">
Your system is ready for Wails development.
</Card>
**Installation Complete!** Your system is ready for Wails development.
<Card title="Build Your First App" icon="rocket">
Create a working application in 10 minutes.
[First App Tutorial →](/quick-start/first-app)
</Card>
<Card title="Build Your First App" icon="rocket">
Create a working application in 10 minutes.
<Card title="Explore Templates" icon="open-book">
See what's available out of the box.
```bash
wails3 init -l # List templates
```
</Card>
</CardGrid>
[First App Tutorial →](/quick-start/first-app)
</Card>
<Card title="Explore Templates" icon="open-book">
See what's available out of the box.
```bash
wails3 init -l # List templates
```
</Card>
---

View file

@ -1,401 +1,34 @@
---
title: Next Steps
description: Explore Wails features and plan your learning path
description: Where to go after building your first app
sidebar:
order: 4
---
import { Card, CardGrid, Tabs, TabItem } from "@astrojs/starlight/components";
You've built your first Wails app and understand the basics. Here's where to go next.
## You've Built Your First App! 🎉
## Learn More
You now understand the basics:
- Creating a Wails project
- Writing Go services
- Calling Go from the frontend
- Hot reload development
Practice by building complete applications:
**Now what?** Choose your own adventure based on what you want to build.
- [TODO App](/tutorials/todo-vanilla) - CRUD operations, state management, modern UI
- [All Tutorials](/tutorials/overview) - Notes apps, dashboards, system tray apps, and more
## Learning Paths
## Features
### 🚀 Path 1: Build a Complete Application
Wails provides native desktop capabilities:
**Best for:** Learning by doing
- [Windows](/features/windows/basics) - Multiple windows, frameless windows, positioning
- [Menus](/features/menus/application) - Application menus, context menus, system tray
- [Dialogs](/features/dialogs/file) - File open/save, message dialogs
- [Events](/features/events/system) - Communication between components
- [Bindings](/features/bindings/methods) - Type-safe Go ↔ JavaScript calls
- [Clipboard](/features/clipboard) - Copy/paste operations
- [Drag & Drop](/features/drag-drop) - File drag and drop
- [Keyboard](/features/keyboard) - Global shortcuts
Follow step-by-step tutorials that build real applications:
## Get Help
<CardGrid>
<Card title="Todo App with React" icon="seti:react">
**What you'll learn:**
- React integration
- SQLite database
- CRUD operations
- State management
**Time:** 45 minutes
[Start Tutorial →](/tutorials/todo-react)
</Card>
<Card title="Dashboard with Vue" icon="seti:vue">
**What you'll learn:**
- Vue 3 composition API
- Real-time data updates
- Charts and visualisations
- Event system
**Time:** 60 minutes
[Start Tutorial →](/tutorials/dashboard-vue)
</Card>
<Card title="File Manager" icon="document">
**What you'll learn:**
- File operations
- Native dialogs
- Drag & drop
- Context menus
**Time:** 45 minutes
[Start Tutorial →](/tutorials/file-operations)
</Card>
</CardGrid>
### 📚 Path 2: Explore Features Systematically
**Best for:** Understanding capabilities before building
Learn what Wails can do, feature by feature:
<CardGrid>
<Card title="Windows" icon="laptop">
- Create multiple windows
- Frameless windows
- Window positioning
- Window events
[Learn More →](/features/windows/basics)
</Card>
<Card title="Menus" icon="list-format">
- Application menus
- Context menus
- System tray menus
- Dynamic menu updates
[Learn More →](/features/menus/application)
</Card>
<Card title="Dialogs" icon="approve-check">
- File open/save
- Message dialogs
- Custom dialogs
- Platform-native UI
[Learn More →](/features/dialogs/file)
</Card>
<Card title="Events" icon="rocket">
- Application events
- Window events
- Custom events
- Event filtering
[Learn More →](/features/events/system)
</Card>
</CardGrid>
### 🎯 Path 3: Solve Specific Problems
**Best for:** Adding features to existing projects
Jump to guides for specific tasks:
<Tabs syncKey="problem">
<TabItem label="Distribution" icon="rocket">
**I need to:**
- [Package my app for Windows](/guides/build/windows)
- [Create a macOS .app bundle](/guides/build/macos)
- [Build Linux packages (deb/rpm)](/guides/build/linux)
- [Set up auto-updates](/guides/distribution/auto-updates)
- [Code sign my application](/guides/build/signing)
</TabItem>
<TabItem label="Integration" icon="puzzle">
**I need to:**
- [Use a REST API from Go](/guides/patterns/rest-api)
- [Integrate a database](/guides/patterns/database)
- [Use Gin router](/guides/patterns/gin-routing)
- [Handle file associations](/guides/distribution/file-associations)
- [Create custom protocols](/guides/distribution/custom-protocols)
</TabItem>
<TabItem label="UI/UX" icon="star">
**I need to:**
- [Create a system tray app](/tutorials/system-tray)
- [Implement drag & drop](/features/drag-drop)
- [Add keyboard shortcuts](/features/keyboard)
- [Show notifications](/features/notifications)
- [Build a frameless window](/features/windows/frameless)
</TabItem>
<TabItem label="Advanced" icon="seti:config">
**I need to:**
- [Create custom templates](/guides/advanced/custom-templates)
- [Use WML (Wails Markup)](/guides/advanced/wml)
- [Handle panics gracefully](/guides/advanced/panic-handling)
- [Implement security best practices](/guides/advanced/security)
- [Debug production issues](/guides/dev/debugging)
</TabItem>
</Tabs>
## Feature Quick Reference
### Essential Features
| Feature | What It Does | When You Need It |
|---------|--------------|------------------|
| [Windows](/features/windows/basics) | Create and manage application windows | Every app |
| [Bindings](/features/bindings/methods) | Call Go from JavaScript | Every app |
| [Events](/features/events/system) | Communication between components | Most apps |
| [Dialogs](/features/dialogs/file) | File open/save, messages | Apps with file I/O |
### UI Features
| Feature | What It Does | When You Need It |
|---------|--------------|------------------|
| [Menus](/features/menus/application) | Application, context, tray menus | Professional apps |
| [Clipboard](/features/clipboard) | Copy/paste operations | Text/data manipulation |
| [Drag & Drop](/features/drag-drop) | File drag & drop | File-based apps |
| [Keyboard](/features/keyboard) | Global keyboard shortcuts | Power user features |
| [Notifications](/features/notifications) | System notifications | Background tasks |
### System Integration
| Feature | What It Does | When You Need It |
|---------|--------------|------------------|
| [System Tray](/features/menus/systray) | Background app with tray icon | Always-running apps |
| [File Associations](/guides/distribution/file-associations) | Open files with your app | Document-based apps |
| [Custom Protocols](/guides/distribution/custom-protocols) | `myapp://` URL handling | Deep linking |
| [Single Instance](/guides/distribution/single-instance) | Prevent multiple instances | Most apps |
| [Auto-Updates](/guides/distribution/auto-updates) | Automatic app updates | Production apps |
### Platform-Specific
| Feature | Platform | What It Does |
|---------|----------|--------------|
| [Dock](/features/platform/macos-dock) | macOS | Dock icon, badge, menu |
| [Toolbar](/features/platform/macos-toolbar) | macOS | Native toolbar |
| [UAC](/features/platform/windows-uac) | Windows | Admin privileges |
| [Desktop](/features/platform/linux) | Linux | Desktop integration |
## Common Use Cases
### Building a Developer Tool?
**You'll likely need:**
1. [Multiple windows](/features/windows/multiple) - For different views
2. [Keyboard shortcuts](/features/keyboard) - For power users
3. [File dialogs](/features/dialogs/file) - For opening projects
4. [System tray](/features/menus/systray) - For background operation
5. [Custom protocols](/guides/distribution/custom-protocols) - For deep linking
**Example apps:** Database clients, API testers, log viewers
### Building a Business Application?
**You'll likely need:**
1. [Database integration](/guides/patterns/database) - For data persistence
2. [Menus](/features/menus/application) - For navigation
3. [Dialogs](/features/dialogs/file) - For import/export
4. [Auto-updates](/guides/distribution/auto-updates) - For deployment
5. [Code signing](/guides/build/signing) - For security
**Example apps:** CRM, inventory, dashboards
### Building a Creative Tool?
**You'll likely need:**
1. [Frameless windows](/features/windows/frameless) - For custom UI
2. [Drag & drop](/features/drag-drop) - For file handling
3. [Clipboard](/features/clipboard) - For copy/paste
4. [File associations](/guides/distribution/file-associations) - For opening files
5. [Native performance](/concepts/architecture) - For processing
**Example apps:** Image editors, video tools, design utilities
### Building a Productivity App?
**You'll likely need:**
1. [System tray](/features/menus/systray) - For quick access
2. [Notifications](/features/notifications) - For reminders
3. [Keyboard shortcuts](/features/keyboard) - For efficiency
4. [Single instance](/guides/distribution/single-instance) - To prevent duplicates
5. [Events](/features/events/system) - For real-time updates
**Example apps:** Note-taking, task managers, time trackers
## Understanding the Architecture
Before diving deeper, understand how Wails works:
```d2
direction: down
User: "User" {
shape: person
style.fill: "#3B82F6"
}
App: "Your Application" {
Frontend: "Frontend\n(HTML/CSS/JS)" {
shape: rectangle
style.fill: "#8B5CF6"
}
Bridge: "Wails Bridge" {
shape: diamond
style.fill: "#10B981"
}
Backend: "Go Backend\n(Services)" {
shape: rectangle
style.fill: "#00ADD8"
}
Frontend -> Bridge: "Call Go functions"
Bridge -> Backend: "Execute methods"
Backend -> Bridge: "Return results"
Bridge -> Frontend: "Update UI"
}
OS: "Operating System" {
WebView: "Native WebView" {
shape: rectangle
}
APIs: "Native APIs" {
shape: rectangle
}
}
User -> App.Frontend: "Interacts"
App.Frontend -> OS.WebView: "Renders in"
App.Backend -> OS.APIs: "Calls"
```
**Key concepts:**
- **Frontend** runs in native WebView (not Chromium)
- **Bridge** enables direct Go ↔ JS communication
- **Backend** accesses OS APIs directly
- **No HTTP overhead** - everything is in-memory
[Deep dive into architecture →](/concepts/architecture)
## Development Workflow
### Daily Development
```bash
# Start development server
wails3 dev
# In another terminal, run tests
go test ./...
# Build for production
wails3 build
```
### Adding Features
1. **Add Go method** to your service
2. **Restart** `wails3 dev` (Go changes need restart)
3. **Import binding** in frontend (auto-generated)
4. **Use the method** in your UI
5. **Test** - frontend changes hot-reload
[Complete workflow guide →](/guides/dev/workflow)
### Debugging
<Tabs syncKey="debug">
<TabItem label="Frontend" icon="seti:javascript">
**Use browser DevTools:**
1. Right-click in app → "Inspect Element"
2. Or press `F12` (Windows/Linux) or `Cmd+Option+I` (macOS)
3. Console shows errors, Network tab shows requests
[Frontend debugging →](/guides/dev/debugging#frontend)
</TabItem>
<TabItem label="Backend" icon="seti:go">
**Use Go debugging:**
```bash
# Run with delve
dlv debug
# Or use your IDE's debugger
# VS Code, GoLand, etc.
```
[Backend debugging →](/guides/dev/debugging#backend)
</TabItem>
</Tabs>
## Resources
<CardGrid>
<Card title="📖 API Reference" icon="document">
Complete API documentation for all Wails packages.
[Browse API →](/reference/overview)
</Card>
<Card title="🎓 Tutorials" icon="open-book">
Step-by-step guides for building real applications.
[View Tutorials →](/tutorials/overview)
</Card>
<Card title="💡 Examples" icon="star">
50+ working examples in the GitHub repository.
[Browse Examples →](https://github.com/wailsapp/wails/tree/v3-alpha/v3/examples)
</Card>
<Card title="💬 Community" icon="discord">
Get help, share projects, discuss features.
[Join Discord →](https://discord.gg/JDdSxwjhGf)
</Card>
</CardGrid>
## Recommended Next Steps
Based on where you are:
### If you're new to Go:
1. [Go Tour](https://go.dev/tour/) - Learn Go basics (2 hours)
2. [Effective Go](https://go.dev/doc/effective_go) - Best practices
3. Build a [simple tutorial](/tutorials/todo-react) - Apply what you learned
### If you're new to desktop apps:
1. [How Wails Works](/concepts/architecture) - Understand the architecture
2. [Window Management](/features/windows/basics) - Learn window basics
3. [Menus](/features/menus/application) - Add professional menus
### If you're ready to build:
1. Choose a [tutorial](/tutorials/overview) that matches your goal
2. Follow it completely - don't skip steps
3. Modify it to fit your needs
4. Share your project in [Discord](https://discord.gg/JDdSxwjhGf)!
---
**Ready to dive deeper?** Pick a path above and start building!
- [Discord](https://discord.gg/JDdSxwjhGf) - Ask questions, share projects
- [Examples](https://github.com/wailsapp/wails/tree/v3-alpha/v3/examples) - 50+ working examples
- [API Reference](/reference/overview) - Complete documentation

View file

@ -52,7 +52,7 @@ Ship quality software with fewer resources.
## When to Choose Wails
### ✅ Wails is Perfect For:
**Wails is Perfect For:**
- **Business applications** (CRM, inventory, dashboards, admin tools)
- **Developer tools** (database clients, API testers, deployment tools)
@ -84,32 +84,26 @@ Go: "Go Backend" {
style.fill: "#00ADD8"
}
Bridge: "Wails Bridge\n(In-Memory)" {
shape: diamond
style.fill: "#10B981"
}
WebView: "Native WebView" {
shape: rectangle
style.fill: "#3B82F6"
Frontend: "Your UI\n(React/Vue/etc)" {
shape: rectangle
style.fill: "#8B5CF6"
}
}
Frontend: "Your UI\n(React/Vue/etc)" {
shape: rectangle
style.fill: "#8B5CF6"
}
Go -> Bridge: "Direct function calls"
Bridge -> WebView: "JSON messages"
WebView -> Frontend: "Native rendering"
Frontend -> Bridge: "Type-safe bindings"
Bridge -> Go: "Zero-copy where possible"
Go <-> WebView: "Bindings & Events"
```
**How Wails achieves performance:**
1. **No runtime bundled** - Uses Go's compiled binary
2. **Native WebView** - OS-provided rendering engine
3. **Direct Go ↔ JS bridge** - In-memory communication, no HTTP overhead
3. **Direct Go ↔ JS bridge** - In-memory communication, no network overhead
4. **Compiled binary** - Instant startup, no JIT compilation
## Next Steps

View file

@ -1,348 +1,72 @@
---
title: Tutorials Overview
description: Learn Wails by building real applications
title: Tutorials
description: Learn Wails by building applications
sidebar:
order: 1
---
import { Card, CardGrid } from "@astrojs/starlight/components";
## Overview
## Learn by Building
Step-by-step tutorials that teach Wails concepts by building complete applications. Each tutorial includes working code, explanations, and practical patterns.
The best way to learn Wails is to build something real. Our tutorials use **production-ready patterns** and **real-world scenarios**—no toy examples.
## Beginner Tutorials
Each tutorial is:
- ✅ **Complete** - Working code from start to finish
- ✅ **Tested** - Verified on all platforms
- ✅ **Explained** - Why, not just how
- ✅ **Practical** - Patterns you'll use in real projects
**[TODO App (Vanilla JS)](/tutorials/todo-vanilla)** - 20 minutes
- CRUD operations, thread-safe state, modern UI design
- No framework complexity required
## Choose Your Path
**[Notes App (Vanilla JS)](/tutorials/notes-vanilla)** - 30 minutes
- File operations, local storage, core Wails concepts
- No framework complexity required
### 🎯 New to Wails?
**[TODO App (React)](/tutorials/todo-react)** - 45 minutes
- React integration, SQLite database, state management
Start with a beginner-friendly tutorial that teaches the fundamentals:
## Intermediate Tutorials
<CardGrid>
<Card title="Notes App (Vanilla JS)" icon="pencil">
**Perfect first tutorial**
- No framework complexity
- Core Wails concepts
- File operations
- Local storage
**Time:** 30 minutes
**Level:** Beginner
[Start Tutorial →](/tutorials/notes-vanilla)
</Card>
**[Dashboard (Vue)](/tutorials/dashboard-vue)** - 60 minutes
- Vue 3 Composition API, charts and graphs, WebSocket integration, event system
<Card title="Todo App (React)" icon="seti:react">
**Learn with React**
- React integration
- SQLite database
- CRUD operations
- State management
**Time:** 45 minutes
**Level:** Beginner
[Start Tutorial →](/tutorials/todo-react)
</Card>
</CardGrid>
**[File Manager](/tutorials/file-operations)** - 45 minutes
- File dialogs, drag & drop, context menus, file system operations
### 🚀 Ready for More?
**[Database Integration](/tutorials/database)** - 40 minutes
- SQLite setup, migrations, query patterns, best practices
Build feature-rich applications with advanced patterns:
**[System Tray App](/tutorials/system-tray)** - 35 minutes
- System tray integration, background tasks, notifications, window management
<CardGrid>
<Card title="Dashboard (Vue)" icon="seti:vue">
**Real-time data visualisation**
- Vue 3 Composition API
- Charts and graphs
- WebSocket integration
- Event system
**Time:** 60 minutes
**Level:** Intermediate
[Start Tutorial →](/tutorials/dashboard-vue)
</Card>
## Advanced Tutorials
<Card title="File Manager" icon="document">
**Native file operations**
- File dialogs
- Drag & drop
- Context menus
- File system operations
**Time:** 45 minutes
**Level:** Intermediate
[Start Tutorial →](/tutorials/file-operations)
</Card>
**[Multi-Window Application](/tutorials/multi-window)** - 50 minutes
- Window lifecycle, inter-window communication, shared state, window positioning
<Card title="Database Integration" icon="seti:db">
**Data persistence patterns**
- SQLite setup
- Migrations
- Query patterns
- Best practices
**Time:** 40 minutes
**Level:** Intermediate
[Start Tutorial →](/tutorials/database)
</Card>
**[Custom Protocols](/tutorials/custom-protocols)** - 40 minutes
- Protocol registration, URL parsing, security considerations, platform differences
<Card title="System Tray App" icon="star">
**Background applications**
- System tray integration
- Background tasks
- Notifications
- Window management
**Time:** 35 minutes
**Level:** Intermediate
[Start Tutorial →](/tutorials/system-tray)
</Card>
</CardGrid>
**[Native Integrations](/tutorials/native-integrations)** - 45 minutes
- macOS Dock integration, Windows UAC, Linux desktop files, platform detection
### 🎓 Advanced Topics
Master complex features and production patterns:
<CardGrid>
<Card title="Multi-Window Application" icon="laptop">
**Multiple window management**
- Window lifecycle
- Inter-window communication
- Shared state
- Window positioning
**Time:** 50 minutes
**Level:** Advanced
[Start Tutorial →](/tutorials/multi-window)
</Card>
<Card title="Custom Protocols" icon="rocket">
**Deep linking and URL handling**
- Protocol registration
- URL parsing
- Security considerations
- Platform differences
**Time:** 40 minutes
**Level:** Advanced
[Start Tutorial →](/tutorials/custom-protocols)
</Card>
<Card title="Native Integrations" icon="puzzle">
**Platform-specific features**
- macOS Dock integration
- Windows UAC
- Linux desktop files
- Platform detection
**Time:** 45 minutes
**Level:** Advanced
[Start Tutorial →](/tutorials/native-integrations)
</Card>
<Card title="Auto-Updates (Sparkle)" icon="approve-check">
**Production deployment**
- Sparkle setup (macOS)
- Update server
- Code signing
- Testing updates
**Time:** 60 minutes
**Level:** Advanced
[Start Tutorial →](/tutorials/sparkle-updates)
</Card>
</CardGrid>
## Tutorial Structure
Each tutorial follows a consistent structure:
1. **What You'll Build** - See the finished product
2. **Prerequisites** - What you need to know
3. **Setup** - Create the project
4. **Step-by-Step Implementation** - Build feature by feature
5. **Testing** - Verify it works
6. **Next Steps** - Where to go from here
**[Auto-Updates (Sparkle)](/tutorials/sparkle-updates)** - 60 minutes
- Sparkle setup (macOS), update server, code signing, testing updates
## Prerequisites
### Required Knowledge
**Required:**
- Go 1.25+
- Basic Go knowledge (variables, functions, structs)
- Basic JavaScript knowledge (variables, functions, async/await)
- [Wails installed](/quick-start/installation)
- **Go basics** - Variables, functions, structs, methods
- **JavaScript basics** - Variables, functions, async/await
- **HTML/CSS basics** - For UI development
**Optional:**
- npm (for framework templates)
:::tip[New to Go?]
Complete the [Go Tour](https://go.dev/tour/) (2 hours) before starting tutorials.
Complete the [Go Tour](https://go.dev/tour/) before starting tutorials.
:::
### Required Software
## Get Help
- **Wails installed** - [Installation guide](/quick-start/installation)
- **Go 1.23+** - [Download](https://go.dev/dl/)
- **npm** (optional) - For framework templates
### Recommended Tools
- **VS Code** with Go extension
- **Browser DevTools** knowledge
- **Git** for version control
## Learning Paths by Goal
### Building a Business Application?
**Recommended sequence:**
1. [Todo App (React)](/tutorials/todo-react) - Learn basics
2. [Database Integration](/tutorials/database) - Add persistence
3. [Multi-Window Application](/tutorials/multi-window) - Multiple views
4. [Auto-Updates](/tutorials/sparkle-updates) - Production deployment
**You'll learn:** CRUD operations, database patterns, window management, deployment
### Building a Developer Tool?
**Recommended sequence:**
1. [File Manager](/tutorials/file-operations) - File handling
2. [System Tray App](/tutorials/system-tray) - Background operation
3. [Custom Protocols](/tutorials/custom-protocols) - Deep linking
4. [Native Integrations](/tutorials/native-integrations) - Platform features
**You'll learn:** File operations, system integration, URL handling, platform APIs
### Building a Creative Tool?
**Recommended sequence:**
1. [Notes App (Vanilla)](/tutorials/notes-vanilla) - Core concepts
2. [File Manager](/tutorials/file-operations) - File I/O
3. [Multi-Window Application](/tutorials/multi-window) - Multiple views
4. [Native Integrations](/tutorials/native-integrations) - Platform features
**You'll learn:** File operations, window management, native APIs, performance
### Building a Productivity App?
**Recommended sequence:**
1. [Todo App (React)](/tutorials/todo-react) - Basic app structure
2. [Database Integration](/tutorials/database) - Data persistence
3. [System Tray App](/tutorials/system-tray) - Background operation
4. [Dashboard (Vue)](/tutorials/dashboard-vue) - Real-time updates
**You'll learn:** State management, persistence, background tasks, real-time data
## Tutorial Difficulty Levels
### 🟢 Beginner
- Assumes basic Go and JavaScript knowledge
- Step-by-step instructions
- Detailed explanations
- Simple patterns
**Start here if:** You're new to Wails or desktop development
### 🟡 Intermediate
- Assumes Wails basics
- Focuses on specific features
- Less hand-holding
- Real-world patterns
**Start here if:** You've completed a beginner tutorial
### 🔴 Advanced
- Assumes solid Wails knowledge
- Complex integrations
- Production considerations
- Performance optimisation
**Start here if:** You're building production applications
## Getting Help
### While Following Tutorials
1. **Read carefully** - Don't skip steps
2. **Type the code** - Don't copy-paste (you'll learn more)
3. **Experiment** - Try changing things
4. **Check the examples** - [GitHub examples](https://github.com/wailsapp/wails/tree/v3-alpha/v3/examples)
### If You Get Stuck
1. **Check the error message** - It usually tells you what's wrong
2. **Review the step** - Did you miss something?
3. **Check the docs** - [API reference](/reference/overview)
4. **Ask for help** - [Discord community](https://discord.gg/JDdSxwjhGf)
### Reporting Issues
Found a problem in a tutorial?
1. **Check if it's already reported** - [GitHub issues](https://github.com/wailsapp/wails/issues)
2. **Provide details** - OS, Go version, error message
3. **Include code** - What you tried
4. **Be specific** - Which tutorial, which step
## Beyond Tutorials
After completing tutorials, explore:
<CardGrid>
<Card title="Features Documentation" icon="star">
Deep dive into specific Wails features.
[Browse Features →](/features/windows/basics)
</Card>
<Card title="Guides" icon="open-book">
Task-oriented guides for common scenarios.
[Browse Guides →](/guides/dev/project-structure)
</Card>
<Card title="API Reference" icon="document">
Complete API documentation.
[Browse API →](/reference/overview)
</Card>
<Card title="Examples" icon="rocket">
50+ working examples on GitHub.
[Browse Examples →](https://github.com/wailsapp/wails/tree/v3-alpha/v3/examples)
</Card>
</CardGrid>
## Community Tutorials
Community members have created excellent tutorials:
:::note[Submit Your Tutorial]
Created a Wails tutorial? [Let us know](https://discord.gg/JDdSxwjhGf) and we'll feature it here!
:::
---
**Ready to start?** Pick a tutorial above and start building!
- [Discord](https://discord.gg/JDdSxwjhGf) - Ask questions, share projects
- [Examples](https://github.com/wailsapp/wails/tree/v3-alpha/v3/examples) - 50+ working examples
- [API Reference](/reference/overview) - Complete documentation

View file

@ -0,0 +1,578 @@
---
title: TODO List App
description: Build a complete TODO list application with CRUD operations
sidebar:
order: 2
---
import { Tabs, TabItem, Steps } from "@astrojs/starlight/components";
Build a complete TODO list application that demonstrates practical Wails concepts:
- CRUD operations (Create, Read, Update, Delete)
- Thread-safe state management
- Modern UI design
- Type-safe bindings
**Time to complete:** 20 minutes
## Create Your Project
<Steps>
1. **Generate the project**
```bash
wails3 init -n todo-app
cd todo-app
```
2. **Create the TODO service**
Delete `greetservice.go` and create a new file `todoservice.go`:
```go title="todoservice.go"
package main
import (
"errors"
"sync"
)
type Todo struct {
ID int `json:"id"`
Title string `json:"title"`
Completed bool `json:"completed"`
}
type TodoService struct {
todos []Todo
nextID int
mu sync.RWMutex
}
func NewTodoService() *TodoService {
return &TodoService{
todos: []Todo{},
nextID: 1,
}
}
func (t *TodoService) GetAll() []Todo {
t.mu.RLock()
defer t.mu.RUnlock()
return t.todos
}
func (t *TodoService) Add(title string) (*Todo, error) {
if title == "" {
return nil, errors.New("title cannot be empty")
}
t.mu.Lock()
defer t.mu.Unlock()
todo := Todo{
ID: t.nextID,
Title: title,
Completed: false,
}
t.todos = append(t.todos, todo)
t.nextID++
return &todo, nil
}
func (t *TodoService) Toggle(id int) error {
t.mu.Lock()
defer t.mu.Unlock()
for i := range t.todos {
if t.todos[i].ID == id {
t.todos[i].Completed = !t.todos[i].Completed
return nil
}
}
return errors.New("todo not found")
}
func (t *TodoService) Delete(id int) error {
t.mu.Lock()
defer t.mu.Unlock()
for i, todo := range t.todos {
if todo.ID == id {
t.todos = append(t.todos[:i], t.todos[i+1:]...)
return nil
}
}
return errors.New("todo not found")
}
```
**What's happening here:**
- `sync.RWMutex` provides thread-safe access to the todos slice
- Each method locks appropriately (read lock for GetAll, write lock for mutations)
- IDs are auto-incremented for each new TODO
- Errors are returned for invalid operations
3. **Update main.go**
Update the service registration in `main.go`:
```go title="main.go" {5}
Services: []application.Service{
application.NewService(NewTodoService()),
},
```
4. **Create the frontend UI**
Replace `frontend/src/main.js`:
```javascript title="frontend/src/main.js"
import {TodoService} from "../bindings/changeme";
async function loadTodos() {
const todos = await TodoService.GetAll();
const list = document.getElementById('todo-list');
list.innerHTML = todos.map(todo => `
<div class="todo ${todo.completed ? 'completed' : ''}">
<input type="checkbox"
${todo.completed ? 'checked' : ''}
onchange="toggleTodo(${todo.id})">
<span>${todo.title}</span>
<button onclick="deleteTodo(${todo.id})">Delete</button>
</div>
`).join('');
}
window.addTodo = async () => {
const input = document.getElementById('todo-input');
const title = input.value.trim();
if (title) {
await TodoService.Add(title);
input.value = '';
await loadTodos();
}
}
window.toggleTodo = async (id) => {
await TodoService.Toggle(id);
await loadTodos();
}
window.deleteTodo = async (id) => {
await TodoService.Delete(id);
await loadTodos();
}
// Load todos on startup
loadTodos();
```
5. **Update the HTML**
Replace `frontend/index.html`:
```html title="frontend/index.html"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>TODO App</title>
<link rel="stylesheet" href="./public/style.css"/>
</head>
<body>
<div class="container">
<h1>My TODOs</h1>
<div class="card">
<div class="input-box">
<input type="text"
id="todo-input"
class="input"
placeholder="Add a new todo..."
onkeypress="if(event.key==='Enter') addTodo()">
<button class="btn" onclick="addTodo()">Add</button>
</div>
<div id="todo-list"></div>
</div>
</div>
<script type="module" src="./src/main.js"></script>
</body>
</html>
```
6. **Style the app**
Replace `frontend/public/style.css`:
```css title="frontend/public/style.css"
:root {
font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto",
"Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
font-size: 16px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: rgba(255, 255, 255, 0.87);
}
body {
margin: 0;
display: flex;
place-items: center;
min-height: 100vh;
}
.container {
width: 100%;
max-width: 600px;
padding: 20px;
}
h1 {
text-align: center;
color: white;
font-size: 2.5em;
font-weight: 300;
margin: 0 0 30px 0;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}
.card {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: 16px;
padding: 30px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}
.input-box {
display: flex;
gap: 10px;
margin-bottom: 25px;
}
.input {
flex: 1;
border: 2px solid #e0e0e0;
border-radius: 12px;
height: 50px;
padding: 0 20px;
font-size: 16px;
transition: all 0.3s ease;
}
.input:focus {
border-color: #667eea;
outline: none;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.btn {
height: 50px;
padding: 0 30px;
border: none;
border-radius: 12px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);
}
#todo-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.todo {
display: flex;
align-items: center;
padding: 18px 20px;
background: white;
border: 2px solid #f0f0f0;
border-radius: 12px;
transition: all 0.3s ease;
gap: 15px;
}
.todo:hover {
border-color: #667eea;
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.15);
transform: translateX(4px);
}
.todo.completed {
opacity: 0.6;
}
.todo.completed span {
text-decoration: line-through;
color: #999;
}
.todo input[type="checkbox"] {
width: 24px;
height: 24px;
cursor: pointer;
appearance: none;
-webkit-appearance: none;
border: 2px solid #667eea;
border-radius: 6px;
position: relative;
transition: all 0.3s ease;
flex-shrink: 0;
}
.todo input[type="checkbox"]:hover {
background: rgba(102, 126, 234, 0.1);
}
.todo input[type="checkbox"]:checked {
background: #667eea;
border-color: #667eea;
}
.todo input[type="checkbox"]:checked::after {
content: '✓';
position: absolute;
color: white;
font-size: 16px;
font-weight: bold;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.todo span {
flex: 1;
font-size: 16px;
color: #333;
}
.todo button {
padding: 8px 16px;
background: #ff4757;
color: white;
border: none;
border-radius: 8px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
opacity: 0;
flex-shrink: 0;
}
.todo:hover button {
opacity: 1;
}
.todo button:hover {
background: #ee5a6f;
transform: scale(1.05);
}
#todo-list:empty::before {
content: "No todos yet. Add one above!";
display: block;
text-align: center;
padding: 40px 20px;
color: #999;
}
```
7. **Run the app**
```bash
wails3 dev
```
Try adding, completing, and deleting todos. Notice how the UI updates instantly after each operation.
</Steps>
## How It Works
### Thread-Safe State Management
The `sync.RWMutex` provides safe concurrent access:
```go
func (t *TodoService) GetAll() []Todo {
t.mu.RLock() // Read lock - multiple readers allowed
defer t.mu.RUnlock()
return t.todos
}
func (t *TodoService) Add(title string) (*Todo, error) {
t.mu.Lock() // Write lock - exclusive access
defer t.mu.Unlock()
// ... mutations
}
```
**Why this matters:**
- Multiple frontend calls can happen concurrently
- Read operations don't block each other
- Write operations get exclusive access
- `defer` ensures locks are always released
### Error Handling
The service returns errors for invalid operations:
```go
func (t *TodoService) Add(title string) (*Todo, error) {
if title == "" {
return nil, errors.New("title cannot be empty")
}
// ...
}
```
In the frontend, you can catch these:
```javascript
try {
await TodoService.Add(title);
} catch (err) {
alert('Error: ' + err);
}
```
### State Synchronization
After each mutation, we reload the full list:
```javascript
window.addTodo = async () => {
await TodoService.Add(title); // Mutation
await loadTodos(); // Refresh
}
```
**Alternative approach:** Return the updated list from each method to avoid the second call.
## Enhancements
### Add Statistics
Add this to `todoservice.go`:
```go
type TodoStats struct {
Total int `json:"total"`
Completed int `json:"completed"`
Active int `json:"active"`
}
func (t *TodoService) GetStats() TodoStats {
t.mu.RLock()
defer t.mu.RUnlock()
stats := TodoStats{
Total: len(t.todos),
}
for _, todo := range t.todos {
if todo.Completed {
stats.Completed++
} else {
stats.Active++
}
}
return stats
}
```
Display in the frontend:
```javascript
async function loadTodos() {
const [todos, stats] = await Promise.all([
TodoService.GetAll(),
TodoService.GetStats()
]);
// Display stats
document.getElementById('stats').textContent =
`${stats.active} active, ${stats.completed} completed`;
// ... render todos
}
```
### Add "Clear Completed"
```go
func (t *TodoService) ClearCompleted() int {
t.mu.Lock()
defer t.mu.Unlock()
removed := 0
newTodos := []Todo{}
for _, todo := range t.todos {
if !todo.Completed {
newTodos = append(newTodos, todo)
} else {
removed++
}
}
t.todos = newTodos
return removed
}
```
### Add Persistence
For production apps, you'd typically add database persistence. See the [Database Integration](/guides/patterns/database) guide for examples with SQLite, PostgreSQL, etc.
## Build for Production
```bash
wails3 build
```
Your TODO app is now a native executable in `build/bin/`.
## What We Learned
**CRUD Operations**
- Create (Add), Read (GetAll), Update (Toggle), Delete (Delete)
- Error handling for invalid operations
- Proper return types for each operation
**Thread Safety**
- `sync.RWMutex` for concurrent access
- Read locks vs write locks
- Deferred unlocking to prevent deadlocks
**Modern UI**
- Gradient backgrounds
- Glassmorphic design
- Custom checkbox styling
- Hover effects and transitions
- Empty state messaging
**State Management**
- Centralized state in Go
- Frontend as view layer
- Refresh pattern after mutations
---
**Next:** Try adding [database persistence](/guides/patterns/database) or building a [system tray app](/tutorials/system-tray).

View file

@ -1,3 +1,16 @@
/* Red accent color theme */
:root {
--sl-color-accent-low: hsl(0, 85%, 95%);
--sl-color-accent: hsl(0, 90%, 45%);
--sl-color-accent-high: hsl(0, 90%, 35%);
}
[data-theme='dark'] {
--sl-color-accent-low: hsl(0, 85%, 15%);
--sl-color-accent: hsl(0, 90%, 50%);
--sl-color-accent-high: hsl(0, 90%, 60%);
}
html {
scrollbar-gutter: stable;
overflow-y: scroll; /* Show vertical scrollbar */

View file

@ -8,6 +8,10 @@ sidebar_position: 2
Now that the CLI is installed, you can generate a new project by using the `wails init` command.
:::tip[Performance Tip for Windows 11 Users]
Consider using [Dev Drive](https://learn.microsoft.com/en-us/windows/dev-drive/) to store your projects. Dev Drives are optimized for developer workloads and can significantly improve build times and disk access speeds by up to 30% compared to regular NTFS drives.
:::
Pick your favourite framework:
```mdx-code-block

View file

@ -55,6 +55,8 @@ import TabItem from "@theme/TabItem";
</TabItem>
<TabItem value="Windows">
Wails requires that the <a href="https://developer.microsoft.com/en-us/microsoft-edge/webview2/">WebView2</a> runtime is installed. Some Windows installations will already have this installed. You can check using the <code>wails doctor</code> command.
<br/><br/>
<strong>Performance Tip:</strong> For Windows 11 users, consider using <a href="https://learn.microsoft.com/en-us/windows/dev-drive/">Dev Drive</a> to store your projects. Dev Drives are optimized for developer workloads and can significantly improve build times and disk access speeds by up to 30% compared to regular NTFS drives.
</TabItem>
<TabItem value={"Linux"}>
Linux requires the standard <code>gcc</code> build tools plus <code>libgtk3</code> and <code>libwebkit</code>. Rather than list a ton of commands for different distros, Wails can try to determine what the installation commands are for your specific distribution. Run <code>wails doctor</code> after installation to be shown how to install the dependencies. If your distro/package manager is not supported, please consult the <a href={"/docs/guides/linux-distro-support"}>Add Linux Distro</a> guide.