Objectives
-
Understand the architecture of a Wails application.
-
Learn how a Wails program starts.
-
Understand the relationship between Go, Wails and WebView2.
-
Learn how the frontend calls Go functions.
High-Level Architecture
User
│
▼
Native Window
│
▼
WebView2 Engine
│
HTML / CSS / JavaScript
│
Wails JS Bridge
│
▼
Go Backend
│
▼
Windows Operating SystemUnlike a web application:
-
No HTTP server
-
No REST API
-
No localhost
JavaScript communicates directly with Go through the Wails bridge.
Project Structure
AppName/
├── main.go
├── app.go
├── wails.json
├── build/
└── frontend/
├── src/
├── dist/
├── package.json
└── wailsjs/Responsibilities
| Component | Responsibility |
|---|---|
main.go | Application entry point and wiring |
app.go | Backend business logic |
frontend/src | User Interface |
frontend/wailsjs | Generated Go ↔ JavaScript bridge |
build | Packaging resources |
wails.json | Wails configuration |
main.go
Responsibilities
main.go contains almost no application logic.
Its job is simply to assemble the application.
main()
│
▼
NewApp()
│
▼
wails.Run(...)Embedded Frontend
//go:embed all:frontend/dist
var assets embed.FSGo embeds all frontend files directly into the executable.
Result:
AppName.exe
├── Go code
├── HTML
├── CSS
├── JavaScript
└── ImagesThis allows distributing a single executable.
Creating the Backend
app := NewApp()Creates the application’s backend object.
Starting Wails
wails.Run(...)Internally Wails approximately performs:
Create Win32 Window
│
▼
Create WebView2
│
▼
Load embedded HTML
│
▼
Initialize JS ↔ Go bridge
│
▼
Display windowAsset Server
AssetServer: &assetserver.Options{
Assets: assets,
}Instead of serving files over HTTP:
Browser
│
HTTP
│
ServerWails serves directly from Go’s embedded filesystem:
WebView2
│
embed.FSEverything runs inside one process.
Window Configuration
Examples:
Title
Width
Height
BackgroundColourThese configure the native application window.
Startup Callback
OnStartup: app.startupExecuted once after application startup.
Typical responsibilities:
-
Load configuration
-
Initialize services
-
Open databases
-
Prepare application state
Binding Backend Objects
Bind: []interface{}{
app,
}Exports public methods of App to JavaScript.
This is the foundation of frontend ↔ backend communication.
app.go
Application State
type App struct {
ctx context.Context
}Currently the application stores only the Wails context.
Future AppName may contain:
App
├── ctx
├── config
├── history
├── bookmarks
├── settings
└── loggerConstructor
func NewApp() *AppCreates the backend object.
Keeping initialization outside main() keeps the entry point clean.
Startup
func (a *App) startup(ctx context.Context)Stores the runtime context.
The context enables future access to:
-
Native dialogs
-
Clipboard
-
Notifications
-
Window operations
-
Application lifecycle
-
Runtime APIs
Backend Method
func (a *App) Greet(name string) stringThis is only a demonstration.
The important concept is that JavaScript can call Go directly.
End-to-End Flow
When clicking Greet:
User
│
▼
Button Click
│
▼
JavaScript Event
│
▼
Generated Wails Bridge
│
▼
Go: App.Greet()
│
▼
Return String
│
▼
JavaScript receives result
│
▼
Update UINo HTTP.
No REST.
No manual JSON handling.
Traditional Web App vs Wails
Traditional
Browser
│
HTTP
│
Backend
│
JSON
│
BrowserWails
WebView2
│
Native Bridge
│
Go Method
│
Return ValueMental Model
main.go
│
▼
Create App
│
▼
wails.Run()
│
┌──────────┴──────────┐
▼ ▼
Native Window WebView2
│
▼
HTML/CSS/JavaScript
│
▼
Generated Bridge
│
▼
Go Backend
Key Takeaways
-
main.gowires the application together. -
app.gocontains backend logic. -
The frontend is embedded into the executable.
-
Wails creates a native Win32 window.
-
Rendering is provided by Microsoft WebView2.
-
JavaScript communicates directly with Go.
-
Bindexposes Go methods to JavaScript. -
startup()is the initialization hook. -
Apprepresents the backend state.
Questions for Reflection
-
Why does Wails not need an HTTP server?
-
What is the purpose of
Bind? -
Why is
context.Contextstored inApp? -
What files become embedded into the executable?
-
Which file is responsible for wiring the application together?
-
If we add
OpenLab()toApp, how could the frontend invoke it?
Next Session
Frontend Architecture
Topics:
-
frontend/src -
Generated
wailsjs -
JavaScript → Go bridge
-
Go → JavaScript return values
-
Complete request/response lifecycle