ES
$ cat ~/articles/tech-roles-library-npm-package.md ← back to articles

You hire a developer as "Senior". Three months later you discover they can't do code reviews or mentor juniors. In the interview they said they had 6 years of experience, and technically that was true. But experience is not the same as level. A developer can spend 6 years writing the same CRUD code without developing architecture, technical leadership, or system design competencies.

The problem is that "Senior" means nothing concrete. For a 5-person startup, senior is whoever has been there more than 2 years. For a BigTech, senior starts at 5-7 years with a specific catalog of demonstrated competencies. When you post a "Senior Backend Developer" job, each candidate interprets something different. When you do a salary review, you have no objective criteria to justify promotions.

The HR department usually manages an Excel table with generic titles: Junior, Mid, Senior, Lead. No definition of what competencies correspond to each level. No criteria to evaluate if someone is ready for promotion. No clear path that the employee themselves can follow to grow.

This generates frustration on both sides. The employee doesn't know what they need to learn to level up. The manager has no objective arguments to defend a promotion to leadership. HR can't compare roles between departments because each team uses different criteria.

Why I created this package

At SPARRING we needed to evaluate technical candidates objectively. The platform generates automated interviews, but to evaluate responses you need to know what competencies to expect from a Backend Developer L3 versus an L5. You can't ask the same questions to a junior as to a senior.

I looked for existing technical level frameworks. I found Rent the Runway's Engineering Ladder published on GitHub, Dropbox levels leaked on Levels.fyi, Spotify's framework circulating on LinkedIn. All useful as inspiration, but none structured as a consumable code library. They were PDF documents or web pages, not APIs.

The alternative was manually creating JSON with the roles I needed. The problem is maintenance. When you add a new role, you have to define 9 levels with their competencies. When you modify the data structure, you have to update all files. Without automatic validation, inconsistencies easily slip through.

I decided to build a complete library that would serve as a single source of truth for technical roles. 78 roles organized in 7 categories. 9 levels per role, from L1 (Trainee) to L9 (VP/CTO). Each level with core competencies, complementary competencies, performance indicators, and typical years of experience range. Bilingual support because we operate in both Spanish and English-speaking markets.

The result is @sparring/tech-roles-library: 702 unique role-level definitions with complete API for search, filtering, career path analysis, and level comparison.

Installation and basic structure

npm install @sparring/tech-roles-library

The library exports a main class that you initialize with the desired language:

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

// English by default
const library = new TechRolesLibrary();

// Spanish
const libraryES = new TechRolesLibrary({ language: 'es' });

The language affects all text: role names, level names, competencies, indicators. A "Backend Developer" in English is "Desarrollador Backend" in Spanish. Competencies are professionally translated, not Google Translated.

The data structure for each role-level entry includes:

{
  category: 'Software Engineering',
  role: 'Backend Developer',
  level: 'L5 - Mid-level II',
  code: 'BE-L5',
  levelNumber: 5,
  yearsRange: { min: 5, max: 7 },
  coreCompetencies: [
    'Scalable RESTful API design',
    'Complex SQL query optimization',
    'Microservices pattern implementation',
    // ... more competencies
  ],
  complementaryCompetencies: [
    'Knowledge of messaging systems',
    'Experience with containers',
    // ... more competencies
  ],
  indicators: [
    'Leads medium-high complexity features',
    'Mentors junior developers',
    'Actively participates in architecture decisions'
  ]
}

The code (BE-L5) is a unique identifier combining role abbreviation and level number. It's useful for quick references in databases or URLs.

Basic access to roles and levels

Get the list of all available roles:

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

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

Get a specific role-level by its code:

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 }

Get all levels for a specific role:

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

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

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

Role categories

The 78 roles are organized into 7 categories that reflect typical tech team structures:

Category Roles Description
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

Filter roles by category:

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

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

Filter all roles at a specific level:

const allSeniors = library.filterByLevel('L6');
console.log(`Senior I roles: ${allSeniors.length}`); // 78 (one per role)

When building a role selector in a UI, you need text search. The search() method finds roles by name or category:

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

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

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

The matchScore indicates relevance: 10 points if it matches role name, 5 points if it matches category. Results are sorted by descending score.

// Search by category
const dataResults = library.search('data');
// Finds: Data Analyst, Data Engineer, Data Scientist, etc.
// Also finds roles in "Data" category

Career path analysis

This is the most powerful functionality for career planning. Given a role and current level, you can get the complete career path view.

What you need to level up

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

console.log(`Current level: ${nextLevel.current.level}`);
console.log(`Next level: ${nextLevel.next.level}`);
console.log(`Typical years: ${nextLevel.next.yearsRange.min}-${nextLevel.next.yearsRange.max}`);
console.log(`New competencies to develop: ${nextLevel.newCompetenciesCount}`);

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

// Output:
// Current level: L5 - Mid-level II
// Next level: L6 - Senior I
// Typical years: 7-10
// New competencies to develop: 8
//   - Technical leadership of small teams
//   - Code standards definition
//   - Technology evaluation and selection
//   - ...

This answers the question every developer has: "what do I need to learn to get promoted?"

Complete career path view

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

console.log('=== Mastered levels ===');
career.masteredLevels.forEach(level => {
  console.log(`${level.code}: ${level.coreCompetencies.length} competencies`);
});

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

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

console.log('\n=== Summary ===');
console.log(`Mastered competencies: ${career.summary.totalMasteredCompetencies}`);
console.log(`Current level competencies: ${career.summary.currentLevelCompetencies}`);
console.log(`Remaining to learn: ${career.summary.remainingToLearn}`);
console.log(`Progress: ${career.summary.progressPercentage}%`);

This view is useful for:

  • Employees: See where they are and what's missing
  • Managers: Plan team development
  • HR: Design training plans based on real gaps

Accumulated competencies

Competencies are cumulative. An L5 should master everything from L1-L4 plus L5 specifics:

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

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

This generates the complete catalog of competencies someone at that level should demonstrate.

Find level by years of experience

If you only know someone's years of experience, you can estimate their level:

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

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

This is an estimate based on typical ranges. 6 years of experience falls in L5 range (5-7 years). But remember: years don't equal level. A developer with 6 years doing the same thing might be at L3 by actual competencies.

Catalog statistics

For dashboards or reports:

const stats = library.getStatistics();

console.log(`Total roles: ${stats.totalRoles}`);           // 78
console.log(`Total entries: ${stats.totalEntries}`);       // 702
console.log(`Categories: ${stats.totalCategories}`);        // 7
console.log('By category:', stats.byCategory);
// { 'Software Engineering': 297, 'AI/ML': 144, 'Data': 135, ... }

Complete catalog with metadata:

const catalog = library.getAllRolesWithMetadata();

catalog.roles.forEach(roleInfo => {
  console.log(`${roleInfo.role} (${roleInfo.category})`);
  console.log(`  Levels: ${roleInfo.levelCount}`);
  console.log(`  Total competencies: ${roleInfo.statistics.totalCompetencies}`);
});

Bilingual support

All translations are professional with correct technical terminology. No language mixing or literal translations that make no sense in tech context.

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'

// Competencies are also translated
console.log(roleEN.coreCompetencies[0]); // 'Scalable RESTful API design'
console.log(roleES.coreCompetencies[0]); // 'Diseño de APIs RESTful escalables'

Spanish uses neutral Spanish without regionalisms. "Desarrollador" instead of "Programador". "Competencias" instead of "Habilidades". Terminology that works equally in Spain, Mexico, Argentina, or Colombia.

The 9 levels explained

The framework uses 9 standardized levels that map to typical tech company structures:

Level Name Typical Years Description
L1 Trainee 0-1 Fresh graduate, in training
L2 Junior I 1-2 Executes defined tasks with supervision
L3 Junior II 2-3 Autonomy on low complexity tasks
L4 Mid-level I 3-5 Full autonomy on medium features
L5 Mid-level II 5-7 Leads features, starts mentoring
L6 Senior I 7-10 Technical leadership, architecture decisions
L7 Senior II 10-12 Team's technical reference
L8 Staff/Principal 12-15 Cross-team impact, defines standards
L9 VP/CTO 15+ Strategic leadership, technical vision

Years are indicative. An exceptional developer can reach L6 in 5 years. One who stagnates can remain at L4 with 10 years of experience. What matters is demonstrated competencies, not the calendar.

Real use cases

Candidate evaluation system

// Candidate claims Senior level (L6)
const expectedCompetencies = library.getCompetencies('Backend Developer', 'L6');

// Compare with competencies demonstrated in interview
const demonstrated = evaluateInterview(candidate);

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

if (gaps.length > 3) {
  console.log('Candidate does not meet L6 level, gaps:', gaps);
  // Suggest L5 or L4 based on gaps
}

Individual development plan

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

// Generate development plan
const developmentPlan = {
  currentLevel: employee.currentLevel,
  targetLevel: nextLevel.next.level,
  timeframe: `${nextLevel.next.yearsRange.min - 3} - ${nextLevel.next.yearsRange.max - 3} years`,
  competenciesToDevelop: nextLevel.newCompetencies,
  suggestedTraining: mapCompetenciesToCourses(nextLevel.newCompetencies)
};

Salary comparison by level

// Your salary database by level
const salaryBands = {
  'L4': { min: 35000, max: 45000 },
  'L5': { min: 45000, max: 55000 },
  'L6': { min: 55000, max: 70000 }
};

// Employee requests raise
const employee = library.getRole('FE-L5');
const band = salaryBands['L5'];

console.log(`Salary band for ${employee.level}: €${band.min} - €${band.max}`);

Technical org charts

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

Validation and data quality

The library passed 99 tests before publication:

  • Structural integrity: All valid JSON, no missing fields
  • Level consistency: Each role has exactly 9 levels L1-L9
  • Translation validation: 0% contamination between languages (no English words in ES files or vice versa)
  • Coherent year ranges: L1 < L2 < L3... without overlaps
  • Unique codes: No duplicates in the 702 role-level codes

Each release runs complete validation. If you add a new role via PR, tests verify it has correct structure, 9 levels, complete translations, and codes following existing pattern.

TypeScript: complete types

The package includes TypeScript definitions. No additional @types/ needed:

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

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

// TypeScript knows return types
const role: RoleEntry = library.getRole('BE-L5');
const career: CareerPath = library.getCareerPathComplete('Backend Developer', 'L5');
const results: SearchResult[] = library.search('frontend');

Types are complete: RoleEntry, CareerPath, SearchResult, LibraryStatistics, configuration options. VS Code autocompletion works perfectly.

Zero dependencies

The package has no runtime dependencies. package.json only lists devDependencies for testing and build. This means:

  • Minimal bundle size
  • No version conflicts with other libraries
  • No inherited vulnerabilities from dependencies
  • Works in any Node.js 16+ environment

Translation files are loaded with lazy loading. If you use the package in Spanish, English files don't load until you switch languages.

Interactive demo

You can explore the complete catalog in the web demo:

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

The demo allows:

  • Browse roles by category
  • View all 9 levels for each role
  • Explore competencies for each level
  • Switch between English and Spanish

Source code is on GitHub: github.com/686f6c61/npm-tech-roles-library

Package published on NPM: @sparring/tech-roles-library

Contributions welcome to add missing roles, improve translations, or correct competencies that don't reflect current market reality.