A lightweight npm package for validating UK National Insurance Numbers (NINO)
npm install nino-validator

A lightweight, fast, and comprehensive npm package for validating UK National Insurance Numbers (NINO) with full compliance to HMRC rules.
- ✅ 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
``bash`
npm install nino-validator
javascript
const { validateNINO } = require('nino-validator');// Simple validation
console.log(validateNINO('AB123456C')); // true
console.log(validateNINO('invalid')); // false
`$3
`javascript
import { validateNINO } from 'nino-validator';// Simple validation
console.log(validateNINO('AB123456C')); // true
console.log(validateNINO('invalid')); // false
`$3
`typescript
import { validateNINO, ValidationOptions } from 'nino-validator';const options: ValidationOptions = { requireSuffix: true };
const isValid: boolean = validateNINO('AB123456C', options);
`Complete Usage Guide
$3
CommonJS:
`javascript
const { validateNINO, formatNINO, parseNINO, generateRandomNINO } = require('nino-validator');
`ES Modules:
`javascript
import { validateNINO, formatNINO, parseNINO, generateRandomNINO } from 'nino-validator';
`Usage (same for both formats):
`javascript
// 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
`$3
`javascript
// 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
`$3
`javascript
// 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'
`$3
`javascript
// 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
`$3
`javascript
// 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
$3
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 letterReturns:
boolean - true if valid, false otherwiseExample:
`javascript
validateNINO('AB123456C'); // true
validateNINO('AB123456', { requireSuffix: true }); // false
`$3
Formats a NINO with standard UK government spacing (XX ## ## ## X).
Parameters:
-
nino (string): The NINO to formatReturns:
string | null - Formatted NINO or null if invalidExample:
`javascript
formatNINO('AB123456C'); // 'AB 12 34 56 C'
formatNINO('invalid'); // null
`$3
Extracts and validates components from a NINO.
Parameters:
-
nino (string): The NINO to parseReturns:
object | null - Components object or null if invalidReturn object structure:
`typescript
{
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
}
`$3
Generates a random valid NINO for testing purposes.
Returns:
string - A randomly generated valid NINOExample:
`javascript
const testNINO = generateRandomNINO(); // 'JK789012M'
`$3
Provides detailed validation with localized error messages.
Parameters:
-
nino (string): The NINO to validate
- options (object, optional): Same as validateNINO()Returns:
ValidationResult - Detailed validation resultReturn object structure:
`typescript
{
isValid: boolean;
error: string | null; // Localized error message
errorCode: string | null; // Machine-readable error code
suggestion: string | null; // Localized suggestion
}
`Example:
`javascript
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).$3
`javascript
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');
`$3
`javascript
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'
});
`$3
- 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
$3
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:
$3
- Structure: Two letters + Six digits + One optional letter
- Example: AB123456C or AB123456$3
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)
$3
`javascript
// ✅ 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:
`javascript
// 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
$3
Run comprehensive performance tests:
`bash
Full benchmark suite with detailed analysis
npm run benchmarkQuick CI-friendly performance check
npm run benchmark:ciMemory-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
`$3
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 |$3
| 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
`html
`TypeScript Support
While this package is written in JavaScript, it includes comprehensive JSDoc comments for TypeScript IntelliSense:
`typescript
import { validateNINO, formatNINO, parseNINO, generateRandomNINO } from 'nino-validator';const isValid: boolean = validateNINO('AB123456C');
const formatted: string | null = formatNINO('AB123456C');
`Testing
`bash
Run tests
npm testRun tests with coverage
npm run test:coverageRun linting
npm run lint
`Real-World Examples
$3
`javascript
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' }
`$3
`javascript
function normalizeNINO(input) {
const parsed = parseNINO(input);
if (!parsed) return null;
return {
prefix: parsed.prefix,
numbers: parsed.numbers,
suffix: parsed.suffix,
display: parsed.formatted
};
}
`$3
`javascript
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$3
`bash
git clone https://github.com/icodenet/nino-validator.git
cd nino-validator
npm install
npm test
``MIT © Byron Thanopoulos
- 📧 Email: byron.thanopoulos@gmail.com
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions