Zig Package Registry: Como Publicar Módulos para a Comunidade

O Zig Package Registry é o repositório oficial de pacotes da linguagem Zig. Embora ainda em desenvolvimento ativo (Zig está em fase de pré-lançamento), o ecossistema já permite que você publique bibliotecas reutilizáveis e compartilhe seu código com milhares de desenvolvedores ao redor do mundo.

Neste tutorial completo, você vai aprender desde como preparar seu pacote para publicação até o workflow de distribuição, versionamento semântico e manutenção contínua. Ao final, você terá uma biblioteca Zig publicada e disponível para qualquer pessoa usar com um simples zig fetch.

Dica: Se você ainda não está familiarizado com o sistema básico de pacotes do Zig (build.zig.zon, dependências, módulos), recomendamos começar com o nosso tutorial Zig Packaging: Módulos e Dependências antes de prosseguir aqui.

O Que é o Zig Package Registry?

A Visão do Ecossistema Zig

O Zig Package Registry é parte de uma visão maior para o ecossistema Zig:

  1. Distribuição descentralizada — Pacotes são identificados por hash de conteúdo, não por nome
  2. Reprodutibilidade garantida — O mesmo build sempre usa o mesmo código
  3. Sem registro central obrigatório — Você pode distribuir de qualquer URL
  4. Curadoria da comunidade — O registro oficial lista pacotes verificados

O Registro Atual

Atualmente, o registro oficial pode ser encontrado em:

Nota importante: O Zig Package Registry ainda está em desenvolvimento ativo. A interface pode mudar, mas os princípios fundamentais (URLs + hashes) permanecem estáveis.

Preparando seu Pacote para Publicação

Checklist Pré-Publicação

Antes de publicar, verifique cada item:

## Checklist de Qualidade

### Código
- [ ] `zig build` funciona sem erros
- [ ] `zig build test` passa todos os testes
- [ ] `zig fmt` formatação aplicada
- [ ] Sem warnings de compilação
- [ ] Código documentado com `///`

### Estrutura
- [ ] Arquivos organizados em src/
- [ ] build.zig.zon configurado
- [ ] README.md completo
- [ ] LICENSE presente
- [ ] CHANGELOG.md atualizado

### Documentação
- [ ] Descrição clara do propósito
- [ ] Exemplos de uso funcionais
- [ ] API documentada
- [ ] Instruções de instalação
- [ ] Badges de CI/LICENSE

### Publicação
- [ ] Versão segue semver
- [ ] .paths não inclui arquivos desnecessários
- [ ] Tag Git criada
- [ ] Release no GitHub
- [ ] Testado em múltiplas plataformas

Estrutura Mínima de um Pacote Publicável

minha-lib/
├── build.zig
├── build.zig.zon      # ← Essencial!
├── src/
│   └── root.zig       # ← Ponto de entrada
├── README.md          # ← Essencial!
├── LICENSE            # ← Essencial!
├── CHANGELOG.md       # ← Recomendado
└── .gitignore

Configurando o build.zig.zon

O build.zig.zon é seu arquivo de manifesto. Veja um exemplo otimizado para publicação:

.{
    .name = .@"minha-lib",
    .version = "1.0.0",
    .fingerprint = 0x12345678,  // Gerado automaticamente
    .minimum_zig_version = "0.15.0",
    
    .dependencies = .{
        // Dependências externas (se houver)
        // .outra_lib = .{ .url = "...", .hash = "..." },
    },
    
    .paths = .{
        // APENAS arquivos necessários
        "build.zig",
        "build.zig.zon",
        "src",
        "LICENSE",
        "README.md",
        "CHANGELOG.md",
    },
}

Campos obrigatórios para publicação:

CampoDescrição
.nameNome único do pacote (prefixado com @)
.versionVersão semântica (semver)
.fingerprintHash único gerado pelo Zig
.pathsArquivos incluídos na distribuição

Criando um README Profissional

Um bom README é crucial para adoção. Veja um template:

# minha-lib

[![CI](https://github.com/user/repo/workflows/CI/badge.svg)](https://github.com/user/repo/actions)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Zig Version](https://img.shields.io/badge/Zig-0.15.0-orange.svg)](https://ziglang.org)

> Descrição curta e clara do que faz a biblioteca (1-2 frases)

## 🚀 Instalação

Adicione ao seu `build.zig.zon`:

```bash
zig fetch --save git+https://github.com/user/minha-lib#v1.0.0

Configure no build.zig:

const lib = b.dependency("minha_lib", .{});
exe.root_module.addImport("minha_lib", lib.module("minha_lib"));

📖 Uso

const minha_lib = @import("minha_lib");

pub fn main() !void {
    const result = minha_lib.funcaoPrincipal();
    // ...
}

📚 Documentação

🧪 Testes

zig build test

📄 Licença

MIT


### Escolhendo uma Licença

Licenças recomendadas para projetos Zig:

| Licença | Uso |
|---------|-----|
| **MIT** | Mais permissiva, recomendada para bibliotecas |
| **Apache-2.0** | Boa para projetos corporativos |
| **Zlib** | Muito permissiva (usada pelo próprio Zig) |
| **BSD-3-Clause** | Permissiva com proteção de marca |

**Comparação rápida:**

MIT: Use, modifique, distribua, comercialize — apenas mantenha o copyright Apache: Igual ao MIT + proteção patente explícita GPL: Se usar, seu código também deve ser GPL (copyleft forte) CC0: Domínio público, sem restrições


## Versionamento Semântico (Semver)

### Regras do Semver

O Zig adota semver rigorosamente. Siga estas regras:

versão: MAJOR.MINOR.PATCH │ │ │ │ │ └── Correções de bugs │ │ (backward compatible) │ │ │ └——– Novas funcionalidades │ (backward compatible) │ └————— Breaking changes (incompatible com versões anteriores)

Exemplos: 1.0.0 → Primeiro release estável 1.1.0 → Nova feature (não quebra nada) 1.1.1 → Bugfix apenas 2.0.0 → Breaking changes (cuidado!)


### Quando Incrementar?

| Mudança | Incremento | Exemplo |
|---------|------------|---------|
| Correção de bug | PATCH | `1.0.0` → `1.0.1` |
| Nova feature | MINOR | `1.0.0` → `1.1.0` |
| Breaking change | MAJOR | `1.0.0` → `2.0.0` |
| Refatoração interna | PATCH | `1.0.0` → `1.0.1` |
| Atualização de docs | PATCH | `1.0.0` → `1.0.1` |

### Breaking Changes no Zig

No contexto Zig, consideramos **breaking change**:

```zig
// ✅ Mudança PATCH (não quebra)
// Adicionar novo parâmetro com default
pub fn funcao(a: i32, b: i32, c: i32) void  // v1.0.0
pub fn funcao(a: i32, b: i32) void          // v1.0.1 (simplificação)

// ❌ Mudança MAJOR (quebra)
// Alterar tipo de retorno
pub fn calcula() i32 { return 42; }         // v1.0.0
pub fn calcula() !i32 { return 42; }        // v2.0.0 (mudou de i32 para !i32)

// ❌ Mudança MAJOR (quebra)
// Remover função pública
pub fn funcao_antiga() void { ... }         // v1.0.0
// (removida)                                 // v2.0.0

// ✅ Mudança MINOR (nova feature)
// Adicionar nova função
pub fn funcao_nova() void { ... }           // Adicionada em v1.1.0

Mantendo um CHANGELOG

Um CHANGELOG bem mantido ajuda usuários a entenderem o que mudou:

# Changelog

Todas as mudanças notáveis deste projeto serão documentadas neste arquivo.

O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.0.0/)
e este projeto adere ao [Semantic Versioning](https://semver.org/lang/pt-BR/).

## [1.1.0] - 2026-02-11

### Added
- Nova função `parseFast()` para parsing otimizado
- Suporte a custom allocators em todo o codebase
- Método `toString()` na struct Principal

### Changed
- Melhoria de performance: 20% mais rápido em arquivos grandes
- Documentação atualizada com novos exemplos

### Fixed
- Corrigido memory leak em `processData()` (#12)
- Tratamento de erro em URLs malformadas

## [1.0.1] - 2026-02-01

### Fixed
- Corrigida regressão na função `calculate()` (#8)
- Build quebrado no Windows (#9)

## [1.0.0] - 2026-01-15

### Added
- Release inicial da biblioteca
- Parsing completo de JSON
- Serialização básica
- Suporte a todos os tipos primitivos

O Workflow de Publicação

Etapa 1: Preparação Final

Antes de publicar, execute uma série de verificações:

#!/bin/bash
# pre-publish.sh - Script de verificação

set -e  # Sai em caso de erro

echo "🔍 Verificando build..."
zig build

echo "🧪 Executando testes..."
zig build test

echo "📝 Verificando formatação..."
zig fmt --check src/

echo "🔎 Verificando warnings..."
zig build -Dwarnings=true

echo "✅ Todas as verificações passaram!"

Etapa 2: Atualizando a Versão

# 1. Atualize a versão no build.zig.zon
#    Edit manualmente: .version = "1.1.0"

# 2. Atualize o CHANGELOG
#    Adicione nova seção com a data de hoje

# 3. Commit das mudanças
git add -A
git commit -m "chore: bump version to 1.1.0"

Etapa 3: Criando a Tag Git

A tag Git identifica o release no seu repositório:

# Criar tag anotada (recomendado)
git tag -a v1.1.0 -m "Release v1.1.0: Performance improvements and bug fixes"

# Push da tag
git push origin v1.1.0

# Ou push de todas as tags
git push origin --tags

Nota: Use v como prefixo (v1.0.0) para seguir convenções do GitHub.

Etapa 4: Criando o Release no GitHub

  1. Acesse seu repositório no GitHub
  2. Clique em “Releases” → “Draft a new release”
  3. Escolha a tag v1.1.0
  4. Título: v1.1.0 ou nome descritivo
  5. Descrição: Copie do CHANGELOG
  6. Opcional: Anexe binários pré-compilados
  7. Publique o release

Etapa 5: Distribuição

Com o release publicado, seu pacote está disponível em:

# Usando a URL do tarball GitHub
zig fetch --save https://github.com/user/minha-lib/archive/refs/tags/v1.1.0.tar.gz

# Ou usando Git diretamente (recomendado)
zig fetch --save git+https://github.com/user/minha-lib#v1.1.0

Gerenciando Múltiplos Releases

Suportando Múltiplas Versões

Às vezes você precisa manter branches de versões anteriores:

# Branch principal (desenvolvimento)
git checkout main

# Criar branch de manutenção para v1.x
git checkout -b release-1.x v1.0.0

# Aplicar correções
git checkout release-1.x
# (faz commits de correção)
git tag -a v1.0.1
git push origin v1.0.1

Deprecando Funcionalidades

Quando precisar remover algo, faça gradualmente:

// v1.0.x - Marcar como deprecated
pub fn funcao_antiga() void {
    @compileError("Use `funcao_nova()` instead. Deprecated in v2.0.0");
}

// v2.0.0 - Remover completamente
// (não existe mais)

Boas Práticas de Publicação

1. Teste em Múltiplas Plataformas

# Teste local
zig build test

# Cross-compilation test
zig build -Dtarget=x86_64-linux-gnu
zig build -Dtarget=x86_64-windows-gnu
zig build -Dtarget=aarch64-macos

# CI recomendada (GitHub Actions)

2. Configure CI/CD

Exemplo de workflow GitHub Actions:

# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
    tags: ['v*']
  pull_request:
    branches: [main]

jobs:
  test:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        zig-version: [0.15.0]
    
    runs-on: ${{ matrix.os }}
    
    steps:
      - uses: actions/checkout@v4
      
      - uses: goto-bus-stop/setup-zig@v2
        with:
          version: ${{ matrix.zig-version }}
      
      - name: Build
        run: zig build
      
      - name: Test
        run: zig build test
      
      - name: Check formatting
        run: zig fmt --check src/

3. Documentação Automática

# Gerar documentação
zig build --prefix docs/

# O Zig gera HTML a partir de comentários `///`
# Publique docs/ no GitHub Pages

4. Segurança e Audit

# Verificar dependências (quando tool oficial existir)
# zig audit

# Por enquanto, verifique manualmente:
cat build.zig.zon  # Revise URLs
# - Confirme que você confia no autor
# - Verifique o hash do código fonte

Casos de Uso Comuns

Caso 1: Biblioteca de Utilitários

Exemplo completo: biblioteca de manipulação de strings.

Estrutura:

zig-string-utils/
├── build.zig
├── build.zig.zon
├── src/
│   ├── root.zig
│   ├── split.zig
│   ├── trim.zig
│   └── utils.zig
├── README.md
├── LICENSE
└── CHANGELOG.md

Publicação:

zig fetch --save git+https://github.com/user/zig-string-utils#v1.0.0

Caso 2: Bindings para C

Biblioteca que expõe biblioteca C via FFI:

// src/root.zig
const c = @cImport({
    @cInclude("mathlib.h");
});

pub fn add(a: f64, b: f64) f64 {
    return c.math_add(a, b);
}

Publique como qualquer outro pacote — usuários nem precisam saber que há C por baixo.

Caso 3: Aplicação com Plugins

Sua aplicação suporta plugins via pacotes:

// build.zig
const plugin_dep = b.dependency("meu_plugin", .{});
exe.root_module.addImport("plugin", plugin_dep.module("plugin"));

Troubleshooting de Publicação

Problema: Hash Mismatch ao Adicionar

Causa: O hash no build.zig.zon não corresponde ao tarball.

Solução:

# Remova o hash incorreto
# Execute build para ver o hash esperado
zig build --fetch

# Copie o hash do erro para o build.zig.zon

Problema: Pacote Não Aparece no Busca

Causa: O registro requer indexação manual ou mencionamento.

Solução:

  1. Garanta que o repositório é público
  2. Mencione em comunidades (Discord, Reddit r/Zig)
  3. Adicione ao índice comunitário via PR

Problema: Dependência quebra com nova versão

Causa: Semver não foi seguido rigorosamente.

Prevenção:

// Sempre use versões específicas
.url = "git+https://github.com/user/lib#v1.0.0",  // ✅
// NÃO: #main ou #latest                            // ❌

Problema: Build quebra em outra máquina

Causa: Arquivos necessários não estão em .paths.

Debug:

# Verifique o que está incluído
zig build --prefix temp/
ls -la temp/

# Compare com seu repositório
# Adicione arquivos faltantes em .paths

Recursos para Publicadores

Ferramentas Recomendadas

FerramentaUso
zig fmtFormatação automática
zig build testTestes
GitHub ActionsCI/CD
zig build --prefix docsDocumentação
GitHub ReleasesDistribuição

Comunidades

Bibliotecas para Estudar

Analise como estas bibliotecas populares são estruturadas:

BibliotecaDescriçãoURL
zulUtilitários geraisgithub.com/vsrinivas/zul
zBenchBenchmarkinggithub.com/hendriknielaender/zBench
zglOpenGL bindingsgithub.com/ziglibs/zgl
zig-gamedevColeção de game devgithub.com/michal-z/zig-gamedev
wsWebSocket servergithub.com/karlseguin/websocket.zig

Exemplo Completo: Publicando uma Biblioteca

Vamos publicar uma biblioteca de manipulação de datas (zig-datetime):

1. Inicialização

mkdir zig-datetime && cd zig-datetime
zig init

2. Desenvolvimento da API

// src/root.zig
const std = @import("std");

/// Representa uma data do calendário gregoriano.
pub const Date = struct {
    year: i32,
    month: u8,
    day: u8,

    /// Cria uma nova data.
    pub fn init(year: i32, month: u8, day: u8) !Date {
        try validate(year, month, day);
        return .{ .year = year, .month = month, .day = day };
    }

    /// Formata a data como string (YYYY-MM-DD).
    pub fn format(
        self: Date,
        comptime fmt: []const u8,
        options: std.fmt.FormatOptions,
        writer: anytype,
    ) !void {
        _ = fmt;
        _ = options;
        try writer.print("{d:0>4}-{d:0>2}-{d:0>2}", .{
            self.year, self.month, self.day,
        });
    }

    fn validate(year: i32, month: u8, day: u8) !void {
        if (month < 1 or month > 12) return error.InvalidMonth;
        if (day < 1 or day > 31) return error.InvalidDay;
        // (simplificado — precisaria considerar meses com 30/28 dias)
    }
};

3. Testes

const testing = std.testing;

test "Date.init valid dates" {
    const d = try Date.init(2026, 2, 11);
    try testing.expectEqual(@as(i32, 2026), d.year);
    try testing.expectEqual(@as(u8, 2), d.month);
    try testing.expectEqual(@as(u8, 11), d.day);
}

test "Date.init invalid month" {
    try testing.expectError(error.InvalidMonth, Date.init(2026, 13, 1));
    try testing.expectError(error.InvalidMonth, Date.init(2026, 0, 1));
}

4. Documentação README

# zig-datetime

Manipulação de datas e horários em Zig.

## Instalação

```bash
zig fetch --save git+https://github.com/user/zig-datetime#v1.0.0

Uso

const datetime = @import("zig-datetime");

const date = try datetime.Date.init(2026, 2, 11);
std.debug.print("Hoje: {}\n", .{date});

### 5. Configuração Final

```zig
// build.zig.zon
.{
    .name = .@"zig-datetime",
    .version = "1.0.0",
    .fingerprint = 0xabcdef12,
    .dependencies = .{},
    .paths = .{"build.zig", "build.zig.zon", "src", "LICENSE", "README.md"},
}

6. Publicação

# Commit e tag
git add -A
git commit -m "feat: initial release v1.0.0"
git tag -a v1.0.0 -m "Initial release"
git push origin main --tags

# Release no GitHub
# (interface web)

# Uso por terceiros
zig fetch --save git+https://github.com/user/zig-datetime#v1.0.0

Próximos Passos

Agora que você sabe como publicar pacotes Zig:

  1. 📦 Zig Packaging: Módulos e Dependências — Aprofunde no sistema de pacotes
  2. 🔧 Zig Build System — Domine o build.zig
  3. 🌐 Zig e WebAssembly — Publique bibliotecas para web
  4. 🧪 Testes em Zig — Garanta qualidade antes de publicar

Compartilhe sua biblioteca com a comunidade no Discord do Zig e no Reddit r/Zig!


Última atualização: 11 de fevereiro de 2026 • Zig versão 0.15.0

Encontrou um erro ou tem sugestões? Contribua com nosso repositório no GitHub.

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.