my website at ewancroft.uk
README.md

@ewanc26/utils#

Canonical source: This package is now maintained in the @ewanc26/pkgs monorepo under packages/utils. This copy exists for historical context — please open issues and PRs there.

Shared utility functions extracted from ewancroft.uk. Zero runtime dependencies.

Modules#

  • Date & LocaleformatRelativeTime, formatLocalizedDate, getUserLocale
  • Number FormattingformatCompactNumber, formatNumber
  • URL UtilitiesgetDomain, atUriToBlueskyUrl, getBlueskyProfileUrl, isExternalUrl
  • Validators & TextisValidTid, isValidDid, truncateText, escapeHtml, getInitials, debounce, throttle
  • RSS GenerationgenerateRSSFeed, generateRSSItem, createRSSResponse, escapeXml, normalizeCharacters, formatRSSDate

Installation#

pnpm add @ewanc26/utils

Quick Examples#

import { formatRelativeTime, formatCompactNumber, getDomain, isValidDid, generateRSSFeed } from '@ewanc26/utils';

formatRelativeTime('2025-11-13T00:00:00Z'); // '3d ago'
formatCompactNumber(1500);                   // '1.5K'
getDomain('https://www.example.com/path');   // 'example.com'
isValidDid('did:plc:abc123');                // true

const xml = generateRSSFeed({ title: 'My Blog', link: 'https://mysite.com', description: '…' }, items);

All functions are SSR-safe and fall back to en-GB when navigator / window are unavailable.

Build#

Development happens in the @ewanc26/pkgs monorepo. Local commands (from packages/utils):

pnpm build   # tsc
pnpm dev     # tsc --watch
pnpm check   # tsc --noEmit

Licence#

AGPL-3.0-only — see the pkgs monorepo licence.