A lightweight, zero-dependency TypeScript library for masking email addresses.
✨ Lightweight - Zero dependencies
🔒 Privacy-focused - Mask sensitive email information
📦 TypeScript - Full type safety and IntelliSense support
⚙️ Customizable - Flexible masking options
🎯 Simple API - Easy to use with sensible defaults
npm install @ekaone/mask-emailyarn add @ekaone/mask-emailpnpm add @ekaone/mask-emailimport { maskEmail, maskEmailBatch, validateEmail, isValidEmail, anonymizeEmail, anonymizeEmailBatch } from '@ekaone/mask-email';
maskEmail('[email protected]');
// Output: 'ek********@gmail.com'
// Batch masking
maskEmailBatch(['[email protected]', '[email protected]']);
// Output: ['jo**@example.com', 'ja**@company.com']import { maskEmail } from '@ekaone/mask-email';
// Default masking (shows first 2 characters)
maskEmail('[email protected]');
// Output: 'jo******@example.com'
maskEmail('[email protected]');
// Output: 'ad***@company.com'Control how many characters remain visible at the beginning of the username:
// Show first 4 characters
maskEmail('[email protected]', { visibleChars: 4 });
// Output: 'ekao******@gmail.com'
// Show only 1 character
maskEmail('[email protected]', { visibleChars: 1 });
// Output: 'e*********@gmail.com'Change the masking character from the default *:
maskEmail('[email protected]', { maskChar: '#' });
// Output: 'us##@example.com'
maskEmail('[email protected]', { maskChar: '•' });
// Output: 'us••@example.com'
maskEmail('[email protected]', { maskChar: '-' });
// Output: '[email protected]'Mask the domain part of the email as well:
// Mask domain
maskEmail('[email protected]', { maskDomain: true });
// Output: 'us**@g****.com'
// Works with subdomains
maskEmail('[email protected]', { maskDomain: true });
// Output: 'co*****@m***.g*****.com'Process multiple emails at once with the same options:
import { maskEmailBatch } from '@ekaone/mask-email';
// Basic batch masking
const emails = [
'[email protected]',
'[email protected]',
'[email protected]'
];
maskEmailBatch(emails);
// Output: ['jo******@example.com', 'ja********@company.com', 'ad***@site.org']
// Batch with custom options
maskEmailBatch(emails, { visibleChars: 3, maskChar: '#' });
// Output: ['joh#####@example.com', 'jan#######@company.com', 'adm##@site.org']
// Batch with domain masking
maskEmailBatch(emails, { maskDomain: true });
// Output: ['jo******@ex******.com', 'ja********@co******.com', 'ad***@si**.org']Return the original email without masking (useful for admin views):
maskEmail('[email protected]', { viewable: true });
// Output: '[email protected]'Mix and match options for custom masking behavior:
maskEmail('[email protected]', {
visibleChars: 3,
maskChar: '-',
maskDomain: true
});
// Output: '[email protected]'
maskEmail('[email protected]', {
visibleChars: 1,
maskChar: '*',
maskDomain: true
});
// Output: 'a****@m***.c******.com'Replace the username with a random identifier for complete privacy:
import { anonymizeEmail, anonymizeEmailBatch } from '@ekaone/mask-email';
// Basic anonymization
anonymizeEmail('[email protected]');
// Output: 'user_a1b2c3@*****.com'
// Custom prefix and ID length
anonymizeEmail('[email protected]', { prefix: 'anon', idLength: 8 });
// Output: 'anon_x7y2k9m4@*******.com'
// Keep domain visible
anonymizeEmail('[email protected]', { maskDomain: false });
// Output: '[email protected]'
// Batch anonymization
const emails = ['[email protected]', '[email protected]'];
anonymizeEmailBatch(emails);
// Output: ['user_a1b2c3@****.com', 'user_x7y8z9@****.com']Process multiple emails with the same options:
import { maskEmailBatch } from '@ekaone/mask-email';
const emails = [
'[email protected]',
'[email protected]',
'[email protected]'
];
// Basic batch masking
maskEmailBatch(emails);
// Output: ['jo******@example.com', 'ja********@company.com', 'ad***@site.org']
// Batch with custom options
maskEmailBatch(emails, { visibleChars: 3, maskChar: '#' });
// Output: ['joh#####@example.com', 'jan#######@company.com', 'adm##@site.org']
// Batch with domain masking
maskEmailBatch(emails, { maskDomain: true });
// Output: ['jo******@ex******.com', 'ja********@co******.com', 'ad***@si**.org']Validate email format and optionally mask valid emails:
import { validateEmail, isValidEmail } from '@ekaone/mask-email';
// Validate and get masked email
const result = validateEmail('[email protected]');
// Returns: { valid: true, original: 'test@example.com', masked: 'te**@example.com' }
// Validation with custom masking options
const custom = validateEmail('[email protected]', { visibleChars: 3 });
// Returns: { valid: true, original: 'user@test.com', masked: 'use*@test.com' }
// Invalid email
const invalid = validateEmail('invalid-email');
// Returns: { valid: false, original: 'invalid-email', masked: null, error: 'Invalid email format' }
// Quick boolean check
isValidEmail('[email protected]'); // true
isValidEmail('invalid'); // false
isValidEmail(''); // falseMasks an array of email addresses with the same options applied to each email.
- emails (
string[]) - Array of email addresses to mask - options (
EmailOptions, optional) - Configuration options (same asmaskEmail)
- (
string[]) - Array of masked email addresses
const emails = ['[email protected]', '[email protected]'];
maskEmailBatch(emails, { visibleChars: 1 });
// Output: ['u***@test.com', 'u***@demo.com']Masks an email address according to the provided options.
- email (
string) - The email address to mask - options (
EmailOptions, optional) - Configuration options
| Option | Type | Default | Description |
|---|---|---|---|
maskChar |
string |
'*' |
Character used for masking |
visibleChars |
number |
2 |
Number of characters visible at the beginning |
visibleCharsEnd |
number |
0 |
Number of characters visible at the end |
maskPercentage |
number |
- | Mask based on percentage (0-100), takes precedence over visibleChars |
maskDomain |
boolean | 'full' |
false |
Mask domain: true/'partial' masks parts keeping TLD, 'full' masks entire domain |
viewable |
boolean |
false |
Return original email without masking |
- (
string) - The masked email address
interface EmailOptions {
/** Character used for masking (default: '*') */
maskChar?: string;
/** Number of characters visible at the beginning (default: 2) */
visibleChars?: number;
/** Number of characters visible at the end (default: 0) */
visibleCharsEnd?: number;
/** Mask based on percentage (0-100), takes precedence over visibleChars */
maskPercentage?: number;
/** Return original email without masking (default: false) */
viewable?: boolean;
/** Mask domain: true/partial keeps TLD visible, 'full' masks entire domain (default: false) */
maskDomain?: boolean | 'full';
}Validates an email address and returns a result object with validation status and optional masked email.
- email (
string) - The email address to validate - options (
EmailOptions, optional) - Masking options applied if email is valid
- (
EmailValidationResult) - Object containing:valid(boolean) - Whether the email format is validoriginal(string) - The original email addressmasked(string | null) - Masked email if valid, null if invaliderror(string, optional) - Error message if validation failed
const result = validateEmail('[email protected]');
// Returns: { valid: true, original: 'test@example.com', masked: 'te**@example.com' }
const invalid = validateEmail('invalid-email');
// Returns: { valid: false, original: 'invalid-email', masked: null, error: 'Invalid email format' }interface EmailValidationResult {
valid: boolean;
original: string;
masked: string | null;
error?: string;
}Quick boolean validation without masking. Returns true if the email is valid, false otherwise.
- email (
string) - The email address to validate
- (
boolean) -trueif valid,falseotherwise
isValidEmail('[email protected]'); // true
isValidEmail('invalid'); // false
isValidEmail(''); // falseAnonymizes an email by replacing the username with a random identifier. Useful for complete privacy protection.
- email (
string) - The email address to anonymize - options (
AnonymizeOptions, optional) - Anonymization options
| Option | Type | Default | Description |
|---|---|---|---|
prefix |
string |
'user' |
Prefix for the anonymous identifier |
idLength |
number |
6 |
Length of the random identifier |
maskDomain |
boolean |
true |
Whether to mask the domain part |
- (
string) - Anonymized email address
anonymizeEmail('[email protected]');
// Output: 'user_a1b2c3@*****.com'
anonymizeEmail('[email protected]', { prefix: 'anon', idLength: 8 });
// Output: 'anon_x7y2k9m4@*******.com'
anonymizeEmail('[email protected]', { maskDomain: false });
// Output: '[email protected]'interface AnonymizeOptions {
prefix?: string;
idLength?: number;
maskDomain?: boolean;
}Batch anonymize multiple email addresses with the same options.
- emails (
string[]) - Array of email addresses to anonymize - options (
AnonymizeOptions, optional) - Anonymization options applied to all emails
- (
string[]) - Array of anonymized email addresses
const emails = ['[email protected]', '[email protected]'];
anonymizeEmailBatch(emails);
// Output: ['user_a1b2c3@****.com', 'user_x7y8z9@****.com']
anonymizeEmailBatch(emails, { prefix: 'anon' });
// Output: ['anon_k3m9p2@****.com', 'anon_q5n8r4@****.com']const userEmail = '[email protected]';
const displayEmail = maskEmail(userEmail);
console.log(`Confirmation sent to: ${displayEmail}`);
// Output: "Confirmation sent to: cu******@company.com"const emails = [
'[email protected]',
'[email protected]',
'[email protected]'
];
emails.forEach(email => {
console.log('Processing:', maskEmail(email, { visibleChars: 3 }));
});
// Output:
// Processing: adm**@site.com
// Processing: use****@example.com
// Processing: con****@business.orgfunction getUserEmailForDisplay(email: string, userRole: string) {
if (userRole === 'admin') {
return maskEmail(email, { viewable: true });
} else if (userRole === 'moderator') {
return maskEmail(email, { visibleChars: 4, maskDomain: false });
} else {
return maskEmail(email, { visibleChars: 2, maskDomain: true });
}
}
console.log(getUserEmailForDisplay('[email protected]', 'admin'));
// Output: '[email protected]'
console.log(getUserEmailForDisplay('[email protected]', 'moderator'));
// Output: '[email protected]'
console.log(getUserEmailForDisplay('[email protected]', 'user'));
// Output: 'jo**@e******.com'// Show masked email in public profiles
function displayPublicProfile(user: { name: string; email: string }) {
return {
name: user.name,
email: maskEmail(user.email, { maskDomain: true })
};
}
const profile = displayPublicProfile({
name: 'John Doe',
email: '[email protected]'
});
console.log(profile);
// Output: { name: 'John Doe', email: 'jo******@e******.com' }The library handles various edge cases gracefully:
// Very short usernames
maskEmail('[email protected]', { visibleChars: 2 });
// Output: '[email protected]' (shows all available characters)
// Invalid email format (no @ symbol)
maskEmail('notanemail');
// Output: 'notanemail' (returns as-is)
// Empty or null values
maskEmail('');
// Output: ''
maskEmail(null);
// Output: null
// Multiple @ symbols (technically invalid but handled)
maskEmail('user@[email protected]');
// Output: 'us*******@domain.com' (uses last @ as separator)
// Subdomains
maskEmail('[email protected]', { maskDomain: true });
// Output: 'us**@m***.g*****.com'This library works in all modern browsers and Node.js environments that support ES2015+.
- ✅ Chrome (latest)
- ✅ Firefox (latest)
- ✅ Safari (latest)
- ✅ Edge (latest)
- ✅ Node.js 14+
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
MIT © Eka Prasetia
⭐ If this library helps you, please consider giving it a star on GitHub!
