A lightweight, functional utility library for Node.js, Bun, and Deno.
- Zero runtime dependencies - Pure JavaScript, no external libs
- Functional programming - Pure functions, method chaining, immutability
- Modern JavaScript - ESM modules, JSDocs, TypeScript definitions
- Multi-language support - Intl-based text processing for any language
- Cryptographically secure - Uses
crypto.getRandomValues()for random generation - Tree-shakeable - Import only what you need
npm install @pwshub/bellajs
# or
pnpm install @pwshub/bellajs
# or
bun add @pwshub/bellajsBellaJS works directly in browsers via CDN. Load it from esm.sh or unpkg.com:
<script type="module">
import { genid } from "https://esm.sh/@pwshub/bellajs";
// or from unpkg.com
import { genid } from "https://unpkg.com/@pwshub/bellajs";
for (let i = 0; i < 5; i++) {
console.log(genid());
}
</script>import {
clone,
formatDate,
formatRelativeTime,
genid,
maybe,
pipe
} from '@pwshub/bellajs'
// Safe null handling with Maybe
const email = maybe(user)
.map(u => u.profile)
.map(p => p.email)
.orElse(() => 'default@example.com')
.value()
// Function composition
const process = pipe(
data => data.filter(x => x.active),
data => data.map(x => x.name),
names => names.join(', ')
)
// Generate secure random IDs
const id = genid(16, 'user_') // 'user_aB3xY9kL2mN5pQ7r'
// Format dates with multi-language support
formatDate(new Date(), 'vi') // "20:34:28, 3 thg 1, 2026"
formatRelativeTime(Date.now() - 300000, 'ja') // "5 分前"| Module | Functions | Description |
|---|---|---|
| Detection | 15 functions | Type checking utilities |
| String | 15 functions | Text manipulation and analysis |
| Random | 2 functions | Cryptographically secure random generation |
| Date | 7 functions | Date formatting and time calculations |
| Array | 15 functions | Array utilities and transformations |
| Object | 2 functions | Deep cloning and property copying |
| Functional | 4 functions | compose, pipe, curry, maybe |
| Number | 2 functions | Number formatting utilities |
| Similarity | 5 functions | String comparison and similarity |
| Store | 1 function | In-memory key-value store with TTL |
| Utility | 1 function | Property definition helper |
| Rating | 6 functions | Wilson Score, Bayesian Average, time-decay ratings |
✅ Safe for:
- Session IDs
- CSRF tokens
- Random identifiers
- Nonces
Uses crypto.getRandomValues() - cryptographically secure!
import { maybe } from '@pwshub/bellajs'
// Without maybe (nested if statements)
let email
if (user && user.profile && user.profile.contact) {
email = user.profile.contact.email
} else {
email = 'default@example.com'
}
// With maybe (clean chaining)
const email = maybe(user)
.map(u => u.profile)
.map(p => p.contact)
.map(c => c.email)
.orElse(() => 'default@example.com')
.value()import {
formatDate,
formatRelativeTime,
getWordCount,
truncate
} from '@pwshub/bellajs'
// Date formatting
formatDate(new Date(), 'en') // "Jan 3, 2026, 8:34:28 PM"
formatDate(new Date(), 'vi') // "20:34:28, 3 thg 1, 2026"
formatDate(new Date(), 'ja') // "2026/1/3 20:34:28"
formatDate(new Date(), 'zh') // "2026 年 1 月 3 日 GMT+7 下午8:34:28"
// Relative time
formatRelativeTime(Date.now() - 3600000, 'en') // "1 hour ago"
formatRelativeTime(Date.now() - 3600000, 'vi') // "1 giờ trước"
formatRelativeTime(Date.now() - 3600000, 'ko') // "1 시간 전"
// Word counting (works with CJK, Arabic, etc.)
getWordCount('Hello world') // 2
getWordCount('こんにちは世界') // 2
getWordCount('مرحبا بالعالم') // 2
// Truncate respecting word boundaries
truncate('Hello world this is a test', 3) // "Hello world this..."import { genid, randomInt } from '@pwshub/bellajs'
// Generate unique IDs
genid() // 'aB3xY9kL2mN5pQ7rS8tU0vW1xY2zA3bC' (32 chars)
genid(16) // 'kL2mN5pQ7rS8tU0v' (16 chars)
genid(16, 'user_') // 'user_aB3xY9kL2mN5p' (prefix included in length)
// Random integers (cryptographically secure)
randomInt(100) // 0-100
randomInt(1) // 0 or 1
randomInt(1000000) // 0-1000000import { memstore } from '@pwshub/bellajs'
// Create cache with 5-minute default TTL
const cache = memstore(300)
// Store data
cache.set('user:1', { name: 'John', email: 'john@example.com' })
// Retrieve data
const user = cache.get('user:1')
// Store with custom TTL (1 hour)
cache.set('session:abc', { userId: 1 }, 3600)
// Check existence
if (cache.has('user:1')) {
console.log('User cached')
}
// Get cache size (excludes expired entries)
console.log(`Cache has ${cache.size()} entries`)
// Iterate over entries
for (const [key, value] of cache.entries()) {
console.log(key, value)
}import { pipe, compose, curry, filter, map } from '@pwshub/bellajs'
// Left-to-right pipeline
const processUser = pipe(
user => user.profile,
profile => profile.settings,
settings => settings.theme
)
// Right-to-left composition
const analyze = compose(
result => result.toUpperCase(),
data => data.join('-'),
items => items.filter(x => x.active)
)
// Curried functions
const add = (a, b) => a + b
const curriedAdd = curry(add)
curriedAdd(5)(3) // 8
curriedAdd(5, 3) // 8import {
chunk,
flatten,
groupBy,
difference,
intersection,
zip
} from '@pwshub/bellajs'
// Chunk array
chunk([1, 2, 3, 4, 5], 2) // [[1,2], [3,4], [5]]
// Flatten nested arrays
flatten([1, [2, [3, [4]]]], 2) // [1, 2, 3, [4]]
// Group by property
groupBy(users, 'role') // { admin: [...], user: [...] }
// Array operations
difference([1, 2, 3, 4], [2, 3]) // [1, 4]
intersection([1, 2, 3], [2, 3, 4]) // [2, 3]
zip([1, 2], ['a', 'b']) // [[1,'a'], [2,'b']]import { formatBytes, formatNumber } from '@pwshub/bellajs'
// Format file sizes
formatBytes(1024) // '1 KiB'
formatBytes(1536) // '1.5 KiB'
formatBytes(1048576) // '1 MiB'
formatBytes(1234567890) // '1.15 GiB'
// Format numbers for display
formatNumber(123) // '123.00'
formatNumber(123.456) // '123.46'
formatNumber(99.9, 0) // '100'import { isValidUrl, isAbsoluteUrl } from '@pwshub/bellajs'
// Validate URLs
isValidUrl('https://example.com') // true
isValidUrl('http://example.com') // true
isValidUrl('ftp://example.com') // false
isValidUrl('not-a-url') // false
// Check if URL is absolute
isAbsoluteUrl('https://example.com') // true
isAbsoluteUrl('//cdn.example.com') // true
isAbsoluteUrl('/path/to/resource') // false| Platform | Version | Support |
|---|---|---|
| Node.js | 22+ | ✅ Full |
| Bun | 1.0+ | ✅ Full |
| Deno | 2.0+ | ✅ Full |
| Browsers | Modern (ESM) | ✅ Full |
# Install dependencies
npm install
# Run tests
npm test
# Run linter
npm run lint
# Auto-fix linting issues
npm run lint:fix- Qwen Code
- Google Gemini
- DeepSeek
The MIT License (MIT)