---
title: "Zig e WebAssembly — Ferramentas, Compilação e Runtime WASM"
url: "https://ziglang.com.br/ecossistema/zig-e-webassembly-ferramentas-compila%C3%A7%C3%A3o-e-runtime-wasm/"
markdown_url: "https://ziglang.com.br/ecossistema/zig-e-webassembly-ferramentas-compila%C3%A7%C3%A3o-e-runtime-wasm.MD"
description: "Guia completo de WebAssembly com Zig: compilação para WASM, WASI, interop JavaScript, otimização de binários e casos de uso práticos."
date: "2026-02-21"
author: "Zig Brasil"
---

# Zig e WebAssembly — Ferramentas, Compilação e Runtime WASM

Guia completo de WebAssembly com Zig: compilação para WASM, WASI, interop JavaScript, otimização de binários e casos de uso práticos.


# Zig e WebAssembly — Ferramentas, Compilação e Runtime WASM

O Zig é uma das melhores linguagens para desenvolvimento WebAssembly. Com suporte nativo a WASM como target de compilação, binários extremamente pequenos e controle total sobre alocação de memória, o Zig produz módulos WASM que frequentemente são menores e mais rápidos que equivalentes em C, C++ ou Rust.

## Por Que Zig para WebAssembly

O Zig possui características que o tornam ideal para WASM:

- **Binários minúsculos**: Um hello world WASM em Zig pode ter menos de 1 KB
- **Sem runtime**: Nenhum código de inicialização oculto no binário
- **Controle de memória**: Sem GC, ideal para o modelo de memória linear do WASM
- **Compilação nativa**: `wasm32-freestanding` e `wasm32-wasi` são targets de primeira classe
- **Interop C**: Use qualquer biblioteca C compilável para WASM

## Compilando para WebAssembly

### Target wasm32-freestanding (Browser)

```zig
// src/lib.zig
export fn somar(a: i32, b: i32) i32 {
    return a + b;
}

export fn fatorial(n: u32) u64 {
    if (n <= 1) return 1;
    var resultado: u64 = 1;
    var i: u32 = 2;
    while (i <= n) : (i += 1) {
        resultado *= i;
    }
    return resultado;
}

export fn fibonacci(n: u32) u64 {
    if (n <= 1) return n;
    var a: u64 = 0;
    var b: u64 = 1;
    var i: u32 = 2;
    while (i <= n) : (i += 1) {
        const temp = a + b;
        a = b;
        b = temp;
    }
    return b;
}
```

```bash
# Compilar para WASM
zig build-lib src/lib.zig -target wasm32-freestanding -dynamic -O ReleaseSmall
```

### build.zig para WASM

```zig
const std = @import("std");

pub fn build(b: *std.Build) void {
    const optimize = b.standardOptimizeOption(.{});

    const lib = b.addSharedLibrary(.{
        .name = "app",
        .root_source_file = b.path("src/lib.zig"),
        .target = b.resolveTargetQuery(.{
            .cpu_arch = .wasm32,
            .os_tag = .freestanding,
        }),
        .optimize = optimize,
    });

    // Exportar tabela de memória
    lib.export_memory = true;
    lib.initial_memory = 65536; // 1 página (64KB)

    b.installArtifact(lib);
}
```

### Usando no Browser

```html
<!DOCTYPE html>
<html>
<head><title>Zig WASM Demo</title></head>
<body>
<script>
async function init() {
    const response = await fetch('app.wasm');
    const bytes = await response.arrayBuffer();
    const { instance } = await WebAssembly.instantiate(bytes, {
        env: {
            // Funções importadas do JavaScript
            log: (valor) => console.log('Zig diz:', valor),
        }
    });

    // Chamar funções exportadas do Zig
    console.log('2 + 3 =', instance.exports.somar(2, 3));
    console.log('10! =', instance.exports.fatorial(10));
    console.log('fib(20) =', instance.exports.fibonacci(20));
}

init();
</script>
</body>
</html>
```

## WASI — WebAssembly System Interface

Para aplicações que precisam de acesso ao sistema de arquivos e rede:

```zig
// src/main.zig - WASI
const std = @import("std");

pub fn main() !void {
    const stdout = std.io.getStdOut().writer();
    try stdout.print("Olá do Zig WASI!\n", .{});

    // Acessar argumentos
    var args = std.process.args();
    while (args.next()) |arg| {
        try stdout.print("Arg: {s}\n", .{arg});
    }

    // Acessar variáveis de ambiente
    const path = std.posix.getenv("PATH") orelse "não definido";
    try stdout.print("PATH: {s}\n", .{path});
}
```

```bash
# Compilar para WASI
zig build-exe src/main.zig -target wasm32-wasi -O ReleaseSmall

# Executar com wasmtime
wasmtime main.wasm

# Executar com wasmer
wasmer main.wasm
```

## Interação Avançada com JavaScript

### Passando Strings

```zig
// Zig: exportar string para JavaScript
var buffer: [1024]u8 = undefined;

export fn obter_saudacao(nome_ptr: [*]const u8, nome_len: usize) usize {
    const nome = nome_ptr[0..nome_len];
    const resultado = std.fmt.bufPrint(&buffer, "Olá, {s}! Bem-vindo ao Zig WASM.", .{nome}) catch return 0;
    return resultado.len;
}

export fn obter_buffer_ptr() [*]const u8 {
    return &buffer;
}
```

```javascript
// JavaScript: trocar strings com Zig
const encoder = new TextEncoder();
const decoder = new TextDecoder();

function saudar(nome) {
    const nomeBytes = encoder.encode(nome);
    const memory = instance.exports.memory;
    const memView = new Uint8Array(memory.buffer);

    // Copiar nome para memória WASM
    const nomePtr = instance.exports.__heap_base;
    memView.set(nomeBytes, nomePtr);

    // Chamar função Zig
    const resultLen = instance.exports.obter_saudacao(nomePtr, nomeBytes.length);
    const bufPtr = instance.exports.obter_buffer_ptr();

    // Ler resultado
    const resultado = decoder.decode(memView.slice(bufPtr, bufPtr + resultLen));
    console.log(resultado);
}
```

### Canvas e Gráficos

```zig
// Renderização em canvas via WASM
const LARGURA: u32 = 800;
const ALTURA: u32 = 600;
var framebuffer: [LARGURA * ALTURA * 4]u8 = undefined;

export fn obter_framebuffer() [*]u8 {
    return &framebuffer;
}

export fn obter_largura() u32 {
    return LARGURA;
}

export fn obter_altura() u32 {
    return ALTURA;
}

export fn renderizar(tempo: f64) void {
    for (0..ALTURA) |y| {
        for (0..LARGURA) |x| {
            const idx = (y * LARGURA + x) * 4;
            const fx = @as(f32, @floatFromInt(x)) / @as(f32, @floatFromInt(LARGURA));
            const fy = @as(f32, @floatFromInt(y)) / @as(f32, @floatFromInt(ALTURA));
            _ = tempo;

            framebuffer[idx + 0] = @intFromFloat(fx * 255); // R
            framebuffer[idx + 1] = @intFromFloat(fy * 255); // G
            framebuffer[idx + 2] = 128;                       // B
            framebuffer[idx + 3] = 255;                       // A
        }
    }
}
```

## Otimização de Tamanho

Técnicas para minimizar o binário WASM:

```bash
# Usar ReleaseSmall
zig build -Doptimize=ReleaseSmall -Dtarget=wasm32-freestanding

# Strip de seções desnecessárias
wasm-strip output.wasm

# Otimizar com wasm-opt (Binaryen)
wasm-opt -O3 -o output-opt.wasm output.wasm
```

| Otimização | Tamanho típico |
|---|---|
| Debug | ~50 KB |
| ReleaseSafe | ~20 KB |
| ReleaseFast | ~15 KB |
| ReleaseSmall | ~5 KB |
| ReleaseSmall + strip | ~2 KB |
| ReleaseSmall + wasm-opt | ~1.5 KB |

## Edge Computing com WASM

O Zig é usado por empresas como [Cloudflare](/cases/case-cloudflare-zig/) para Workers WASM em edge computing, aproveitando o startup rápido e tamanho mínimo dos binários.

## Boas Práticas

1. **Use `ReleaseSmall`** para binários web — cada byte conta
2. **Minimize imports** — reduza dependências do host
3. **Pré-aloque memória** — evite crescimento dinâmico da memória WASM
4. **Teste em múltiplos runtimes** — wasmtime, wasmer, browser
5. **Profile com ferramentas WASM** — use wasm-opt analyze para identificar gargalos

## Próximos Passos

Explore as [bibliotecas gráficas](/ecossistema/zig-graphics-libs/) para renderização WASM, os [frameworks web](/ecossistema/httpz-web/) para backends WASI, e o [case da Cloudflare](/cases/case-cloudflare-zig/) para uso em produção. Consulte nossos [tutoriais](/tutoriais/) para projetos WASM práticos.
