gui/docs/ref/wails-v3/quick-start/first-app.mdx
Snider 4bdbb68f46
Some checks failed
Security Scan / security (push) Failing after 9s
Test / test (push) Failing after 1m21s
refactor: update import path from go-config to core/config
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-14 10:26:36 +00:00

270 lines
7.3 KiB
Text

---
title: Your First App
description: Build a working Wails application in 10 minutes
sidebar:
order: 3
---
import { Tabs, TabItem, Steps } from "@astrojs/starlight/components";
We will 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
:::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
<Steps>
1. **Generate the project**
```bash
wails3 init -n myapp
cd myapp
```
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.
Run `wails3 init -l` to see all available templates.
:::
2. **Understand the project structure**
```
myapp/
├── main.go # Application entry point
├── greetservice.go # Greet service
├── frontend/ # Your UI code
│ ├── index.html # HTML entry point
│ ├── src/
│ │ └── 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
```
3. **Run the app**
```bash
wails3 dev
```
:::note[First Run]
The first run may take longer than expected as it installs frontend dependencies, generates bindings, etc. Subsequent runs are much faster.
:::
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 the code that makes this work.
### The Go Backend
Open `greetservice.go`:
```go title="greetservice.go"
package main
import (
"fmt"
)
type GreetService struct{}
func (g *GreetService) Greet(name string) string {
return fmt.Sprintf("Hello %s, It's show time!", name)
}
```
**Key concepts:**
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[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.
**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 {GreetService} from "../bindings/changeme";
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** - `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`.
**Never edit these files manually**—they're regenerated on every build.
:::
## Customize Your App
Let's add a new feature to understand the workflow.
### Add a "Greet Many" Feature
<Steps>
1. **Add the method to GreetService**
Add this to `greetservice.go`:
```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 greetings
}
```
2. **The app will auto-rebuild**
Save the file and `wails3 dev` will automatically rebuild your Go code and restart the app.
:::note[Auto-Rebuild]
Go code changes trigger an automatic rebuild and restart. Frontend changes hot-reload without restart.
:::
3. **Use it in the frontend**
Add this to `frontend/src/main.js`:
```javascript title="frontend/src/main.js"
window.greetMany = async () => {
const names = ['Alice', 'Bob', 'Charlie'];
const greetings = await GreetService.GreetMany(names);
console.log(greetings);
};
```
Open the browser console and call `greetMany()` - you'll see the array of greetings.
</Steps>
## Build for Production
When you're ready to distribute your app:
```bash
wails3 build
```
**What this does:**
- 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/myapp.exe`
Double-click to run. No dependencies needed (WebView2 is part of Windows).
</TabItem>
<TabItem label="macOS" icon="apple">
**Output:** `build/bin/myapp.app`
Drag to Applications folder or double-click to run.
</TabItem>
<TabItem label="Linux" icon="linux">
**Output:** `build/bin/myapp`
Run with `./build/bin/myapp` or create a `.desktop` file for your launcher.
</TabItem>
</Tabs>
:::tip[Cross-Platform Builds]
Want to build for other platforms? See [Cross-Platform Builds →](/guides/build/cross-platform)
:::
## What we've learned
**Project Structure**
- `main.go` for Go backend
- `frontend/` for UI code
- `Taskfile.yml` for build tasks
**Services**
- Create Go structs with exported methods
- Register with `application.NewService()`
- Methods automatically available in frontend
**Bindings**
- Auto-generated TypeScript definitions
- Type-safe function calls
- Async by default (Promises)
**Development Workflow**
- `wails3 dev` for hot reload
- Go changes auto-rebuild and restart
- Frontend changes hot-reload instantly
---
**Questions?** Join [Discord](https://discord.gg/JDdSxwjhGf) and ask the community.