npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

nino-validator

v1.0.0

Published

A lightweight npm package for validating UK National Insurance Numbers (NINO)

Readme

NINO Validator

npm version License: MIT

A lightweight, fast, and comprehensive npm package for validating UK National Insurance Numbers (NINO) with full compliance to HMRC rules.

Features

  • Complete HMRC compliance - Validates against all official NINO rules
  • 🚀 Blazing fast - 5M+ ops/sec, zero dependencies, all functions rated "Excellent"
  • 🛡️ Type safe - Full JSDoc documentation with TypeScript-friendly types
  • 🔧 Flexible options - Configurable validation behavior
  • 🎯 100% test coverage - Thoroughly tested with comprehensive test suite
  • 📱 Cross-platform - Works in Node.js and browsers
  • 📦 Dual package - Supports both CommonJS and ES Modules (ESM)
  • 🏷️ TypeScript ready - Includes TypeScript declaration files

Installation

npm install nino-validator

Quick Start

CommonJS (Node.js)

const { validateNINO } = require('nino-validator');

// Simple validation
console.log(validateNINO('AB123456C')); // true
console.log(validateNINO('invalid'));   // false

ES Modules (ESM)

import { validateNINO } from 'nino-validator';

// Simple validation
console.log(validateNINO('AB123456C')); // true
console.log(validateNINO('invalid'));   // false

TypeScript

import { validateNINO, ValidationOptions } from 'nino-validator';

const options: ValidationOptions = { requireSuffix: true };
const isValid: boolean = validateNINO('AB123456C', options);

Complete Usage Guide

Basic Validation

CommonJS:

const { validateNINO, formatNINO, parseNINO, generateRandomNINO } = require('nino-validator');

ES Modules:

import { validateNINO, formatNINO, parseNINO, generateRandomNINO } from 'nino-validator';

Usage (same for both formats):

// Validate different NINO formats
validateNINO('AB123456C');        // true - standard format
validateNINO('AB123456');         // true - suffix optional by default
validateNINO('ab123456c');        // true - case insensitive
validateNINO('AB 12 34 56 C');    // true - spaces allowed by default
validateNINO('  AB123456C  ');    // true - whitespace trimmed
validateNINO('invalid-nino');     // false - invalid format

Advanced Validation Options

// Require suffix letter
validateNINO('AB123456', { requireSuffix: true });   // false - no suffix
validateNINO('AB123456C', { requireSuffix: true });  // true - has suffix

// Strict formatting (no spaces allowed)
validateNINO('AB 12 34 56 C', { allowSpaces: false }); // false - contains spaces
validateNINO('AB123456C', { allowSpaces: false });     // true - no spaces

// Combine options
validateNINO('AB123456C', { 
  requireSuffix: true, 
  allowSpaces: false 
}); // true

Formatting NINOs

// Standard formatting with spaces
formatNINO('AB123456C');    // 'AB 12 34 56 C'
formatNINO('ab123456c');    // 'AB 12 34 56 C' (normalized)
formatNINO('AB123456');     // 'AB 12 34 56' (no suffix)
formatNINO('invalid');      // null (invalid NINO)

// Clean up user input
const userInput = '  ab 12 34 56 c  ';
const formatted = formatNINO(userInput); // 'AB 12 34 56 C'

Parsing NINO Components

// Extract all components
const result = parseNINO('AB123456C');
console.log(result);
// Output:
// {
//   prefix: 'AB',
//   numbers: '123456', 
//   suffix: 'C',
//   formatted: 'AB 12 34 56 C',
//   original: 'AB123456C'
// }

// Handle NINOs without suffix
const noSuffix = parseNINO('AB123456');
console.log(noSuffix.suffix); // null

// Invalid NINOs return null
parseNINO('invalid'); // null

Generate Test Data

// Generate random valid NINOs for testing
const testNINO = generateRandomNINO(); 
console.log(testNINO);           // e.g., 'JG123789A'
console.log(validateNINO(testNINO)); // always true

// Generate multiple test cases
const testCases = Array.from({ length: 10 }, () => generateRandomNINO());
console.log(testCases);
// ['AB123456C', 'JK789012G', 'MN345678P', ...]

API Reference

validateNINO(nino, options?)

Validates a UK National Insurance Number against HMRC rules.

Parameters:

  • nino (string): The NINO to validate
  • options (object, optional):
    • allowSpaces (boolean, default: true): Allow spaces in the input
    • requireSuffix (boolean, default: false): Require the suffix letter

Returns: boolean - true if valid, false otherwise

Example:

validateNINO('AB123456C');                        // true
validateNINO('AB123456', { requireSuffix: true }); // false

formatNINO(nino)

Formats a NINO with standard UK government spacing (XX ## ## ## X).

Parameters:

  • nino (string): The NINO to format

Returns: string | null - Formatted NINO or null if invalid

Example:

formatNINO('AB123456C'); // 'AB 12 34 56 C'
formatNINO('invalid');   // null

parseNINO(nino)

Extracts and validates components from a NINO.

Parameters:

  • nino (string): The NINO to parse

Returns: object | null - Components object or null if invalid

Return object structure:

{
  prefix: string;      // Two-letter prefix (e.g., 'AB')
  numbers: string;     // Six-digit number (e.g., '123456')
  suffix: string | null; // Single suffix letter or null
  formatted: string;   // Standardized format
  original: string;    // Original input
}

generateRandomNINO()

Generates a random valid NINO for testing purposes.

Returns: string - A randomly generated valid NINO

Example:

const testNINO = generateRandomNINO(); // 'JK789012M'

validateNINOWithDetails(nino, options?)

Provides detailed validation with localized error messages.

Parameters:

  • nino (string): The NINO to validate
  • options (object, optional): Same as validateNINO()

Returns: ValidationResult - Detailed validation result

Return object structure:

{
  isValid: boolean;
  error: string | null;       // Localized error message
  errorCode: string | null;   // Machine-readable error code
  suggestion: string | null;  // Localized suggestion
}

Example:

const result = validateNINOWithDetails('AB123');
console.log(result);
// {
//   isValid: false,
//   error: 'NINO too short (5 characters). Minimum 8 characters required',
//   errorCode: 'TOO_SHORT',
//   suggestion: 'Ensure the NINO has 2 letters, 6 digits, and optionally 1 letter'
// }

Internationalization (i18n)

The NINO Validator supports multiple languages for error messages. Currently supported languages are English (en) and Greek (el).

Language Management

const { 
  setLanguage, 
  getCurrentLanguage, 
  getSupportedLanguages,
  isLanguageSupported 
} = require('nino-validator');

// Check supported languages
console.log(getSupportedLanguages());
// { en: 'English', el: 'Ελληνικά (Greek)' }

// Switch to Greek
setLanguage('el');
console.log(getCurrentLanguage()); // 'el'

// Validate with Greek error messages
const result = validateNINOWithDetails('invalid');
console.log(result.error);
// 'Μη έγκυρη μορφή NINO. Αναμενόμενη μορφή: XX123456X (το επίθημα είναι προαιρετικό)'

// Switch back to English
setLanguage('en');

Auto-Detection and Initialization

const { detectLanguage, initializeI18n } = require('nino-validator');

// Auto-detect language from environment
const detected = detectLanguage();
console.log(detected); // 'el' if Greek locale detected

// Initialize with auto-detection
const language = initializeI18n({ autoDetect: true });
console.log(`Language set to: ${language}`);

// Initialize with fallback
initializeI18n({ 
  autoDetect: true, 
  fallbackLanguage: 'el' 
});

Language Support Features

  • Consistent Error Codes: Error codes remain the same across languages for programmatic handling
  • Parameter Interpolation: Dynamic values (like lengths, invalid characters) are properly inserted into translated messages
  • Environment Detection: Automatically detects language from Node.js environment variables or browser settings
  • Fallback Handling: Gracefully falls back to English if requested language is not supported

Adding New Languages

To add support for additional languages, error messages need to be translated in the internal message files. Contact the maintainer for language addition requests.

NINO Validation Rules

This package validates against all official HMRC rules:

✅ Valid Format

  • Structure: Two letters + Six digits + One optional letter
  • Example: AB123456C or AB123456

❌ Invalid Patterns

  1. Invalid Prefixes: BG, GB, NK, KN, TN, NT, ZZ, and all combinations starting with D, F, G, I, N, O, Q, U, V
  2. Invalid First Letters: D, F, I, Q, U, V
  3. Invalid Second Letters: D, F, I, Q, U, V
  4. Invalid Suffixes: D, F, I, Q, U, V
  5. Repeated Numbers: All six digits cannot be identical (e.g., 111111)

Examples

// ✅ Valid NINOs
'AB123456C'    // Standard format
'AB123456'     // Without suffix
'JG103759A'    // Real-world example
'AB 12 34 56 C' // With spaces

// ❌ Invalid NINOs  
'BG123456C'    // Invalid prefix 'BG'
'AB111111C'    // All digits the same
'AB123456D'    // Invalid suffix 'D'
'DA123456C'    // Invalid first letter 'D'
'AB12345'      // Too few digits
'A1234567'     // Wrong format

Error Handling

The package handles errors gracefully:

// Type safety
validateNINO(null);        // false
validateNINO(undefined);   // false  
validateNINO(123456789);   // false
validateNINO('');          // false

// Invalid formats return null
formatNINO('invalid');     // null
parseNINO('invalid');      // null

// Options validation
validateNINO('AB123456C', { invalidOption: true }); // Works (ignores invalid options)

Performance

NINO Validator is designed for high performance with comprehensive benchmarking:

  • Zero dependencies - No external packages required
  • Fast validation - Optimized regex and lookup operations
  • Memory efficient - Minimal memory footprint
  • Browser compatible - Works in all modern browsers

Performance Benchmarks

Run comprehensive performance tests:

# Full benchmark suite with detailed analysis
npm run benchmark

# Quick CI-friendly performance check  
npm run benchmark:ci

# Memory-focused benchmarks with GC control
npm run benchmark:memory

Sample Benchmark Output:

⚡ NINO Validator CI Benchmarks
===============================
✅ validateNINO (valid)           | 2,350,000 ops/sec |    0.4μs/op
✅ validateNINO (invalid)         | 5,150,000 ops/sec |    0.2μs/op  
✅ formatNINO                     |   915,000 ops/sec |    1.1μs/op
✅ parseNINO                      |   800,000 ops/sec |    1.2μs/op
✅ generateRandomNINO             |   575,000 ops/sec |    1.7μs/op
✅ Bulk validation                | 3,000,000 ops/sec |    0.3μs/op

🎯 Performance check: ✅ PASS

Typical Performance Results

On modern hardware (Node.js v18+):

| Function | Operations/Second | Rating | Use Case | |----------|------------------|--------|----------| | validateNINO (valid) | 2,350,000+ | 🟢 Excellent | Form validation | | validateNINO (invalid) | 5,150,000+ | 🟢 Excellent | Input filtering | | formatNINO | 915,000+ | 🟢 Excellent | Display formatting | | parseNINO | 800,000+ | 🟢 Excellent | Data extraction | | generateRandomNINO | 575,000+ | 🟢 Excellent | Test data generation | | Bulk validation | 3,000,000+ | 🟢 Excellent | Batch processing |

Performance Ratings Scale

| Rating | Operations/Second | Description | |--------|------------------|-------------| | 🟢 Excellent | ≥100,000 | Outstanding performance | | 🟡 Good | ≥10,000 | Acceptable performance | | 🔴 Poor | <10,000 | May need optimization |

Performance Insights:

  • Invalid inputs are validated ~2x faster than valid ones (short-circuit validation)
  • Bulk operations can process over 3 million NINOs per second
  • Memory usage is minimal (~0.1MB for 10,000 operations)
  • All functions consistently achieve "Excellent" performance ratings
  • Zero performance degradation with large datasets

See benchmark documentation for detailed performance analysis and optimization tips.

Browser Usage

<!DOCTYPE html>
<html>
<head>
    <script src="https://unpkg.com/nino-validator@latest/index.js"></script>
</head>
<body>
    <script>
        // Use the global ninoValidator object
        console.log(ninoValidator.validateNINO('AB123456C')); // true
    </script>
</body>
</html>

TypeScript Support

While this package is written in JavaScript, it includes comprehensive JSDoc comments for TypeScript IntelliSense:

import { validateNINO, formatNINO, parseNINO, generateRandomNINO } from 'nino-validator';

const isValid: boolean = validateNINO('AB123456C');
const formatted: string | null = formatNINO('AB123456C');

Testing

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

# Run linting
npm run lint

Real-World Examples

Form Validation

function validateNINOInput(input) {
  const nino = input.trim();
  
  if (!nino) {
    return { valid: false, error: 'NINO is required' };
  }
  
  if (!validateNINO(nino)) {
    return { valid: false, error: 'Invalid NINO format' };
  }
  
  return { valid: true, formatted: formatNINO(nino) };
}

// Usage
const result = validateNINOInput('  ab 12 34 56 c  ');
console.log(result); // { valid: true, formatted: 'AB 12 34 56 C' }

Database Storage

function normalizeNINO(input) {
  const parsed = parseNINO(input);
  if (!parsed) return null;
  
  return {
    prefix: parsed.prefix,
    numbers: parsed.numbers,
    suffix: parsed.suffix,
    display: parsed.formatted
  };
}

Test Data Generation

function createTestUser() {
  return {
    id: Math.random().toString(36),
    nino: generateRandomNINO(),
    name: 'Test User'
  };
}

Changelog

See CHANGELOG.md for version history.

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Add tests for new functionality
  5. Ensure all tests pass (npm test)
  6. Commit your changes (git commit -m 'Add amazing feature')
  7. Push to the branch (git push origin feature/amazing-feature)
  8. Open a Pull Request

Development Setup

git clone https://github.com/icodenet/nino-validator.git
cd nino-validator
npm install
npm test

License

MIT © Byron Thanopoulos

Support