Desktop Apps
irgo's desktop mode creates native applications for macOS, Windows, and Linux using a real HTTP server and native webview window.
How Desktop Mode Works
Unlike mobile mode (which uses virtual HTTP), desktop mode:
- Starts a Go HTTP server on an auto-selected localhost port
- Opens a native window with an embedded browser engine (WebKit on macOS, Chromium on Windows/Linux)
- The webview navigates to the localhost URL
┌─────────────────────────────────────────┐│ Desktop App ││ ┌─────────────────────────────────┐ ││ │ Native Webview Window │ ││ │ (Chromium/WebKit) │ ││ │ Navigates to localhost:PORT │ ││ └──────────────┬──────────────────┘ ││ │ HTTP ││ ┌──────────────▼──────────────────┐ ││ │ Go HTTP Server │ ││ │ • Page Routes → HTML │ ││ │ • API Routes → JSON │ ││ │ • Static Assets │ ││ └─────────────────────────────────┘ │└─────────────────────────────────────────┘This architecture means your app works exactly like the web dev server, but packaged as a native desktop application.
Prerequisites
Desktop builds require CGO and a C compiler:
- macOS: Xcode Command Line Tools (
xcode-select --install) - Windows: MinGW-w64 or similar
- Linux: GCC and WebKit2GTK (
apt install build-essential libwebkit2gtk-4.0-dev)
Warning
CGO must be enabled. If you see errors about CGO_ENABLED=0, ensure you have a C compiler installed and set CGO_ENABLED=1.
Desktop Entry Point
Desktop apps use a separate entry point with the desktop build tag:
main_desktop.go
//go:build desktoppackage mainimport ( "flag" "fmt" "net/http" "myapp/app" "github.com/stukennedy/irgo/desktop")func main() { devMode := flag.Bool("dev", false, "Enable devtools") flag.Parse() // Create router r := app.NewRouter() // Set up HTTP handler with static files mux := http.NewServeMux() staticDir := desktop.FindStaticDir() mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir(staticDir)))) mux.Handle("/", r.Handler()) // Configure desktop app config := desktop.DefaultConfig() config.Title = "My App" config.Debug = *devMode // Create and run desktopApp := desktop.New(mux, config) fmt.Println("Starting desktop app...") if err := desktopApp.Run(); err != nil { fmt.Printf("Error: %v\n", err) }}Configuration
config := desktop.Config{ Title: "My App", // Window title Width: 1024, // Initial window width Height: 768, // Initial window height Resizable: true, // Allow window resizing Debug: false, // Enable browser devtools Port: 0, // 0 = auto-select available port}// Or start with defaultsconfig := desktop.DefaultConfig()config.Title = "My App"config.Debug = trueConfiguration Options
| Option | Type | Default | Description |
|---|---|---|---|
Title | string | "Irgo App" | Window title bar text |
Width | int | 1024 | Initial window width in pixels |
Height | int | 768 | Initial window height in pixels |
Resizable | bool | true | Allow window resizing |
Debug | bool | false | Enable browser devtools (right-click inspect) |
Port | int | 0 | Server port (0 = auto-select) |
Running Desktop Apps
# Run directly (compiles and runs)irgo run desktop# With devtools enabled (for debugging)irgo run desktop --devBuilding Desktop Apps
# Build for current platformirgo build desktop# Build for specific platformirgo build desktop macos # Creates build/desktop/macos/MyApp.appirgo build desktop windows # Creates build/desktop/windows/MyApp.exeirgo build desktop linux # Creates build/desktop/linux/myappBuild Output
build/desktop/├── macos/│ └── MyApp.app/ # macOS application bundle│ └── Contents/│ ├── MacOS/│ │ └── myapp # Executable│ ├── Resources/│ │ └── static/ # Static assets│ └── Info.plist # App metadata├── windows/│ └── MyApp.exe # Windows executable└── linux/ └── myapp # Linux binaryUtility Functions
import "github.com/stukennedy/irgo/desktop"// Find static files directory// Works both in dev (./static) and bundled appstaticDir := desktop.FindStaticDir()// Find bundled resources// Looks in app bundle on macOS, same dir as exe on Windows/LinuxresourcePath := desktop.FindResourcePath("config.json")Desktop vs Mobile Comparison
| Aspect | Desktop | Mobile |
|---|---|---|
| HTTP | Real localhost server | Virtual (no sockets) |
| Bridge | None (direct HTTP) | gomobile + native code |
| Entry Point | main_desktop.go | main.go |
| Build Tag | desktop | !desktop |
| CGO Required | Yes (webview) | No |
| DevTools | Native browser devtools | Safari/Chrome remote debugging |
Troubleshooting
CGO Errors
If you see "CGO_ENABLED=0" errors:
# Check CGO is enabledgo env CGO_ENABLED# Set it if neededexport CGO_ENABLED=1# Make sure you have a C compiler# macOSxcode-select --install# Linuxsudo apt install build-essentialWebview Not Showing (Linux)
# Install WebKit2GTKsudo apt install libwebkit2gtk-4.0-devStatic Files Not Found
Use desktop.FindStaticDir() to locate static files. It handles both development and bundled app scenarios.
Next Steps
- Mobile Apps - iOS and Android development
- Deployment - Packaging and distribution
- Examples - Sample desktop applications
