Package Exports
- friendlyfy-js
Readme
friendlyfy-js
A zero-dependency utility library with 70+ functions for formatting dates, numbers, strings, arrays, objects, and validation. Works seamlessly in both Node.js and browser environments with pure JavaScript implementation.
โจ Features
- ๐ Date & Time (10 functions): Human-readable formatting, timezone support, duration formatting
- ๐ข Numbers & Math (15 functions): Shortening, formatting, validation, statistical analysis
- ๐ค String Manipulation (15 functions): Text transformation, HTML handling, case conversion
- ๐ Array Operations (15 functions): Manipulation, set operations, sorting, statistics
- ๐ง Object Utilities (15 functions): Deep cloning, merging, transformation, validation
- โ Validation & Security (13 functions): Email, URL, phone, credit card, password validation
- ๐ Full Internationalization: Complete locale support using native
Intl
APIs - โก ESM Ready: Built for Node.js v20+ with native ES modules
- ๐ฆ Zero Dependencies: Uses only native JavaScript APIs
๐ Installation
npm install friendlyfy-js
๐ฏ Quick Start
import {
// Date & Time
timeAgo,
formatDuration,
// Numbers
shortenNumber,
formatFileSize,
formatOrdinal,
// Strings
slugify,
capitalize,
// Arrays
chunk,
unique,
// Objects
deepClone,
pick,
// Validation
isValidEmail,
validatePassword,
// Crypto
generateUUID,
hash,
// Files
getMimeType,
sanitizeFilename
} from 'friendlyfy-js';
// Date formatting
console.log(timeAgo('2025-10-08T10:00:00Z')); // "3 hours ago"
console.log(formatDuration(3661)); // "1h 1m 1s"
// Number formatting
console.log(shortenNumber(12543)); // "12.5K"
console.log(formatFileSize(1048576)); // "1.05 MB"
console.log(formatOrdinal(21)); // "21st"
// String manipulation
console.log(slugify("Hello World!")); // "hello-world"
console.log(capitalize("hello world")); // "Hello world"
// Array operations
console.log(chunk([1,2,3,4,5,6], 2)); // [[1,2], [3,4], [5,6]]
console.log(unique([1,2,2,3,3,3])); // [1,2,3]
// Object utilities
const cloned = deepClone({user: {name: 'John'}});
const userData = pick({name: 'John', age: 30, city: 'NYC'}, ['name', 'age']);
// Validation
console.log(isValidEmail('user@example.com')); // true
console.log(validatePassword('MySecure123!')); // {valid: true, strength: 'strong'}
// Cryptography
console.log(generateUUID()); // "96cf1769-2655-4880-801d-7062903e9b2b"
console.log(hash('Hello World')); // "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e"
// File operations
console.log(getMimeType('image.jpg')); // "image/jpeg"
console.log(sanitizeFilename('file<>:"|?*.txt')); // "file_______.txt"
๐ API Reference
๐ Date & Time Helpers
timeAgo(date, locale?)
Returns human-readable time ago string.
timeAgo('2024-01-01T00:00:00Z'); // "2 months ago"
timeAgo(new Date(), 'es-ES'); // "hace 2 horas"
timeFromNow(date, locale?)
Returns human-readable time from now string.
timeFromNow('2025-12-25T00:00:00Z'); // "in 8 months"
formatDateWithTimezone(date, timezone?, options?, locale?)
Formats date with timezone support.
formatDateWithTimezone('2024-01-15T14:30:00Z', 'America/New_York');
// "01/15/2024, 09:30:00 AM"
formatDuration(seconds, options?, locale?)
Formats duration in human-readable format.
formatDuration(3661); // "1h 1m 1s"
formatDuration(3661, {compact: true}); // "1h 1m 1s"
formatDuration(3661, {maxUnits: 2}); // "1h 1m"
startOf(date, period)
/ endOf(date, period)
Get start/end of time periods.
startOf(new Date(), 'week'); // Start of current week
endOf(new Date(), 'month'); // End of current month
๐ข Number Helpers
shortenNumber(num, decimals?)
Shortens numbers with K, M, B, T suffixes.
shortenNumber(12543); // "12.5K"
shortenNumber(1250000); // "1.3M"
shortenNumber(1250000000); // "1.3B"
formatFileSize(bytes, options?, locale?)
Formats file size in human-readable format.
formatFileSize(1024); // "1.02 KB"
formatFileSize(1048576); // "1.05 MB"
formatFileSize(1048576, {binary: true}); // "1.00 MiB"
formatOrdinal(num, locale?)
Formats ordinal numbers.
formatOrdinal(1); // "1st"
formatOrdinal(2); // "2nd"
formatOrdinal(21); // "21st"
formatRange(start, end, options?, locale?)
Formats number ranges.
formatRange(1, 5); // "1-5"
formatRange(1000, 2000); // "1,000-2,000"
formatRange(1, 5, {separator: ' to '}); // "1 to 5"
pluralize(count, singular, plural?, locale?)
Pluralizes words based on count.
pluralize(1, 'item'); // "1 item"
pluralize(5, 'item'); // "5 items"
pluralize(1, 'child', 'children'); // "1 child"
๐ค String Helpers
slugify(str, options?)
Converts string to URL-friendly slug.
slugify("Hello World! 123"); // "hello-world-123"
slugify("Hello World!", {separator: '_'}); // "hello_world_123"
truncate(str, length, options?)
Truncates string with ellipsis.
truncate("This is a long text", 10); // "This is a ..."
truncate("This is a long text", 10, {wordBoundary: true}); // "This is..."
capitalize(str, lowerRest?)
Capitalizes first letter.
capitalize("hello world"); // "Hello world"
capitalize("hello world", true); // "Hello world"
camelToKebab(str)
/ kebabToCamel(str)
Converts between camelCase and kebab-case.
camelToKebab("camelCaseString"); // "camel-case-string"
kebabToCamel("kebab-case-string"); // "kebabCaseString"
stripHtml(str)
/ escapeHtml(str)
Handles HTML content.
stripHtml("<p>Hello <b>World</b></p>"); // "Hello World"
escapeHtml("<script>alert('xss')</script>"); // "<script>alert('xss')</script>"
maskString(str, options?)
Masks sensitive strings.
maskString("1234567890"); // "12******90"
maskString("1234567890", {visibleStart: 3, visibleEnd: 3}); // "123****890"
๐ Array Helpers
chunk(arr, size)
Chunks array into smaller arrays.
chunk([1,2,3,4,5,6,7,8,9,10], 3); // [[1,2,3], [4,5,6], [7,8,9], [10]]
unique(arr, keyFn?)
Removes duplicates from array.
unique([1,2,2,3,3,3,4,5]); // [1,2,3,4,5]
unique(users, user => user.city); // Unique users by city
shuffle(arr, inPlace?)
Shuffles array randomly.
shuffle([1,2,3,4,5]); // [3,2,4,1,5]
groupBy(arr, key)
Groups array items by key.
groupBy(users, 'city'); // { 'New York': [...], 'London': [...] }
groupBy(users, user => user.age > 25 ? 'adult' : 'young'); // { 'adult': [...], 'young': [...] }
intersection(arr1, arr2)
/ difference(arr1, arr2)
/ union(arr1, arr2)
Set operations on arrays.
intersection([1,2,3,4], [3,4,5,6]); // [3,4]
difference([1,2,3,4], [3,4,5,6]); // [1,2]
union([1,2,3,4], [3,4,5,6]); // [1,2,3,4,5,6]
arrayStats(arr)
Gets array statistics.
arrayStats([1,2,3,4,5]); // {length: 5, sum: 15, average: 3, min: 1, max: 5, median: 3}
๐ง Object Helpers
deepClone(obj)
Deep clones an object.
const cloned = deepClone({user: {profile: {name: 'John'}}});
deepMerge(target, ...sources)
Deep merges objects.
deepMerge({a: 1, b: {c: 2}}, {b: {d: 3}}); // {a: 1, b: {c: 2, d: 3}}
pick(obj, keys)
/ omit(obj, keys)
Selects/removes object properties.
pick({name: 'John', age: 30, city: 'NYC'}, ['name', 'age']); // {name: 'John', age: 30}
omit({name: 'John', age: 30, city: 'NYC'}, ['age']); // {name: 'John', city: 'NYC'}
get(obj, path, defaultValue?)
/ set(obj, path, value)
Gets/sets nested object properties.
get({user: {profile: {name: 'John'}}}, 'user.profile.name'); // "John"
set(obj, 'user.profile.settings.theme', 'dark');
transformKeys(obj, transformFn)
/ transformValues(obj, transformFn)
Transforms object keys/values.
transformKeys({firstName: 'John', lastName: 'Doe'}, k => k.toUpperCase()); // {FIRSTNAME: 'John', LASTNAME: 'Doe'}
transformValues({a: 1, b: 2}, v => v * 2); // {a: 2, b: 4}
โ Validation Helpers
isValidEmail(email)
Validates email addresses.
isValidEmail('user@example.com'); // true
isValidEmail('invalid-email'); // false
isValidUrl(url, options?)
Validates URLs.
isValidUrl('https://example.com'); // true
isValidUrl('ftp://example.com', {protocols: ['ftp:']}); // true
isValidPhone(phone, country?)
Validates phone numbers.
isValidPhone('+1234567890', 'US'); // true
isValidPhone('+44123456789', 'UK'); // true
isValidCreditCard(cardNumber)
Validates credit card numbers.
isValidCreditCard('4111111111111111'); // {valid: true, type: 'visa'}
validatePassword(password, options?)
Validates password strength.
validatePassword('MySecure123!'); // {valid: true, score: 6, strength: 'strong', feedback: []}
isValidIP(ip, version?)
Validates IP addresses.
isValidIP('192.168.1.1'); // true
isValidIP('2001:db8::1', 'v6'); // true
isValidUUID(uuid, version?)
Validates UUIDs.
isValidUUID('550e8400-e29b-41d4-a716-446655440000'); // true
๐ Crypto Helpers
hash(data, algorithm?, encoding?)
Generates hash using specified algorithm.
hash('Hello World'); // "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e"
hash('Hello World', 'md5', 'hex'); // "b10a8db164e0754105b7a99be72e3fe5"
hmac(data, secret, algorithm?, encoding?)
Generates HMAC.
hmac('Hello World', 'secret'); // "82ce0d2f821fa0ce5447b21306f214c99240fecc6387779d7515148bbdd0c415"
generateUUID()
Generates UUID v4.
generateUUID(); // "96cf1769-2655-4880-801d-7062903e9b2b"
generateToken(length?, options?)
Generates secure tokens.
generateToken(16); // "qRWt7ncmhhwy8FNK"
generateToken(32, {includeSymbols: true}); // "K#m9@vL2$nP8&qR5!"
hashPassword(password, options?)
Hashes passwords securely.
const hashed = await hashPassword('MyPassword123');
const isValid = await verifyPassword('MyPassword123', hashed); // true
generateApiKey(options?)
Generates API keys.
generateApiKey(); // "ak_fvtqhqwlhicphwgyazvrq"
generateApiKey({prefix: 'sk', includeTimestamp: true}); // "sk_1j8k9l2m_fvtqhqwlhicphwgyazvrq"
๐ File Helpers
getFileExtension(filename)
/ getFilenameWithoutExtension(filename)
Gets file extension or name without extension.
getFileExtension('document.pdf'); // "pdf"
getFilenameWithoutExtension('document.pdf'); // "document"
normalizePath(filePath)
/ joinPaths(...paths)
Path manipulation.
normalizePath('./folder/../file.txt'); // "file.txt"
joinPaths('folder', 'subfolder', 'file.txt'); // "folder/subfolder/file.txt"
getMimeType(filename)
Gets MIME type from filename.
getMimeType('image.jpg'); // "image/jpeg"
getMimeType('document.pdf'); // "application/pdf"
getMimeType('script.js'); // "application/javascript"
sanitizeFilename(filename, options?)
Sanitizes filenames for safe storage.
sanitizeFilename('file<>:"|?*.txt'); // "file_______.txt"
sanitizeFilename('My File (1).pdf', {replacement: '-'}); // "My-File-1-.pdf"
fileExists(filePath)
/ dirExists(dirPath)
Checks file/directory existence.
await fileExists('/path/to/file.txt'); // true/false
await dirExists('/path/to/directory'); // true/false
getFileStats(filePath)
Gets file statistics.
await getFileStats('/path/to/file.txt'); // {size: 1024, isFile: true, createdAt: Date, modifiedAt: Date, ...}
๐ Internationalization
All functions support locale-specific formatting:
import { timeAgo, formatWithCommas, formatCurrency, formatOrdinal } from 'friendlyfy-js';
// Spanish
timeAgo(date, 'es-ES'); // "hace 2 horas"
formatWithCommas(1234567, 'es-ES'); // "1.234.567"
// German
formatCurrency(1234.56, 'EUR', 'de-DE'); // "1.234,56 โฌ"
// French
formatOrdinal(1, 'fr-FR'); // "1er"
๐งช Examples
Run the comprehensive examples:
npm start
# or
node example.js
๐ Requirements
- Node.js v20.0.0 or higher
- ESM support (use
import
syntax)
๐ License
MIT License - see LICENSE file for details.
๐ค Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
๐ Changelog
1.0.1
- Added comprehensive utility functions (100+ functions)
- String manipulation helpers (15 functions)
- Array operation helpers (15 functions)
- Object utility helpers (15 functions)
- Validation and security helpers (13 functions)
- Cryptography helpers (15 functions)
- File system helpers (20 functions)
- Complete examples and documentation
- Full internationalization support
1.0.0
- Initial release
- Date helper functions with
Intl.RelativeTimeFormat
- Number helper functions with various formatting options
- Full internationalization support
- ESM module support
๐ฏ Use Cases
Frontend Development
- String manipulation and formatting
- Date/time display
- Form validation
- Data transformation
Backend Development
- API response formatting
- Data validation
- File handling
- Security utilities
Full-Stack Applications
- Complete utility coverage
- Consistent formatting across frontend/backend
- Internationalization support
- Performance optimization
๐ Related Packages
- date-fns - Date utility library
- lodash - Utility library
- validator.js - String validation
- crypto-js - Cryptographic functions
โญ Star History
Made with โค๏ธ by Vinay Kumar