EN
$ cat ~/articles/tech-roles-library-npm-package.md ← volver a artículos

Contratas a un desarrollador como "Senior". Tres meses después descubres que no sabe hacer code reviews ni mentorizar juniors. En la entrevista dijo que tenía 6 años de experiencia, y técnicamente era cierto. Pero experiencia no es lo mismo que nivel. Un desarrollador puede pasar 6 años escribiendo el mismo código CRUD sin desarrollar competencias de arquitectura, liderazgo técnico o diseño de sistemas.

El problema es que "Senior" no significa nada concreto. Para una startup de 5 personas, senior es quien lleva más de 2 años. Para una BigTech, senior empieza a los 5-7 años con un catálogo específico de competencias demostradas. Cuando publicas una oferta de "Senior Backend Developer", cada candidato interpreta algo diferente. Cuando haces una revisión salarial, no tienes criterios objetivos para justificar promociones.

El departamento de HR suele manejar una tabla Excel con títulos genéricos: Junior, Mid, Senior, Lead. Sin definición de qué competencias corresponden a cada nivel. Sin criterios para evaluar si alguien está listo para promocionar. Sin itinerario claro que el propio empleado pueda seguir para crecer.

Esto genera frustración en ambos lados. El empleado no sabe qué necesita aprender para subir de nivel. El manager no tiene argumentos objetivos para defender una promoción ante dirección. HR no puede comparar roles entre departamentos porque cada equipo usa criterios diferentes.

Por qué creé este paquete

En SPARRING necesitábamos evaluar candidatos técnicos de forma objetiva. La plataforma genera entrevistas automatizadas, pero para evaluar respuestas necesitas saber qué competencias esperar de un Backend Developer L3 versus un L5. No puedes preguntar lo mismo a un junior que a un senior.

Busqué frameworks de niveles técnicos existentes. Encontré el Engineering Ladder de Rent the Runway publicado en GitHub, los niveles de Dropbox filtrados en Levels.fyi, el framework de Spotify que circula por LinkedIn. Todos útiles como inspiración, pero ninguno estructurado como librería consumible por código. Eran documentos PDF o páginas web, no APIs.

La alternativa era crear JSON manualmente con los roles que necesitaba. El problema es el mantenimiento. Cuando añades un rol nuevo, tienes que definir 9 niveles con sus competencias. Cuando modificas la estructura de datos, tienes que actualizar todos los archivos. Sin validación automática, es fácil que se cuelen inconsistencias.

Decidí construir una librería completa que sirviera como fuente única de verdad para roles técnicos. 78 roles organizados en 7 categorías. 9 niveles por rol, desde L1 (Trainee) hasta L9 (VP/CTO). Cada nivel con competencias core, competencias complementarias, indicadores de desempeño, y rango de años de experiencia típico. Soporte bilingüe porque operamos en mercados hispanohablantes y anglófonos.

El resultado es @sparring/tech-roles-library: 702 definiciones únicas de rol-nivel con API completa para búsqueda, filtrado, análisis de career paths y comparación entre niveles.

Instalación y estructura básica

npm install @sparring/tech-roles-library

La librería exporta una clase principal que inicializas con el idioma deseado:

const TechRolesLibrary = require('@sparring/tech-roles-library');

// Inglés por defecto
const library = new TechRolesLibrary();

// Español
const libraryES = new TechRolesLibrary({ language: 'es' });

El idioma afecta todos los textos: nombres de roles, nombres de niveles, competencias, indicadores. Un "Backend Developer" en inglés es "Desarrollador Backend" en español. Las competencias están traducidas profesionalmente, no con Google Translate.

La estructura de datos de cada entrada de rol-nivel incluye:

{
  category: 'Software Engineering',
  role: 'Backend Developer',
  level: 'L5 - Mid-level II',
  code: 'BE-L5',
  levelNumber: 5,
  yearsRange: { min: 5, max: 7 },
  coreCompetencies: [
    'Diseño de APIs RESTful escalables',
    'Optimización de consultas SQL complejas',
    'Implementación de patrones de microservicios',
    // ... más competencias
  ],
  complementaryCompetencies: [
    'Conocimiento de sistemas de mensajería',
    'Experiencia con contenedores',
    // ... más competencias
  ],
  indicators: [
    'Lidera features de complejidad media-alta',
    'Mentoriza desarrolladores junior',
    'Participa activamente en decisiones de arquitectura'
  ]
}

El código (BE-L5) es un identificador único que combina abreviatura del rol y número de nivel. Es útil para referencias rápidas en bases de datos o URLs.

Acceso básico a roles y niveles

Obtener la lista de todos los roles disponibles:

const roles = library.getRoles();
console.log(`Total roles: ${roles.length}`); // 78

// Muestra: ['AI Engineer', 'Backend Developer', 'Data Analyst', ...]

Obtener un rol-nivel específico por su código:

const role = library.getRole('BE-L5');

console.log(role.role);      // 'Backend Developer'
console.log(role.level);     // 'L5 - Mid-level II'
console.log(role.yearsRange); // { min: 5, max: 7 }

Obtener todos los niveles de un rol específico:

const backendLevels = library.getLevelsForRole('Backend Developer');

backendLevels.forEach(entry => {
  console.log(`${entry.code}: ${entry.level} (${entry.yearsRange.min}-${entry.yearsRange.max || '15+'} años)`);
});

// Salida:
// BE-L1: L1 - Trainee (0-1 años)
// BE-L2: L2 - Junior I (1-2 años)
// BE-L3: L3 - Junior II (2-3 años)
// BE-L4: L4 - Mid-level I (3-5 años)
// BE-L5: L5 - Mid-level II (5-7 años)
// BE-L6: L6 - Senior I (7-10 años)
// BE-L7: L7 - Senior II (10-12 años)
// BE-L8: L8 - Staff/Principal (12-15 años)
// BE-L9: L9 - VP/CTO (15+ años)

Categorías de roles

Los 78 roles están organizados en 7 categorías que reflejan la estructura típica de equipos tech:

Categoría Roles Descripción
Software Engineering 33 Full-stack, backend, frontend, mobile, QA
AI/ML 16 Machine learning, data science, MLOps
Data 15 Data engineering, analytics, BI
Product 7 Product management, ownership, analysis
Security 4 Security engineering, DevSecOps
Infrastructure 2 Platform, SRE, cloud
Sales 1 Technical sales, solutions engineering

Filtrar roles por categoría:

const categories = library.getCategories();
console.log(categories);
// ['AI/ML', 'Data', 'Infrastructure', 'Product', 'Sales', 'Security', 'Software Engineering']

const aiRoles = library.filterByCategory('AI/ML');
console.log(`Roles de AI/ML: ${aiRoles.length / 9}`); // 16 roles × 9 niveles = 144 entradas

Filtrar todos los roles de un nivel específico:

const allSeniors = library.filterByLevel('L6');
console.log(`Roles Senior I: ${allSeniors.length}`); // 78 (uno por cada rol)

Búsqueda de roles

Cuando construyes un selector de roles en una UI, necesitas búsqueda por texto. El método search() encuentra roles por nombre o categoría:

const results = library.search('fullstack', { limit: 5 });

results.forEach(result => {
  console.log(`${result.role} (${result.category}) - Score: ${result.matchScore}`);
});

// Salida:
// Full-Stack Developer (Software Engineering) - Score: 10
// Full-Stack Engineer (Software Engineering) - Score: 10

El matchScore indica relevancia: 10 puntos si matchea en nombre del rol, 5 puntos si matchea en categoría. Los resultados vienen ordenados por score descendente.

// Buscar por categoría
const dataResults = library.search('data');
// Encuentra: Data Analyst, Data Engineer, Data Scientist, etc.
// También encuentra roles en categoría "Data"

Análisis de career paths

Esta es la funcionalidad más potente para planificación de carreras. Dado un rol y nivel actual, puedes obtener la vista completa del itinerario.

Qué necesitas para subir de nivel

const nextLevel = library.getNextLevel('Backend Developer', 'L5');

console.log(`Nivel actual: ${nextLevel.current.level}`);
console.log(`Siguiente nivel: ${nextLevel.next.level}`);
console.log(`Años típicos: ${nextLevel.next.yearsRange.min}-${nextLevel.next.yearsRange.max}`);
console.log(`Nuevas competencias a desarrollar: ${nextLevel.newCompetenciesCount}`);

nextLevel.newCompetencies.forEach(comp => {
  console.log(`  - ${comp}`);
});

// Salida:
// Nivel actual: L5 - Mid-level II
// Siguiente nivel: L6 - Senior I
// Años típicos: 7-10
// Nuevas competencias a desarrollar: 8
//   - Liderazgo técnico de equipos pequeños
//   - Definición de estándares de código
//   - Evaluación y selección de tecnologías
//   - ...

Esto responde la pregunta que todo desarrollador tiene: "¿qué necesito aprender para promocionar?"

Vista completa del career path

const career = library.getCareerPathComplete('Backend Developer', 'L5');

console.log('=== Niveles dominados ===');
career.masteredLevels.forEach(level => {
  console.log(`${level.code}: ${level.coreCompetencies.length} competencias`);
});

console.log('\n=== Nivel actual ===');
console.log(`${career.currentLevel.code}: ${career.currentLevel.level}`);

console.log('\n=== Camino de crecimiento ===');
career.growthPath.forEach(level => {
  console.log(`${level.code}: ${level.level}`);
});

console.log('\n=== Resumen ===');
console.log(`Competencias dominadas: ${career.summary.totalMasteredCompetencies}`);
console.log(`Competencias nivel actual: ${career.summary.currentLevelCompetencies}`);
console.log(`Por aprender: ${career.summary.remainingToLearn}`);
console.log(`Progreso: ${career.summary.progressPercentage}%`);

Esta vista es útil para:

  • Empleados: Ver dónde están y qué les falta
  • Managers: Planificar desarrollo de su equipo
  • HR: Diseñar planes de formación basados en gaps reales

Competencias acumuladas

Las competencias son acumulativas. Un L5 debe dominar todo lo de L1-L4 más las específicas de L5:

const accumulated = library.getAccumulatedCompetencies('Backend Developer', 'L5');

accumulated.levels.forEach(level => {
  console.log(`\n${level.level}:`);
  level.coreCompetencies.forEach(comp => {
    console.log(`  ✓ ${comp}`);
  });
});

Esto genera el catálogo completo de competencias que alguien en ese nivel debe demostrar.

Encontrar nivel por años de experiencia

Si solo conoces los años de experiencia de alguien, puedes estimar su nivel:

const level = library.getByExperience('Backend Developer', 6);

console.log(level.level);      // 'L5 - Mid-level II'
console.log(level.yearsRange); // { min: 5, max: 7 }

Esto es una estimación basada en rangos típicos. 6 años de experiencia cae en el rango de L5 (5-7 años). Pero recuerda: años no equivalen a nivel. Un desarrollador con 6 años haciendo lo mismo puede estar en L3 por competencias reales.

Para dashboards o reportes:

const stats = library.getStatistics();

console.log(`Total roles: ${stats.totalRoles}`);           // 78
console.log(`Total entradas: ${stats.totalEntries}`);       // 702
console.log(`Categorías: ${stats.totalCategories}`);        // 7
console.log('Por categoría:', stats.byCategory);
// { 'Software Engineering': 297, 'AI/ML': 144, 'Data': 135, ... }

Catálogo completo con metadata:

const catalog = library.getAllRolesWithMetadata();

catalog.roles.forEach(roleInfo => {
  console.log(`${roleInfo.role} (${roleInfo.category})`);
  console.log(`  Niveles: ${roleInfo.levelCount}`);
  console.log(`  Competencias totales: ${roleInfo.statistics.totalCompetencies}`);
});

Soporte bilingüe

Todas las traducciones son profesionales con terminología técnica correcta. No hay mezcla de idiomas ni traducciones literales que no tienen sentido en el contexto tech.

const libEN = new TechRolesLibrary({ language: 'en' });
const libES = new TechRolesLibrary({ language: 'es' });

const roleEN = libEN.getRole('BE-L5');
const roleES = libES.getRole('BE-L5');

console.log(roleEN.role);  // 'Backend Developer'
console.log(roleES.role);  // 'Desarrollador Backend'

console.log(roleEN.level); // 'L5 - Mid-level II'
console.log(roleES.level); // 'L5 - Mid-level II'

// Las competencias también están traducidas
console.log(roleEN.coreCompetencies[0]); // 'Scalable RESTful API design'
console.log(roleES.coreCompetencies[0]); // 'Diseño de APIs RESTful escalables'

El español usa español neutro sin regionalismos. "Desarrollador" en lugar de "Programador". "Competencias" en lugar de "Habilidades". Terminología que funciona igual en España, México, Argentina o Colombia.

Los 9 niveles explicados

El framework usa 9 niveles estandarizados que mapean a estructuras típicas de empresas tech:

Nivel Nombre Años típicos Descripción
L1 Trainee 0-1 Recién graduado, en formación
L2 Junior I 1-2 Ejecuta tareas definidas con supervisión
L3 Junior II 2-3 Autonomía en tareas de complejidad baja
L4 Mid-level I 3-5 Autonomía completa en features medianas
L5 Mid-level II 5-7 Lidera features, empieza a mentorizar
L6 Senior I 7-10 Liderazgo técnico, decisiones de arquitectura
L7 Senior II 10-12 Referente técnico del equipo
L8 Staff/Principal 12-15 Impacto cross-team, define estándares
L9 VP/CTO 15+ Liderazgo estratégico, visión técnica

Los años son orientativos. Un desarrollador excepcional puede llegar a L6 en 5 años. Uno que se estanca puede quedarse en L4 con 10 años de experiencia. Lo que importa son las competencias demostradas, no el calendario.

Casos de uso reales

Sistema de evaluación de candidatos

// Candidato dice tener nivel Senior (L6)
const expectedCompetencies = library.getCompetencies('Backend Developer', 'L6');

// Comparar con competencias que demuestra en entrevista
const demonstrated = evaluateInterview(candidate);

const gaps = expectedCompetencies.core.filter(
  comp => !demonstrated.includes(comp)
);

if (gaps.length > 3) {
  console.log('Candidato no cumple nivel L6, gaps:', gaps);
  // Sugerir L5 o L4 según gaps
}

Plan de desarrollo individual

const employee = { role: 'Frontend Developer', currentLevel: 'L4' };
const nextLevel = library.getNextLevel(employee.role, employee.currentLevel);

// Generar plan de desarrollo
const developmentPlan = {
  currentLevel: employee.currentLevel,
  targetLevel: nextLevel.next.level,
  timeframe: `${nextLevel.next.yearsRange.min - 3} - ${nextLevel.next.yearsRange.max - 3} años`,
  competenciesToDevelop: nextLevel.newCompetencies,
  suggestedTraining: mapCompetenciesToCourses(nextLevel.newCompetencies)
};

Comparación salarial por nivel

// Tu base de datos de salarios por nivel
const salaryBands = {
  'L4': { min: 35000, max: 45000 },
  'L5': { min: 45000, max: 55000 },
  'L6': { min: 55000, max: 70000 }
};

// Empleado pide subida
const employee = library.getRole('FE-L5');
const band = salaryBands['L5'];

console.log(`Banda salarial para ${employee.level}: ${band.min}€ - ${band.max}€`);

Organigramas técnicos

const team = [
  { name: 'Ana', roleCode: 'BE-L6' },
  { name: 'Carlos', roleCode: 'BE-L4' },
  { name: 'María', roleCode: 'FE-L5' },
  { name: 'Pedro', roleCode: 'BE-L3' }
];

team.forEach(member => {
  const role = library.getRole(member.roleCode);
  console.log(`${member.name}: ${role.role} ${role.level}`);
});

// Ana: Backend Developer L6 - Senior I
// Carlos: Backend Developer L4 - Mid-level I
// María: Frontend Developer L5 - Mid-level II
// Pedro: Backend Developer L3 - Junior II

Validación y calidad de datos

La librería pasó 99 tests antes de publicación:

  • Integridad estructural: Todos los JSON válidos, sin campos faltantes
  • Consistencia de niveles: Cada rol tiene exactamente 9 niveles L1-L9
  • Validación de traducciones: 0% contaminación entre idiomas (ni palabras en inglés en archivos ES ni viceversa)
  • Rangos de años coherentes: L1 < L2 < L3... sin solapamientos
  • Códigos únicos: Sin duplicados en los 702 códigos de rol-nivel

Cada release ejecuta validación completa. Si añades un rol nuevo vía PR, los tests verifican que tenga estructura correcta, 9 niveles, traducciones completas, y códigos que sigan el patrón existente.

TypeScript: tipos completos

El paquete incluye definiciones TypeScript. No necesitas @types/ adicionales:

import TechRolesLibrary from '@sparring/tech-roles-library';
import type { RoleEntry, CareerPath, SearchResult } from '@sparring/tech-roles-library';

const library = new TechRolesLibrary({ language: 'es' });

// TypeScript conoce el tipo de retorno
const role: RoleEntry = library.getRole('BE-L5');
const career: CareerPath = library.getCareerPathComplete('Backend Developer', 'L5');
const results: SearchResult[] = library.search('frontend');

Los tipos están completos: RoleEntry, CareerPath, SearchResult, LibraryStatistics, opciones de configuración. El autocompletado de VS Code funciona perfectamente.

Cero dependencias

El paquete no tiene dependencias de runtime. El package.json solo lista devDependencies para testing y build. Esto significa:

  • Bundle size mínimo
  • Sin conflictos de versiones con otras librerías
  • Sin vulnerabilidades heredadas de dependencias
  • Funciona en cualquier entorno Node.js 16+

Los archivos de traducción se cargan con lazy loading. Si usas el paquete en español, no carga los archivos ingleses hasta que cambies de idioma.

Demo interactiva

Puedes explorar el catálogo completo en la demo web:

https://686f6c61.github.io/npm-tech-roles-library/demo/

La demo permite:

  • Navegar roles por categoría
  • Ver los 9 niveles de cada rol
  • Explorar competencias de cada nivel
  • Cambiar entre inglés y español

El código fuente está en GitHub: github.com/686f6c61/npm-tech-roles-library

El paquete está publicado en NPM: @sparring/tech-roles-library

Contribuciones bienvenidas para añadir roles faltantes, mejorar traducciones, o corregir competencias que no reflejen la realidad del mercado actual.