Nix como pegamento: tooling de última generación sobre un legacy que no puedes tocar


25 de junio de 2026

El problema que todos conocemos

Tienes un proyecto viejo. De los que funcionan, facturan y nadie quiere tocar. Tira de una versión de Node de hace cinco años porque su cadena de build (webpack antiguo, plugins que ya no se mantienen) se cae con cualquier cosa más nueva. Migrarlo es un proyecto en sí mismo, y no toca este trimestre.

Y un día quieres meterle una herramienta moderna. En mi caso, un harness de navegador (Playwright) para automatizar pruebas. Playwright quiere Node 18 o superior. Tu proyecto vive en Node 16. Chocan.

La salida típica es fea: malabares con nvm (acuérdate de cambiar de versión según qué comando lanzas), un Dockerfile a medida que se pudre, o el clásico "en mi máquina funciona" que en la del compañero no. Estás intentando hacer convivir dos épocas distintas en un mismo árbol de código, y las herramientas de toda la vida no están pensadas para eso.

El cambio de mentalidad

Aquí es donde un flake de Nix deja de ser "una forma rara de instalar dependencias" y se convierte en otra cosa: una manera de declarar y componer entornos enteros.

La clave es que un flake puede exponer varios devShells independientes. No tienes que elegir UNA versión de Node para todo el proyecto. Puedes tener:

Cada uno es reproducible, aislado, y se materializa con un comando. No se pisan.

{
  outputs = { self, nixpkgs, ... }:
    let pkgs = import nixpkgs { system = "x86_64-linux"; };
    in {
      devShells.x86_64-linux = {
        # Entorno LEGACY: el Node viejo para construir, tal cual.
        default = pkgs.mkShell {
          buildInputs = [ node16 ];   # tu derivación del Node antiguo
        };

        # Entorno MODERNO: Node nuevo + harness + navegadores del store.
        e2e = pkgs.mkShell {
          buildInputs = [ pkgs.nodejs_20 pkgs.playwright-driver.browsers ];
          shellHook = ''
            export PLAYWRIGHT_BROWSERS_PATH=${pkgs.playwright-driver.browsers}
            export PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
          '';
        };
      };
    };
}

nix develop te da el entorno legacy para compilar. nix develop .#e2e te da el moderno para el harness. El mismo repositorio, dos toolchains que en circunstancias normales se odiarían, conviviendo en paz.

El detalle que lo hace redondo: los navegadores también del store

Playwright normalmente descarga sus navegadores la primera vez. Eso es una fuente clásica de "a mí me va y a ti no": versiones distintas, descargas que fallan, binarios que en según qué sistema ni arrancan.

Si los coges del propio repositorio de paquetes de Nix (playwright-driver.browsers), desaparece el problema: el navegador es una dependencia declarada más, idéntica para todo el mundo, sin descargas. El único peaje es que la versión del paquete npm del harness tiene que casar con la que trae Nix; se fija una vez y listo. A cambio, el entorno es bit a bit el mismo en tu portátil, en el del compañero y en CI.

Bonus: probar tu build local contra la web real, sin desplegar

Ya puestos, el harness abre una puerta muy golosa. Imagina que tu código se publica como una librería embebible —pongamos un reproductor, =player.js=— servida desde un CDN, y que la página real (con sus datos, su backend, todo de verdad) la carga desde ahí. El ciclo tradicional para probar un cambio es: compilar, desplegar a un entorno de pruebas, mirar. Lento.

Con el harness puedes interceptar la petición a ese player.js del CDN y responder con tu build local:

await context.route('**/player.js', (route) => {
  route.fulfill({ body: fs.readFileSync('./dist/player.js') });
});
await page.goto('https://la-web-real.ejemplo.com/una-pagina');

El navegador carga la página real entera, pero tu código corre desde el disco. Si además compilas en modo desarrollo (sin minificar, con source maps) puedes poner breakpoints y depurar tu cambio sobre la web de verdad. Junta eso con un --watch que recompila al guardar, y el ciclo pasa de "compilar → desplegar → mirar" a "guardar → F5 → ver". En un legacy, eso es oro.

La moraleja

No hace falta modernizar un proyecto entero para trabajar con herramientas de hoy. A veces el movimiento inteligente no es reescribir lo viejo, sino construir alrededor un entorno que deje convivir lo viejo y lo nuevo sin que se peleen.

Nix, visto así, no es un gestor de paquetes excéntrico: es pegamento entre épocas. Y lo bonito es que ese pegamento es reproducible — lo que montas hoy en tu máquina, lo monta igual cualquiera mañana, sin un README de veinte pasos que nadie sigue.

A veces la mejor forma de avanzar con lo viejo es darle, por fuera, las comodidades de lo nuevo.

Comparte este post:

Es tu post

Estas seguro? Esto no se puede deshacer.

Comentarios (0)

Sin comentarios todavia. Se el primero!

Deja un comentario