Pular para o conteúdo

Como o Wails funciona

O Wails é um framework para construir aplicativos de desktop usando Go para o backend e tecnologias web para o frontend. Mas, ao contrário do Electron, o Wails não empacota um navegador; ele usa o WebView nativo do sistema operacional.

Diagram

Diferenças principais em relação ao Electron:

AspectoWailsElectron
NavegadorWebView fornecido pelo SOChromium empacotado (~100MB)
BackendGo (compilado)Node.js (interpretado)
ComunicaçãoBridge em memóriaIPC (inter-processo)
Tamanho do pacote~15MB~150MB
Memória~10MB~100MB+
Inicialização<0,5s2-3s

O Wails usa o mecanismo de renderização web integrado ao sistema operacional:

WebView2 (Microsoft Edge WebView2)

  • Baseado no Chromium (mesmo do navegador Edge)
  • Pré-instalado no Windows 10/11
  • Atualizações automáticas via Windows Update
  • Suporte completo aos padrões web modernos

Por que isso importa:

  • Sem navegador empacotado → Tamanho do aplicativo menor
  • Nativo do SO → Melhor integração e desempenho
  • Atualizações automáticas → Correções de segurança via atualizações do SO
  • Renderização familiar → Igual ao navegador do sistema

O bridge é o coração do Wails; ele permite comunicação direta entre Go e JavaScript.

Diagram

Como funciona:

  1. Frontend chama um método Go (via binding auto-gerado)
  2. Bridge codifica a chamada para JSON (nome do método + argumentos)
  3. Router encontra o método Go nos serviços registrados
  4. Método Go executa e retorna um valor
  5. Bridge decodifica o resultado e envia de volta ao frontend
  6. Promise é resolvida no JavaScript com o resultado

Características de desempenho:

  • Em memória: Sem sobrecarga de rede, sem HTTP
  • Zero-copy quando possível (para grandes volumes de dados)
  • Assíncrono por padrão: Não bloqueante em ambos os lados
  • Tipado com segurança: Definições de TypeScript geradas automaticamente

Os serviços são a maneira recomendada de expor funcionalidade do Go para o frontend.

// 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, "}),
},
})

Descoberta de serviços:

  • O Wails varre sua struct na inicialização
  • Métodos exportados tornam-se chamáveis do frontend
  • Informações de tipo são extraídas para bindings de TypeScript
  • Tratamento de erros é automático (erros do Go → exceções JS)

Binding de TypeScript gerado:

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

Por que serviços?

  • Tipado com segurança: Suporte completo ao TypeScript
  • Descoberta automática: Sem registro manual de métodos
  • Organizado: Agrupe funcionalidades relacionadas
  • Testável: Serviços são apenas structs Go

Mais informações sobre serviços →

Os eventos permitem comunicação pub/sub entre componentes.

Diagram

Casos de uso:

  • Comunicação entre janelas: Uma janela notifica as outras
  • Tarefas em segundo plano: Serviço Go notifica a UI sobre o progresso
  • Sincronização de estado: Mantém múltiplas janelas sincronizadas
  • Acoplamento fraco: Componentes não precisam de referências diretas

Exemplo:

// 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)
})

Mais informações sobre eventos →

Entender o ciclo de vida ajuda você a saber quando inicializar recursos e fazer a limpeza.

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 →


Dúvidas sobre a arquitetura? Pergunte no Discord ou consulte a referência da API.