🧶 yarn: El Orden del Monorepo y la Estabilidad

“El clan ninja no es un guerrero solitario. Es una red coordinada donde cada miembro conoce su lugar.” - Código del Trabajo Coordinado

🎯 ¿Qué es yarn y por qué existe?

yarn fue creado por Facebook en 2016 para resolver problemas críticos de npm (en ese momento):

  1. Lentitud: Instalaciones tardaban minutos
  2. No determinismo: Diferentes instalaciones producían diferentes versiones
  3. Sin lockfile: No había forma de garantizar reproducibilidad
  4. Sin soporte para monorepos: Difícil gestionar múltiples paquetes relacionados

Hoy (2026):

  • npm mejoró enormemente (lockfile, velocidad)
  • yarn sigue siendo relevante por workspaces y estabilidad
  • yarn v1 (classic) vs yarn v2+ (Berry) son ecosistemas diferentes

Instalación:

# Con npm
npm install -g yarn

# Con Homebrew (macOS)
brew install yarn

# Verificar instalación
yarn --version

📜 Comandos Básicos

yarn usa sintaxis similar a npm pero más concisa:

Instalar Paquetes

# Instalar dependencia (NO necesitas 'install')
yarn add express

# Instalar devDependency
yarn add -D jest

# Instalar versión específica
yarn add react@18.2.0

# Instalar globalmente
yarn global add typescript

Eliminar Paquetes

yarn remove lodash

Actualizar Paquetes

# Ver paquetes desactualizados
yarn outdated

# Actualizar todos (interactivo)
yarn upgrade-interactive

# Actualizar uno específico
yarn upgrade react

# Actualizar a última versión (ignorar rangos)
yarn upgrade react@latest

Instalar Desde package.json

# Instalar todo (clonar proyecto)
yarn install

# Atajo (solo 'yarn' es suficiente)
yarn

# Instalar solo producción
yarn install --production

Ejecutar Scripts

# NO necesitas 'run'
yarn dev
yarn build
yarn test

🔒 yarn.lock: La Garantía de Reproducibilidad

El archivo yarn.lock registra las versiones exactas de TODAS las dependencias.

Diferencia con npm:

Aspectonpm (package-lock.json)yarn (yarn.lock)
FormatoJSONYAML-like custom
LegibilidadDifícil (generado)Más legible
Merge conflictsFrecuentesMenos frecuentes
GeneraciónAutomáticaAutomática

Ejemplo de yarn.lock:

lodash@^4.17.21:
  version "4.17.21"
  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
  integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==

Reglas de oro:

  • ✅ SÍ versiona yarn.lock en Git
  • ❌ NO lo edites manualmente
  • ✅ Commitea cambios en yarn.lock junto con package.json

🏢 Workspaces: El Superpoder de yarn

Workspaces permiten gestionar múltiples paquetes en un solo repositorio (monorepo).

Cuándo Usar Monorepos

Sí usa monorepo si:

  • Tienes paquetes relacionados (app web + app móvil + librería compartida)
  • Compartes código entre proyectos
  • Quieres hacer cambios atómicos (un commit afecta varios paquetes)

No uses monorepo si:

  • Proyectos completamente independientes
  • Equipos separados sin código compartido

Configurar Workspaces

Estructura de directorios:

mi-monorepo/
├── packages/
│   ├── web-app/
│   │   ├── package.json
│   │   └── src/
│   ├── mobile-app/
│   │   ├── package.json
│   │   └── src/
│   └── shared-components/
│       ├── package.json
│       └── src/
├── package.json  ← Root package
└── yarn.lock

Root package.json:

{
  "name": "mi-monorepo",
  "private": true,
  "workspaces": [
    "packages/*"
  ]
}

Packages individuales:

// packages/web-app/package.json
{
  "name": "web-app",
  "version": "1.0.0",
  "dependencies": {
    "react": "^18.2.0",
    "shared-components": "1.0.0"   Referencia interna
  }
}
// packages/shared-components/package.json
{
  "name": "shared-components",
  "version": "1.0.0",
  "dependencies": {
    "react": "^18.2.0"
  }
}

Instalar Dependencias en Monorepo

# Desde la raíz, instala TODAS las dependencias de todos los workspaces
yarn install

Qué sucede:

  1. yarn lee workspaces en root package.json
  2. Encuentra todos los package.json en packages/*
  3. Instala dependencias en un solo node_modules/ en la raíz
  4. Enlaza paquetes internos automáticamente

Resultado:

mi-monorepo/
├── node_modules/          ← UN SOLO node_modules
│   ├── react/
│   ├── shared-components → packages/shared-components (symlink)
│   └── ...
├── packages/
│   ├── web-app/
│   └── shared-components/

Añadir Dependencia a un Workspace Específico

# Añadir axios solo a web-app
yarn workspace web-app add axios

# Añadir jest a mobile-app como devDependency
yarn workspace mobile-app add -D jest

Ejecutar Scripts en Workspaces

# Ejecutar dev en web-app
yarn workspace web-app dev

# Ejecutar test en todos los workspaces
yarn workspaces run test

# Ejecutar build en todos
yarn workspaces run build

🔍 yarn vs npm vs pnpm

Característicanpmyarnpnpm
VelocidadMediaAltaMuy alta
Espacio discoAltoAltoMuy bajo
WorkspacesSí (v7+)Sí (nativo)Sí (nativo)
Lockfilepackage-lock.jsonyarn.lockpnpm-lock.yaml
Sintaxisnpm installyarn addpnpm add
PopularidadMuy altaAltaCreciente
Curva aprendizajeBajaBajaBaja

Cuándo Usar Cada Uno

Usa npm si:

  • Equipo usa npm (convención)
  • Proyecto simple sin monorepo
  • Siguiendo tutoriales (mayoría usa npm)

Usa yarn si:

  • Trabajas en monorepo
  • Quieres instalaciones determinísticas
  • Tu equipo ya lo usa (React, Next.js lo usan internamente)

Usa pnpm si:

  • Espacio en disco es crítico
  • Múltiples proyectos en tu máquina
  • Quieres máxima velocidad

⚡ Comandos Avanzados de yarn

Verificar Integridad

# Verificar que node_modules coincide con yarn.lock
yarn check

# Verificar checksums de paquetes
yarn check --integrity

Limpiar Caché

# Ver ubicación de caché
yarn cache dir

# Limpiar caché
yarn cache clean

Listar Dependencias

# Ver árbol de dependencias
yarn list

# Solo nivel 0 (directas)
yarn list --depth=0

# Ver de dónde viene un paquete
yarn why lodash

Upgrade Interactivo

# Seleccionar qué paquetes actualizar (UI interactiva)
yarn upgrade-interactive --latest

Auditar Seguridad

# Buscar vulnerabilidades
yarn audit

# Intentar arreglarlas
yarn audit fix

💡 yarn v1 (Classic) vs yarn v2+ (Berry)

yarn Classic (v1.x)

  • Versión tradicional (2016-2020)
  • Compatible con npm
  • Usa node_modules/ normal
  • Recomendado para principiantes

yarn Berry (v2+)

  • Reescritura completa (2020+)
  • Modo Plug’n’Play (PnP): Sin node_modules/
  • Más rápido pero menos compatible
  • Solo para expertos

Verificar qué versión tienes:

yarn --version
# 1.22.x = Classic
# 3.x.x = Berry

Migrar a Berry (opcional):

yarn set version berry

⚠️ No recomendado para principiantes: Berry tiene incompatibilidades con muchas herramientas.


🎯 Ejemplo Real: Monorepo con yarn

Caso de Uso

Tienes:

  • Frontend (React)
  • Backend (Node.js)
  • Librería compartida de utilidades

Configuración

1. Crear estructura:

mkdir ninja-monorepo
cd ninja-monorepo
yarn init -y

2. Configurar workspaces en package.json:

{
  "name": "ninja-monorepo",
  "private": true,
  "workspaces": [
    "packages/*"
  ]
}

3. Crear paquetes:

mkdir -p packages/{frontend,backend,shared}

# Frontend
cd packages/frontend
yarn init -y
yarn add react react-dom

# Backend
cd ../backend
yarn init -y
yarn add express

# Shared
cd ../shared
yarn init -y

4. Enlazar paquetes:

// packages/frontend/package.json
{
  "dependencies": {
    "react": "^18.2.0",
    "shared": "1.0.0"   Workspace interno
  }
}

5. Instalar todo:

# Desde la raíz
cd ../..
yarn install

6. Ejecutar scripts:

yarn workspace frontend start
yarn workspace backend dev

🎯 Reto Ninja del Tema

Misión: Crear tu primer monorepo con yarn

  1. Inicializa monorepo:

    mkdir yarn-dojo
    cd yarn-dojo
    yarn init -y
  2. Configura workspaces en package.json:

    {
      "private": true,
      "workspaces": ["packages/*"]
    }
  3. Crea dos paquetes:

    mkdir -p packages/{app,utils}
    cd packages/utils
    yarn init -y
    # Crea src/index.js con una función simple
    cd ../app
    yarn init -y
  4. Enlaza utils en app:

    // packages/app/package.json
    {
      "dependencies": {
        "utils": "1.0.0"
      }
    }
  5. Instala:

    cd ../..
    yarn install
  6. Usa el paquete compartido:

    // packages/app/index.js
    const { suma } = require('utils');
    console.log(suma(2, 3));

Criterios de éxito:

  • ✅ Creaste un monorepo funcional
  • ✅ Enlazaste paquetes internos
  • ✅ Instalaste en un solo node_modules/
  • ✅ Ejecutaste código compartido entre paquetes

⚠️ Errores Comunes

Error #1: Workspaces no detectados

error Couldn't find any versions for "mi-paquete"

Causa: package.json root no tiene "private": true

Solución:

{
  "private": true,
  "workspaces": ["packages/*"]
}

Error #2: Versiones incompatibles

error Incompatible peer dependencies

Solución:

# Forzar instalación (usar con precaución)
yarn install --ignore-engines

Error #3: yarn.lock en conflicto (Git)

Solución:

# Eliminar yarn.lock conflictivo
rm yarn.lock

# Regenerar desde package.json
yarn install

📚 Recursos Adicionales


Siguiente Pergamino: 4.7 package.json, Scripts y Semver

¿Creaste tu monorepo? Comparte tu estructura en Discord con #yarnNinja! 🧶🥷