Перейти к содержимому

Как работает Wails

Wails — это фреймворк для создания десктопных приложений, использующий Go для бэкенда и веб-технологии для фронтенда. Но в отличие от Electron, Wails не включает в себя браузер, а использует нативный WebView операционной системы.

Diagram

Ключевые отличия от Electron:

АспектWailsElectron
БраузерWebView от ОСВстроенный Chromium (~100 МБ)
БэкендGo (скомпилированный)Node.js (интерпретируемый)
КоммуникацияМост в памятиIPC (межпроцессное взаимодействие)
Размер бандла~15 МБ~150 МБ
Память~10 МБ~100 МБ+
Запуск<0.5 с2–3 с

Wails использует встроенный движок рендеринга веб-страниц операционной системы:

WebView2 (Microsoft Edge WebView2)

  • Основан на Chromium (тот же, что и в браузере Edge)
  • Предустановлен в Windows 10/11
  • Автоматические обновления через Windows Update
  • Полная поддержка современных веб-стандартов

Почему это важно:

  • Нет встроенного браузера → Меньший размер приложения
  • Нативный для ОС → Лучшая интеграция и производительность
  • Автообновления → Патчи безопасности из обновлений ОС
  • Привычный рендеринг → Тот же, что и в системном браузере

Мост — это сердце Wails, обеспечивающее прямую коммуникацию между Go и JavaScript.

Diagram

Как это работает:

  1. Фронтенд вызывает метод Go (через автоматически сгенерированное связывание)
  2. Мост кодирует вызов в JSON (имя метода + аргументы)
  3. Маршрутизатор находит метод Go в зарегистрированных сервисах
  4. Метод Go выполняется и возвращает значение
  5. Мост декодирует результат и отправляет его обратно на фронтенд
  6. Promise разрешается в JavaScript с результатом

Характеристики производительности:

  • В памяти: Нет накладных расходов сети, нет HTTP
  • Zero-copy там, где это возможно (для больших данных)
  • Асинхронно по умолчанию: Неблокирующе с обеих сторон
  • Типобезопасно: Автоматически генерируются определения TypeScript

Сервисы — это рекомендуемый способ экспорта функциональности Go на фронтенд.

// Define a service (just a regular Go struct)
type GreetService struct {
prefix string
}
// Methods with exported names are automatically available
func (g *GreetService) Greet(name string) string {
return g.prefix + name + "!"
}
func (g *GreetService) GetTime() time.Time {
return time.Now()
}
// Register the service
app := application.New(application.Options{
Services: []application.Service{
application.NewService(&GreetService{prefix: "Hello, "}),
},
})

Обнаружение сервисов:

  • Wails сканирует вашу структуру при запуске
  • Экспортируемые методы становятся доступными для вызова из фронтенда
  • Информация о типах извлекается для связываний TypeScript
  • Обработка ошибок автоматическая (ошибки Go → исключения JS)

Сгенерированное связывание TypeScript:

// Auto-generated in frontend/bindings/GreetService.ts
export function Greet(name: string): Promise<string>
export function GetTime(): Promise<Date>

Почему сервисы?

  • Типобезопасность: Полная поддержка TypeScript
  • Автообнаружение: Не требуется ручная регистрация методов
  • Организованность: Группировка связанной функциональности
  • Тестируемость: Сервисы — это обычные структуры Go

Подробнее о сервисах →

События обеспечивают pub/sub коммуникацию между компонентами.

Diagram

Сценарии использования:

  • Коммуникация между окнами: Одно окно уведомляет другие
  • Фоновые задачи: Сервис Go уведомляет UI о прогрессе
  • Синхронизация состояния: Поддержание синхронности нескольких окон
  • Слабая связанность: Компонентам не нужны прямые ссылки друг на друга

Пример:

// Go: Emit an event
app.Event.Emit("user-logged-in", user)
// JavaScript: Listen for event
import { Events } from '@wailsio/runtime'
Events.On('user-logged-in', (user) => {
console.log('User logged in:', user)
})

Подробнее о событиях →

Понимание жизненного цикла помогает знать, когда инициализировать ресурсы и очищать их.

Diagram

Lifecycle hooks:

app := application.New(application.Options{
Name: "My App",
// Called before windows are created
OnStartup: func(ctx context.Context) {
// Initialise database, load config, etc.
},
// Called when app is about to quit
OnShutdown: func() {
// Save state, close connections, etc.
},
})

Learn more about lifecycle →

Understanding how Wails builds your application:

Diagram

Build steps:

  1. Analyse Go code

    • Scan services for exported methods
    • Extract parameter and return types
    • Generate method signatures
  2. Generate TypeScript bindings

    • Create .ts files for each service
    • Include full type definitions
    • Add JSDoc comments
  3. Build frontend

    • Run your bundler (Vite, webpack, etc.)
    • Minify and optimise
    • Output to frontend/dist/
  4. Compile Go

    • Compile with optimisations (-ldflags="-s -w")
    • Include build metadata
    • Platform-specific compilation
  5. Embed assets

    • Embed frontend files into Go binary
    • Compress assets
    • Create single executable

Result: A single native executable with everything embedded.

Learn more about building →

Wails behaves differently in development and production:

Characteristics:

  • Hot reload: Frontend changes reload instantly
  • Source maps: Debug with original source
  • DevTools: Browser DevTools available
  • Logging: Verbose logging enabled
  • External frontend: Served from dev server (Vite)

How it works:

Diagram

Benefits:

  • Instant feedback on changes
  • Full debugging capabilities
  • Faster iteration

Understanding memory usage helps you build efficient applications.

Memory regions:

  1. Go Heap

    • Your services and application state
    • Managed by Go garbage collector
    • Typically 5-10MB for simple apps
  2. WebView Memory

    • DOM, JavaScript heap, CSS
    • Managed by WebView’s engine
    • Typically 10-20MB for simple apps
  3. Bridge Memory

    • Message buffers for communication
    • Minimal overhead (<1MB)
    • Zero-copy for large data where possible

Optimisation tips:

  • Avoid large data transfers: Pass IDs, fetch details on demand
  • Use events for updates: Don’t poll from frontend
  • Stream large files: Don’t load entirely into memory
  • Clean up listeners: Remove event listeners when done

Learn more about performance →

Wails provides a secure-by-default architecture:

Diagram

Security features:

  1. Method whitelisting

    • Only exported methods are callable
    • Private methods are inaccessible
    • Explicit service registration required
  2. Type validation

    • Arguments checked against Go types
    • Invalid types rejected
    • Prevents injection attacks
  3. No eval()

    • Frontend can’t execute arbitrary Go code
    • Only predefined methods callable
    • No dynamic code execution
  4. Context isolation

    • Each window has its own context
    • Services can check caller context
    • Permissions per window possible

Best practices:

  • Validate user input in Go (don’t trust frontend)
  • Use context for authentication/authorisation
  • Sanitise file paths before file operations
  • Rate limit expensive operations

Learn more about security →

Application Lifecycle - Understand startup, shutdown, and lifecycle hooks
Learn More →

Go-Frontend Bridge - Deep dive into how the bridge works
Learn More →

Build System - Understand how Wails builds your application
Learn More →

Start Building - Apply what you’ve learned in a tutorial Tutorials →


Вопросы об архитектуре? Задавайте их в Discord или смотрите справочник API.