DEV Community

Alex Spinov
Alex Spinov

Posted on

Wails v2 Has a Free API: Build Lightweight Desktop Apps with Go and Web Technologies

What is Wails?

Wails lets you build desktop applications using Go for the backend and any web framework for the frontend. Think Electron, but with Go instead of Node.js — resulting in binaries that are 10-50x smaller and use significantly less memory.

Quick Start

go install github.com/wailsapp/wails/v2/cmd/wails@latest
wails init -n myapp -t react-ts
cd myapp
wails dev
Enter fullscreen mode Exit fullscreen mode

You get a native desktop app with React + TypeScript frontend and Go backend, with hot reload.

How It Works

Wails binds Go functions directly to JavaScript — no REST API, no WebSocket, no IPC boilerplate:

// app.go
package main

import "context"

type App struct {
    ctx context.Context
}

func NewApp() *App {
    return &App{}
}

func (a *App) startup(ctx context.Context) {
    a.ctx = ctx
}

// This function is callable from JavaScript!
func (a *App) Greet(name string) string {
    return "Hello " + name + "!"
}

// Complex types work too
type FileInfo struct {
    Name string `json:"name"`
    Size int64  `json:"size"`
    Path string `json:"path"`
}

func (a *App) ListFiles(dir string) ([]FileInfo, error) {
    entries, err := os.ReadDir(dir)
    if err != nil {
        return nil, err
    }
    var files []FileInfo
    for _, e := range entries {
        info, _ := e.Info()
        files = append(files, FileInfo{
            Name: e.Name(),
            Size: info.Size(),
            Path: filepath.Join(dir, e.Name()),
        })
    }
    return files, nil
}
Enter fullscreen mode Exit fullscreen mode

Call Go from React

Wails auto-generates TypeScript bindings:

// frontend/src/App.tsx
import { Greet, ListFiles } from "../wailsjs/go/main/App";

function App() {
  const [greeting, setGreeting] = useState("");
  const [files, setFiles] = useState([]);

  const handleGreet = async () => {
    const result = await Greet("World");
    setGreeting(result); // "Hello World!"
  };

  const handleListFiles = async () => {
    const result = await ListFiles("/home/user");
    setFiles(result); // [{name, size, path}, ...]
  };

  return (
    <div>
      <button onClick={handleGreet}>Greet</button>
      <p>{greeting}</p>
      <button onClick={handleListFiles}>List Files</button>
      {files.map(f => <div key={f.path}>{f.name} ({f.size} bytes)</div>)}
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

No fetch calls. No API routes. Direct function calls with full type safety.

Events System

// Go: emit event
runtime.EventsEmit(a.ctx, "file-processed", filename, progress)

// Go: listen for event
runtime.EventsOn(a.ctx, "user-action", func(data ...interface{}) {
    fmt.Println("User did:", data)
})
Enter fullscreen mode Exit fullscreen mode
// Frontend: listen for event
import { EventsOn } from "../wailsjs/runtime";

EventsOn("file-processed", (filename, progress) => {
  console.log(`${filename}: ${progress}%`);
});
Enter fullscreen mode Exit fullscreen mode

Native Dialogs

import "github.com/wailsapp/wails/v2/pkg/runtime"

func (a *App) OpenFile() (string, error) {
    return runtime.OpenFileDialog(a.ctx, runtime.OpenDialogOptions{
        Title: "Select File",
        Filters: []runtime.FileFilter{
            {DisplayName: "Images", Pattern: "*.png;*.jpg;*.gif"},
        },
    })
}

func (a *App) SaveFile(content string) error {
    path, _ := runtime.SaveFileDialog(a.ctx, runtime.SaveDialogOptions{
        Title: "Save File",
        DefaultFilename: "output.txt",
    })
    return os.WriteFile(path, []byte(content), 0644)
}
Enter fullscreen mode Exit fullscreen mode

Build for All Platforms

# Build for current platform
wails build

# Build with NSIS installer (Windows)
wails build -nsis

# Cross-compile
wails build -platform darwin/amd64
wails build -platform windows/amd64
wails build -platform linux/amd64
Enter fullscreen mode Exit fullscreen mode

Wails vs Electron

Metric Wails Electron
Binary Size 8-15 MB 150-250 MB
Memory Usage 30-50 MB 200-500 MB
Startup Time <1s 2-5s
Backend Go Node.js
Frontend Any web framework Any web framework

Need a lightweight desktop app or Go-powered developer tool?

📧 spinov001@gmail.com
🔧 My tools on Apify Store

Go + web frontend — is this the future of desktop apps? Let me know!

Top comments (0)