Desde hace un tiempo que en cualquier proyecto personal de código que empiezo, termino usando tres tecnologías: y es un ecosistema enorme y muy versátil, pero en este contexto lo que nos interesa es que podemos usar esta herramienta para declarar todas las utilidades necesarias para correr un proyecto, compilarlo, hacer linting, etc., y sin usar contenedores. Es compatible con casi cualquier entorno tipo Unix, o sea Linux, macOS y Windows bajo WSL.
En particular, lo que uso es algo llamado “flake”. Este es un archivo de nombre flake.nix que se pone en la raíz del proyecto, y es donde declaramos los paquetes que necesita.
Partamos con un ejemplo simple:
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
};
outputs = {nixpkgs, ...}: let
pkgs = import nixpkgs {system = "aarch64-darwin";};
in {
devShell."aarch64-darwin" = pkgs.mkShell {
buildInputs = [
pkgs.elmPackages.elm
pkgs.elmPackages.elm-format
pkgs.elmPackages.elm-test
pkgs.just
pkgs.nushell
];
};
};
}
Con esto, hemos definido un entorno que contiene algunas herramientas para un proyecto . No es el oficial, pero es mejor en varios aspectos, entre ellos, viene con flakes activados por defecto, funciona mejor en macOS, y también incluye una forma fácil de desinstalar. Corre el script de abajo en tu terminal para instalarlo (o copia el script de la dirección vinculada arriba). Cuidado: Cuando te pregunte si instalar “Determinate Nix”, ponle que no. Ese es un fork, y lo que queremos es instalar Nix oficial.
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
Si por otro lado ya tienes instalado Nix y no te funcionan los flakes, necesitas añadir un poco de configuración. Abre o crea un archivo ~/.config/nix/nix.conf y ponle esto:
experimental-features = flakes nix-command
Ya con todo configurado correctamente, te pongo una versión ajustada del archivo flake.nix:
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = {
nixpkgs,
flake-utils,
...
}:
flake-utils.lib.eachDefaultSystem (
system: let
pkgs = import nixpkgs {system = system;};
in {
devShell = pkgs.mkShell {
buildInputs = [
pkgs.elmPackages.elm
pkgs.elmPackages.elm-format
pkgs.elmPackages.elm-test
pkgs.just
pkgs.nushell
];
};
}
);
}
Lo que hicimos fue declarar una nueva entrada bajo inputs, de nombre flake-utils, y más abajo usar la función eachDefaultSystem que provee, la que nos ayuda a configurar un shell de desarrollo para múltiples entornos simultáneamente. Lo demás está igual.
Para agregar otros paquetes, los encuentras en , .
Nushell para escribir scripts
e interactuar sólo con texto plano, trabajamos con datos estructurados. Básicamente, es un shell y lenguaje que reemplaza la necesidad de Bash, grep, sed, awk, jq, curl y muchas otras utilidades de línea de comandos frecuentemente usadas para procesar datos.
Igual se ajusta hasta cierto punto a nuestras expectativas como usuarios de Bash y similares. Por ejemplo, en un shell Nushell el comando ls funciona como es de esperarse:
$ ls
╭───┬────────────┬──────┬───────┬─────────────╮
│ # │ name │ type │ size │ modified │
├───┼────────────┼──────┼───────┼─────────────┤
│ 0 │ flake.lock │ file │ 569 B │ 8 hours ago │
│ 1 │ flake.nix │ file │ 405 B │ 7 hours ago │
╰───┴────────────┴──────┴───────┴─────────────╯
Pero esta salida no es puramente texto. En realidad lo que hemos obtenido es una tabla con filas y columnas. Mira el tipo de cosas que podemos hacer con sólo Nushell:
$ ls | where name =~ '[.]lock$' | get 0.name | open
::: | from json | get nodes.nixpkgs.locked.lastModified
::: | $in * 1_000_000_000 | into datetime
Tue, 5 Aug 2025 11:35:34 +0000 (2 days ago)
Obviamente este ejemplo es puramente demostrativo, pero fíjate: estamos listando archivos, filtrando en base a un regex, sacando el nombre del primero en la lista, leyendo el contenido del archivo, interpretándolo como JSON, recuperando un valor numérico dentro del JSON, multiplicando para convertir segundos a nanosegundos, y finalmente convirtiendo eso a una fecha.
Es tan práctico que lo tengo como mi shell por defecto. Pero para el caso de este artículo, lo relevante es su utilidad para escribir scripts simples y legibles que transforman archivos, levantan servicios, recuperan datos de internet, y más. Los archivos llevan la extensión .nu.
Veamos un pequeño ejemplo. Este es un script que actualiza una lista de exclusiones para evitar visitas de robots de IA, con datos que descargamos del es una herramienta con un alcance muy moderado: permitir definir tareas repetibles para un proyecto. Lo típico es definir una tarea “build” para compilar el código, o una “dev” para ejecutarlo localmente, o una “test” para correr los tests. La manera en que funcionaría usando Just es con los comandos just build, just dev y just test, cuyas tareas uno mismo define en un archivo de nombre justfile.
Seguro que hasta ahí no hay nada nuevo, es lo mismo que uno haría con Make o con npm run, por ejemplo. Y es verdad, Just no ofrece un paradigma novedoso. Lo único que ofrece es simpleza.
El modelo de Just es Make. No sé tú, pero yo al menos he escrito muchos , o cualquier otro lenguaje aquí. Esta funcionalidad es súper útil.
Esa fue mi presentación sobre estas herramientas que uso para configurar mis proyectos. Hay una otra herramienta que no mencioné: direnv, la cual hace que sea mucho más placentero trabajar con entornos Nix. Tal vez otro día escribiré algo al respecto, no sé.
Ojalá que te haya sido útil, y cuéntame si encontraste algo incorrecto o confuso.
SOCIAL SHARE CARD GENERATOR