mise, Nix e devcontainers resolvem "works on my machine" — eles só discordam sobre como

A frase "works on my machine" assombra equipes de software há décadas. Um novo desenvolvedor chega, passa dois dias configurando seu ambiente. Um sênior atualiza o Python, quebra três projetos. O CI falha por causa de uma versão de biblioteca que ninguém lembrou de travar. A causa raiz é sempre a mesma: ambientes de desenvolvimento são stateful, implícitos e montados manualmente.
Em 2026, esse problema está genuinamente resolvido — mas "resolvido" significa três ferramentas concorrentes com filosofias radicalmente diferentes. Entender os tradeoffs é a verdadeira habilidade.
Tier 1 — mise: O Ponto de Partida Pragmático
mise (anteriormente rtx) é um gerenciador de versões poliglota escrito em Rust. Ele substitui o asdf sendo 10–20x mais rápido graças ao seu núcleo compilado e resolução paralela de plugins. Ele gerencia Node.js, Python, Go, Ruby, Java e dezenas de outros runtimes a partir de uma única ferramenta.
O mecanismo central é o arquivo .mise.toml na raiz do projeto:
[tools]
node = "22.3.0"
python = "3.12.4"
go = "1.22.5"
[env]
DATABASE_URL = "postgres://localhost/myapp_dev"
Execute mise install e ele lê a config, baixa as versões travadas em um cache local com endereçamento de conteúdo (~/.local/share/mise/installs/) e as ativa para o diretório atual. Sem malabarismos com symlinks, sem hacks de shell além de adicionar mise activate ao seu profile.
A diferença de performance em relação ao asdf não é sutil. Instalar uma versão do Node.js que o asdf leva 45 segundos para resolver e instalar, o mise completa em menos de 4 segundos. Para equipes que trocam constantemente entre projetos com requisitos de runtime diferentes, isso se acumula em uma economia real de tempo.
O que o mise não faz: ele gerencia runtimes de linguagens, não bibliotecas do sistema. Se seu projeto precisa de uma versão específica de libpq, openssl ou ffmpeg, o mise não pode ajudar. Ele também não consegue reproduzir a versão exata do glibc no Linux ou o toolchain exato do Xcode no macOS. Para a maioria dos desenvolvedores de aplicações, essas lacunas não importam. Para todos os outros, continue lendo.
Tier 2 — Nix e Nix Flakes: Reprodbilidade Total
Nix é um gerenciador de pacotes funcional construído em torno de uma ideia: cada pacote é uma função pura de suas entradas. Dadas as mesmas entradas, você sempre obtém a mesma saída. Os pacotes ficam em /nix/store/ sob caminhos endereçados por conteúdo, como /nix/store/ybmrfz0-nodejs-22.3.0/. Dois pacotes podem depender de versões diferentes da mesma biblioteca sem conflito porque literalmente estão em caminhos diferentes.
nixpkgs é o repositório de pacotes: mais de 90.000 pacotes, todos construídos de forma reprodutível, abrangendo todos os principais ecossistemas de linguagens, além de ferramentas de sistema, fontes, bancos de dados e compiladores. É o maior conjunto de pacotes de fonte única de qualquer distribuição Linux.
Nix flakes (estabilizado no NixOS 23.11) adiciona um modelo de dependência orientado por lockfile ao próprio Nix. Um flake.nix na raiz do projeto trava o commit exato do nixpkgs e define um devShell:
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.05";
outputs = { self, nixpkgs }: {
devShells.x86_64-linux.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
packages = with nixpkgs.legacyPackages.x86_64-linux; [
nodejs_22
python312
go_1_22
postgresql_16
ffmpeg
];
};
};
}
Execute nix develop e você cai em um shell onde cada ferramenta está exatamente como especificado — até as versões das bibliotecas C. O arquivo flake.lock trava o SHA do commit do nixpkgs. Seis meses depois, em uma máquina diferente, em um país diferente, nix develop produz o mesmo ambiente.
A curva de aprendizado honesta: O Nix tem sua própria linguagem funcional (também chamada Nix), seu próprio modelo mental de como as builds funcionam e uma documentação que pressupõe familiaridade com conceitos de programação funcional. A maioria dos desenvolvedores leva de 1 a 2 semanas antes de se sentir confortável escrevendo flakes do zero. Ferramentas como devenv.sh e flake-parts reduzem isso significativamente, mas não há atalho para os conceitos fundamentais.
O retorno é real. Equipes que usam Nix flakes relatam zero incidentes de "environment drift" em post-mortems. O CI executa o mesmo shell nix develop que o desenvolvimento local. Novos desenvolvedores executam nix develop no primeiro dia e têm um ambiente funcional em minutos, não em dias.
Tier 3 — devcontainers: Onboarding e Desenvolvimento Cloud-First
devcontainers é uma especificação aberta (apoiada pela Microsoft e usada no VS Code e GitHub Codespaces) que define um ambiente de desenvolvimento como um container Docker. A configuração fica em .devcontainer/devcontainer.json:
{
"name": "My Project",
"image": "mcr.microsoft.com/devcontainers/javascript-node:22",
"features": {
"ghcr.io/devcontainers/features/python:1": { "version": "3.12" },
"ghcr.io/devcontainers/features/go:1": { "version": "1.22" }
},
"postCreateCommand": "npm install",
"customizations": {
"vscode": {
"extensions": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"]
}
}
}
A extensão Remote - Containers do VS Code monta seus arquivos locais dentro do container e executa todo o seu editor dentro dele — language servers, debuggers, terminais, tudo executando no ambiente do container. O GitHub Codespaces leva isso adiante: clique em "Open in Codespaces" e todo o ambiente de desenvolvimento roda na infraestrutura em nuvem do GitHub, não no seu laptop.
Onde os devcontainers vencem: a integração é genuinamente de um clique. O isolamento de segurança é real — o sistema de arquivos do container é separado do seu host. Para tarefas pesadas de computação (treinamento de modelos grandes, renderização de vídeo, compilação de bases de código C++ enormes), delegar para Codespaces com máquinas em nuvem de 32 núcleos é produtividade legítima.
Onde os devcontainers enfrentam dificuldades: a sobrecarga do Docker é real no macOS. O desempenho do sistema de arquivos através da camada da VM do Docker pode ser 2-3x mais lento que o nativo para tarefas intensivas de I/O, como executar um grande conjunto de testes. Você também depende de conectividade de rede e do Docker estar operacional — nenhuma das duas é garantida em todos os contextos de desenvolvimento.
Como Equipes Reais Combinam Essas Ferramentas
A falsa escolha é selecionar uma e ir all-in. Equipes que já descobriram isso geralmente fazem camadas:
- mise para a troca de linguagens no dia a dia. Todo desenvolvedor tem. Ele resolve 90% das questões de "qual versão de Node/Python/Go" com atrito mínimo. O
.mise.tomlé commitado no repositório. - Nix flakes para equipes com requisitos de nível de sistema. Se você precisa de versões específicas de bibliotecas nativas, ou se está construindo tanto no Linux quanto no macOS e precisa de ambientes idênticos,
flake.nixvale o investimento. Algumas equipes usam Nix apenas no CI, obtendo reprodutibilidade onde mais importa. - devcontainers para onboarding e paridade com CI. A config
.devcontainer/é mantida para o primeiro dia do novo desenvolvedor e para acesso ao GitHub Codespaces. Ela não substitui as ferramentas de desenvolvimento local, mas fornece um fallback garantido.
Um exemplo concreto: uma equipe de 12 desenvolvedores usa mise localmente para troca rápida de versões, Nix flakes no CI (GitHub Actions executa nix develop --command make test) e um devcontainer para acesso ao Codespaces quando membros da equipe estão viajando ou em máquinas corporativas bloqueadas.
Os Tradeoffs Honestos
- mise: instala em 30 segundos, funciona em qualquer lugar, resolve 90% dos problemas reais, mas não consegue gerenciar bibliotecas do sistema nem garantir reprodutibilidade binária abaixo do nível do runtime da linguagem.
- Nix: a opção mais poderosa disponível, produz ambientes genuinamente bit-reprodutíveis, cobre todas as camadas da pilha, mas requer investimento real para aprender e pode fazer tarefas simples (adicionar uma nova dependência de pacote) parecerem pesadas até que os conceitos se encaixem.
- devcontainers: a menor barreira de entrada para onboarding, nativo de nuvem, nativo do VS Code, mas carrega sobrecarga do Docker, requer conectividade e pode obscurecer detalhes do ambiente de maneiras que dificultam a depuração.
Por Onde Começar
Se sua equipe tem menos de 5 desenvolvedores e a dor é "cada um está em versões diferentes de Node/Python": instale o mise hoje, commite um .mise.toml, pronto. Você resolverá 90% das reclamações de ambiente em uma tarde.
Se sua equipe tem 10+ desenvolvedores, você está implantando no Linux, tem dependências de bibliotecas nativas e o environment drift já causou incidentes reais de produção: invista em Nix flakes. Reserve 2–3 semanas para que um desenvolvedor se torne o especialista em Nix da equipe. O retorno é genuíno.
Se sua principal dor é o tempo de onboarding, você trabalha muito com GitHub ou precisa de isolamento seguro para contratados: devcontainers são a alavanca certa. Eles compõem bem tanto com mise quanto com Nix — você pode executar o mise dentro de um devcontainer ou construir sua imagem de devcontainer a partir de uma derivação Nix.
O problema do "works on my machine" está resolvido. A questão restante é qual solução se encaixa nas restrições reais da sua equipe — e se você está disposto a pagar os custos de aprendizado que as opções mais poderosas exigem.