Zero-dependency, ultra-lightweight JavaScript utility libraries
A collection of tiny, focused utility packages with zero runtime dependencies. Each package is designed to do one thing well.
| Package | Description | Size |
|---|---|---|
| nano-clsx | Conditional className builder | <300b |
| nano-slug | URL-safe slug generator | <400b |
| nano-safe-storage | Fault-tolerant localStorage wrapper | <600b |
| nano-human-bytes | Human-readable byte formatting | <500b |
| tiny-debounce-throttle | Debounce/throttle with cancel/flush | <600b |
| tiny-time-ago | Relative time formatting | <500b |
| click-outside-lite | Click outside detection | <400b |
| deep-merge-lite | Deep merge with array strategies | <700b |
| deep-clean-obj | Remove null/undefined from objects | <500b |
| resilient-fetcher | Fetch with retry/timeout | <800b |
Install any package individually:
npm install nano-clsx nano-slug nano-safe-storage
# or
pnpm add deep-merge-lite resilient-fetcherConditional className builder (alternative to clsx/classnames).
import { clsx } from 'nano-clsx';
clsx('foo', 'bar'); // 'foo bar'
clsx({ active: true, hidden: false }); // 'active'
clsx(['a', { b: true }]); // 'a b'URL-safe slug generator with custom replacements.
import { slugify } from 'nano-slug';
slugify('Hello World'); // 'hello-world'
slugify('Café Résumé'); // 'cafe-resume'
slugify('Rock & Roll'); // 'rock-and-roll'
slugify('Long Title', { maxLength: 10 }); // 'long-title'Fault-tolerant localStorage with TTL and namespacing.
import { createStorage } from 'nano-safe-storage';
const storage = createStorage({ prefix: 'app_', ttl: 3600 });
storage.set('user', { name: 'John' });
storage.get('user'); // { name: 'John' }
storage.set('token', 'abc', { ttl: 900 }); // 15 min TTLHuman-readable byte formatting.
import { formatBytes, parseBytes } from 'nano-human-bytes';
formatBytes(1536); // '1.5 KB'
formatBytes(1536, { bits: true }); // '12.29 Kb'
parseBytes('1.5 KB'); // 1536Debounce/throttle with cancel, flush, and RAF support.
import { debounce, throttle } from 'tiny-debounce-throttle';
const search = debounce(fetchResults, 300, { maxWait: 1000 });
search('query');
search.cancel();
search.flush();
const animate = throttle.raf(updatePosition);Relative time formatting with locale support.
import { timeAgo, createTimeAgo } from 'tiny-time-ago';
timeAgo(Date.now() - 60000); // '1 minute ago'
timeAgo(new Date('2024-12-23')); // '1 day ago'
const ago = createTimeAgo('es');
ago(new Date('2024-12-23')); // 'hace 1 día'Detect clicks outside elements (modals, dropdowns).
import { onClickOutside } from 'click-outside-lite';
const cleanup = onClickOutside(modalRef, handleClose, {
once: true,
ignore: ['.tooltip']
});Deep merge with array strategies and cloneDeep.
import { merge, cloneDeep } from 'deep-merge-lite';
merge({}, objA, objB);
merge({}, objA, objB, { arrayMerge: 'concat' });
const copy = cloneDeep(original);Remove null, undefined, and empty values from objects.
import { clean } from 'deep-clean-obj';
clean({ a: 1, b: null, c: '' }); // { a: 1 }
clean(obj, { preserveEmptyArrays: true });
clean(obj, { exclude: ['meta.*'] });Fetch wrapper with retry, timeout, and backoff.
import { resilientFetch } from 'resilient-fetcher';
const response = await resilientFetch('https://api.example.com', {
retries: 3,
timeout: 5000,
backoff: 'exponential'
});# Install dependencies
pnpm install
# Run tests
pnpm test
# Build all packages
pnpm build
# Run benchmarks
pnpm benchMIT © BaryoDev