Discover which npm packages work in Cloudflare Workers. 395+ packages tested and working.
Showing runtime packages only. Build tools, CLI tools, and test frameworks are hidden by default.
Enable "Show build tools & incompatible" to see all 992 tested packages.
Showing 231 packages
Create executable GraphQL schemas. Merges type definitions and resolvers.
import { makeExecutableSchema } from '@graphql-tools/schema';
// Usage:
const typeDefs = 'type Query { hello: String }';
const resolvers = { Query: { hello: () => 'world' } };
const schema = makeExecutableSchema({ typeDefs, resolvers });
return { success: schema.getQueryType()?.name === 'Query', result: 'Schema created' };
JavaScript parser producing AST. Supports ES2022+ including private fields, optional chaining, nullish coalescing, and ESM syntax. Useful for code analysis, transformation, or building dev tools in Workers.
import * as acorn from 'acorn';
export default {
async fetch(request) {
// Parse ES modules with modern syntax
const code = `
import { foo } from './bar';
const obj = { a: 1, ...other };
const fn = async () => await fetch('/api');
class Foo { static bar = 42; }
`;
const ast = acorn.parse(code, {
ecmaVersion: 2022,
sourceType: 'module'
});
return Response.json({
type: ast.type,
statements: ast.body.length,
firstNode: ast.body[0].type
});
}
};
Async utilities for control flow
import async from 'async';
// Usage:
const results = await async.parallel([
async () => 1,
async () => 2,
async () => 3,
]);
return { success: results[0] === 1 && results[1] === 2 && results[2] === 3, result: results };
HTTP Basic Authentication parser - parses Authorization header to extract credentials
import auth from 'basic-auth';
// Usage:
// Simulate an HTTP request with Basic Auth header
const credentials = btoa('user:pass'); // Base64 encode 'user:pass'
const mockRequest = {
headers: {
authorization: `Basic ${credentials}`
}
};
const parsed = auth(mockRequest);
return { success: parsed?.name === 'user' && parsed?.pass === 'pass', result: parsed };
Buffer List - collect and manage multiple buffers as one contiguous buffer.
import bl from 'bl';
// Usage:
const list = new bl();
list.append(Buffer.from('Hello '));
list.append(Buffer.from('World'));
const result = list.toString();
return { success: result === 'Hello World', result: { text: result, length: list.length } };
Feature-rich Promise library with utilities like map (with concurrency), filter, reduce, props, some, any, delay, and more. All features work on Workers.
import Promise from 'bluebird';
export default {
async fetch(request) {
// Promise.map with concurrency control
const items = [1, 2, 3, 4, 5];
const mapped = await Promise.map(items, async (n) => {
await Promise.delay(10);
return n * 2;
}, { concurrency: 2 });
// Promise.props - resolve object of promises
const props = await Promise.props({
a: Promise.resolve(1),
b: Promise.delay(10).then(() => 2)
});
// Promise.filter, Promise.reduce
const filtered = await Promise.filter(items, n => n % 2 === 0);
const sum = await Promise.reduce(items, (acc, n) => acc + n, 0);
return Response.json({ mapped, props, filtered, sum });
}
};
Express middleware for parsing request bodies. Use with httpServerHandler from cloudflare:node for Express compatibility, or use native Request.json()/Request.text() for simpler cases.
import bodyParser from 'body-parser';
// Usage: Express middleware for parsing request bodies
// Use with httpServerHandler from cloudflare:node for Express apps
const jsonParser = bodyParser.json();
const urlencodedParser = bodyParser.urlencoded({ extended: true });
return { success: true, result: 'Middleware created' };
HTTP-friendly error objects with proper status codes, messages, and error payloads. Supports notFound(), unauthorized(), badRequest(), forbidden(), conflict(), internal(), teapot(), and more. Use Boom.isBoom() to detect Boom errors.
import Boom from 'boom';
export default {
async fetch(request) {
const url = new URL(request.url);
try {
if (url.pathname === '/protected') {
throw Boom.unauthorized('Authentication required');
}
if (url.pathname === '/missing') {
throw Boom.notFound('Resource not found', { id: 123 });
}
return Response.json({ message: 'OK' });
} catch (error) {
if (Boom.isBoom(error)) {
return Response.json(error.output.payload, {
status: error.output.statusCode,
headers: error.output.headers
});
}
throw error;
}
}
};
Node.js Buffer polyfill. Use built-in Workers Buffer or Uint8Array when possible.
import { Buffer } from 'buffer';
// Usage:
const buf = Buffer.from('hello world', 'utf-8');
const hex = buf.toString('hex');
const base64 = buf.toString('base64');
return { success: hex.length === 22 && base64.length === 16, result: { hex, base64 } };
Convert byte values to/from human-readable strings (e.g., "1MB" β 1048576).
import bytes from 'bytes';
// Usage:
const parsed = bytes('1MB');
const formatted = bytes(1048576);
return { success: parsed === 1048576 && formatted === '1MB', result: { parsed, formatted } };
Random data generator for testing, mocking APIs, and development. Generates names, emails, addresses, GUIDs, IPs, colors, sentences, and more. Supports seeding for reproducible results.
import Chance from 'chance';
export default {
async fetch(request) {
const chance = new Chance();
// Seed for reproducible results
const seeded = new Chance(12345);
return Response.json({
person: {
name: chance.name(),
email: chance.email(),
phone: chance.phone(),
address: chance.address(),
city: chance.city()
},
misc: {
guid: chance.guid(),
ip: chance.ip(),
url: chance.url(),
color: chance.color({ format: 'hex' })
},
// Seeded gives same result every time
seededName: seeded.name()
});
}
};
Color manipulation library for parsing (hex, rgb, hsl, lab), converting between formats, generating scales/gradients, mixing colors, and checking WCAG contrast ratios for accessibility.
import chroma from 'chroma-js';
export default {
async fetch(request) {
// Parse and manipulate colors
const color = chroma('#3498db');
return Response.json({
original: color.hex(),
darken: color.darken().hex(),
brighten: color.brighten().hex(),
rgb: color.rgb(),
hsl: color.hsl(),
luminance: color.luminance(),
// Generate color scales
gradient: chroma.scale(['#fafa6e', '#2A4858']).colors(5),
// Color mixing
mix: chroma.mix('red', 'blue', 0.5).hex(),
// WCAG contrast check
contrast: chroma.contrast('white', '#3498db')
});
}
};
Conditionally join CSS class names together. Useful for dynamic styling.
import classNames from 'classnames';
// Usage:
const classes = classNames('btn', { active: true, disabled: false }, 'primary');
return { success: classes === 'btn active primary', result: classes };
CLI table formatting. Limited usefulness in Workers but works.
import Table from 'cli-table';
// Usage:
const table = new Table({ head: ['Name', 'Age'] });
table.push(['John', '30'], ['Jane', '25']);
const str = table.toString();
return { success: str.includes('John') && str.includes('30'), result: str.substring(0, 100) };
Deep clone objects including dates, functions, and nested structures. Works on Workers. Alternative: structuredClone() for simpler cases.
π‘ Alternative: built-in: structuredClone
import clone from 'clone';
const original = { a: 1, b: { c: 2 } };
const cloned = clone(original);
cloned.b.c = 999;
// original.b.c is still 2
return { success: original.b.c === 2, cloned };
Generator-based async control flow. Supports sequential operations, parallel arrays/objects. Modern async/await is preferred for new code, but co still works for legacy codebases.
import co from 'co';
export default {
async fetch(request) {
// Generator-based control flow
const result = await co(function* () {
// Sequential async operations
const response = yield fetch('https://httpbin.org/json');
const data = yield response.json();
// Parallel with arrays
const [a, b, c] = yield [
Promise.resolve(1),
Promise.resolve(2),
Promise.resolve(3)
];
return { title: data.slideshow.title, sum: a + b + c };
});
return Response.json(result);
}
};
Color manipulation and conversion library. Works well in Workers.
import Color from 'color';
// Usage:
const color = Color('rgb(255, 0, 0)');
const hex = color.hex();
const lightened = color.lighten(0.5).hex();
return { success: hex === '#FF0000', result: { hex, lightened } };
Express middleware for gzip/deflate compression. Works with Express via httpServerHandler.
π‘ Alternative: CompressionStream (built-in Web API) or Hono's compress() middleware
import { httpServerHandler } from 'cloudflare:node';
import express from 'express';
import compression from 'compression';
const app = express();
app.use(compression());
app.get('/test', (req, res) => {
res.json({ data: 'x'.repeat(1000) });
});
app.listen(3000);
export default httpServerHandler({ port: 3000 });
import concat from 'concat-stream';
// Usage:
const { Writable } = await import('stream');
const stream = concat((data) => {
return { success: data.toString() === 'hello', result: data.toString() };
});
stream.write('hello');
stream.end();
return { success: true, result: 'stream created' };
Flash message middleware for Express. Works with express-session via httpServerHandler.
Error: Package connect-flash needs manual test configuration - do not use generic Object.keys() test
import { httpServerHandler } from 'cloudflare:node';
import express from 'express';
import session from 'express-session';
import flash from 'connect-flash';
const app = express();
app.use(session({ secret: 'secret', resave: false, saveUninitialized: true }));
app.use(flash());
app.get('/set', (req, res) => { req.flash('info', 'Hello!'); res.json({ set: true }); });
app.get('/get', (req, res) => res.json({ messages: req.flash('info') }));
app.listen(3000);
export default httpServerHandler({ port: 3000 });
Converts source maps between different formats (JSON, base64, inline comments).
import { fromObject, fromJSON } from 'convert-source-map';
// Usage:
const map = { version: 3, sources: ['foo.js'], mappings: 'AAAA' };
const converter = fromObject(map);
const json = converter.toJSON();
const parsed = fromJSON(json);
return { success: parsed.toObject().version === 3, result: parsed.toObject() };
Node.js cron job scheduler for running scheduled tasks (e.g., CronJob('0 0 * * *', callback)). Requires child_process for spawning tasks. Workers has built-in Scheduled Events (Cron Triggers) for scheduled tasks - use scheduled handler: export default { scheduled(event, env, ctx) { ... } }
π‘ Alternative: Cloudflare Workers Scheduled Events (Cron Triggers) - built-in
Error: No such module "node:child_process".
D3 array manipulation library with statistical functions (min, max, mean, median), array transformations (group, bin, bisect), and data operations.
import { min, max, mean, median, extent, group } from 'd3-array';
// Usage:
const data = [1, 5, 2, 8, 3];
const minVal = min(data);
const maxVal = max(data);
const meanVal = mean(data);
const medianVal = median(data);
const extentVal = extent(data);
const grouped = group([{key: 'a', val: 1}, {key: 'b', val: 2}, {key: 'a', val: 3}], d => d.key);
return { success: minVal === 1 && maxVal === 8 && meanVal === 3.8 && medianVal === 3, result: { minVal, maxVal, meanVal, medianVal, extentVal, grouped: grouped.size } };
D3 scales for mapping data values to visual ranges. Includes linear, logarithmic, power, time, and categorical scales for data visualization.
import { scaleLinear, scaleLog, scalePow, scaleTime } from 'd3-scale';
// Usage:
const linear = scaleLinear().domain([0, 10]).range([0, 100]);
const log = scaleLog().domain([1, 10]).range([0, 100]);
const pow = scalePow().exponent(2).domain([0, 10]).range([0, 100]);
const time = scaleTime().domain([new Date(2020, 0, 1), new Date(2021, 0, 1)]).range([0, 100]);
const linearVal = linear(5);
const logVal = log(5);
const powVal = pow(5);
const timeVal = time(new Date(2020, 6, 1));
return { success: linearVal === 50 && logVal > 0 && powVal === 25 && timeVal > 0, result: { linearVal, logVal, powVal, timeVal } };
D3 shape generators for SVG path data. Provides line(), area(), pie(), arc(), and more for creating data-driven shapes and charts.
import { line, area, pie, arc } from 'd3-shape';
// Usage:
const lineGenerator = line().x((d, i) => i * 10).y(d => d);
const linePath = lineGenerator([10, 20, 30, 20, 10]);
const areaGenerator = area().x((d, i) => i * 10).y0(0).y1(d => d);
const areaPath = areaGenerator([10, 20, 30, 20, 10]);
const pieGenerator = pie();
const pieData = pieGenerator([1, 2, 3]);
const arcGenerator = arc().innerRadius(0).outerRadius(100);
const arcPath = arcGenerator(pieData[0]);
return { success: typeof linePath === 'string' && typeof areaPath === 'string' && pieData.length === 3 && typeof arcPath === 'string', result: { linePath: linePath.substring(0, 20), pieAngles: pieData.map(d => [d.startAngle, d.endAngle]) } };
Lightweight debugging utility with namespace-based logging. Works in Workers - debug output appears in console/logs.
import debug from 'debug';
// Create namespaced loggers
const logApp = debug('app:main');
const logHttp = debug('app:http');
// Enable namespaces
debug.enable('app:*');
export default {
async fetch(request) {
const url = new URL(request.url);
logApp('Request: %s %s', request.method, url.pathname);
logHttp('Headers: %O', Object.fromEntries(request.headers));
return Response.json({ debugEnabled: debug.enabled('app:main') });
}
};
Arbitrary-precision decimal arithmetic
import Decimal from 'decimal.js';
// Usage:
const x = new Decimal(0.1);
const y = new Decimal(0.2);
const result = x.plus(y).toString();
return { success: result === '0.3', result };
Calculate deep differences between objects. Captures changes (added, deleted, edited, array changes) and can apply/revert changes.
import { diff, applyChange } from 'deep-diff';
// Usage:
const lhs = { name: 'Alice', age: 30, city: 'NYC' };
const rhs = { name: 'Alice', age: 31, city: 'LA' };
const differences = diff(lhs, rhs);
const hasChanges = differences && differences.length === 2;
const ageChanged = differences.some(d => d.path[0] === 'age' && d.lhs === 30 && d.rhs === 31);
const cityChanged = differences.some(d => d.path[0] === 'city' && d.lhs === 'NYC' && d.rhs === 'LA');
return { success: hasChanges && ageChanged && cityChanged, result: differences };
Deep equality comparison for objects
import deepEqual from 'deep-equal';
// Usage:
const result1 = deepEqual({ a: 1, b: { c: 2 } }, { a: 1, b: { c: 2 } });
const result2 = deepEqual({ a: 1 }, { a: 2 });
return { success: result1 && !result2, result: { result1, result2 } };
Recursively extend objects
import deepExtend from 'deep-extend';
// Usage:
const result = deepExtend({ a: 1, b: { c: 2 } }, { b: { d: 3 } });
return { success: result.a === 1 && result.b.c === 2 && result.b.d === 3, result };
Deep merge of objects
import deepmerge from 'deepmerge';
// Usage:
const result = deepmerge({ a: 1, b: { c: 2 } }, { b: { d: 3 } });
return { success: result.a === 1 && result.b.c === 2 && result.b.d === 3, result };
Deprecation warning utility for Node.js modules. Works in Workers for issuing console warnings about deprecated API usage.
import depd from 'depd';
const deprecate = depd('my-module');
function oldFunction() {
deprecate('oldFunction() is deprecated');
return 'result';
}
export default {
async fetch(request) {
const result = oldFunction();
return Response.json({ result, message: 'Check console for deprecation warning' });
}
};
Destroy a stream safely, handling different stream types.
import destroy from 'destroy';
import { Readable } from 'node:stream';
// Usage:
const stream = new Readable({ read() {} });
destroy(stream);
return { success: stream.destroyed, result: { destroyed: stream.destroyed } };
Serialize JavaScript values (including Date, RegExp, Map, Set)
import { stringify, parse } from 'devalue';
// Usage:
const obj = { a: 1, b: new Date('2026-01-10'), c: /test/ };
const str = stringify(obj);
const result = parse(str);
return { success: result.a === 1 && result.b instanceof Date, result };
Text diff implementation (characters, words, lines, JSON)
import * as diff from 'diff';
// Usage:
const result = diff.diffChars('hello', 'hallo');
return { success: result.length > 0 && result.some(p => p.added || p.removed), result };
Money/currency handling with precision
import Dinero from 'dinero.js';
// Usage:
const price = Dinero({ amount: 500, currency: 'USD' });
const total = price.add(Dinero({ amount: 200, currency: 'USD' }));
return { success: total.getAmount() === 700, result: total.toFormat('$0,0.00') };
discord.js is a Discord bot library that requires persistent WebSocket connections to Discord's Gateway API for real-time events (listening to messages, presence updates, voice state changes, etc.). Designed for long-running Node.js bot applications that maintain always-on Gateway connections. Workers is a stateless serverless environment without support for persistent WebSocket connections or long-running processes. The main discord.js package uses @discordjs/ws for Gateway WebSocket management which is incompatible with Workers' request/response lifecycle. Note: The discord.js website shows 'Powered by Cloudflare Workers' because their documentation site is hosted on Workers, not because the bot library works on Workers. For Discord interactions on Workers, use @discordjs/rest (REST API only) or @discordjs/core (thin wrapper for REST + webhook-based interactions). These packages support slash commands, webhooks, and REST API calls without requiring Gateway connections.
π‘ Alternative: @discordjs/rest or @discordjs/core for REST-only Discord interactions (slash commands, webhooks)
ES6 Promise polyfill (mostly unnecessary in Workers)
import { Promise } from 'es6-promise';
// Usage:
const p = new Promise((resolve) => resolve('ok'));
const result = await p;
return { success: result === 'ok', result };
Escape special regex characters
import escapeStringRegexp from 'escape-string-regexp';
// Usage:
const result = escapeStringRegexp('foo.bar*baz');
return { success: result === 'foo\\.bar\\*baz', result };
JavaScript parser (ECMAScript parser)
import { parseScript } from 'esprima';
// Usage:
const ast = parseScript('const x = 42;');
return { success: ast.type === 'Program', result: ast.type };
Generate HTTP ETags for caching. Create strong/weak ETags from content.
import etag from 'etag';
// Usage:
const body = 'Hello World';
const tag = etag(body);
return { success: tag.startsWith('"') || tag.startsWith('W/'), result: { etag: tag } };
Stream utilities and helpers
import es from 'event-stream';
// Usage:
const results = [];
const stream = es.through(function(data) { results.push(data); this.emit('data', data); });
stream.write('test');
return { success: results[0] === 'test', result: results };
Enhanced EventEmitter with wildcards and namespaces
import { EventEmitter2 } from 'eventemitter2';
// Usage:
const emitter = new EventEmitter2();
let called = false;
emitter.on('test', () => { called = true; });
emitter.emit('test');
return { success: called, result: { called } };
Fast EventEmitter implementation
import EventEmitter from 'eventemitter3';
// Usage:
const emitter = new EventEmitter();
let value = '';
emitter.on('event', (msg) => { value = msg; });
emitter.emit('event', 'hello');
return { success: value === 'hello', result: { value } };
Node.js EventEmitter - available in Workers
import { EventEmitter } from 'events';
// Usage:
const ee = new EventEmitter();
let count = 0;
ee.on('test', () => { count++; });
ee.emit('test');
return { success: count === 1, result: { count } };
Object extension utility
import extend from 'extend';
// Usage:
const result = extend({ a: 1 }, { b: 2 }, { c: 3 });
return { success: result.a === 1 && result.b === 2 && result.c === 3, result };
Shallow object extension utility. Like Object.assign() but with more flexible API for merging multiple objects.
import extend from 'extend-shallow';
// Usage:
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const obj3 = { c: 5, d: 6 };
const result = extend(obj1, obj2, obj3);
const success = result.a === 1 && result.b === 3 && result.c === 5 && result.d === 6;
return { success, result };
Fast deep equality comparison for objects and arrays
import equal from 'fast-deep-equal';
// Usage:
const a = { x: 1, y: { z: 2 } };
const b = { x: 1, y: { z: 2 } };
const c = { x: 1, y: { z: 3 } };
const result1 = equal(a, b);
const result2 = equal(a, c);
return { success: result1 === true && result2 === false, result: { equal: result1, notEqual: result2 } };
ASCII art text generator. Must preload fonts using importable-fonts - async font loading does not work in Workers.
import figlet from 'figlet';
import standard from 'figlet/importable-fonts/Standard.js';
// Usage: Must preload fonts
figlet.parseFont('Standard', standard);
const ascii = figlet.textSync('Hi!', { font: 'Standard' });
return { success: ascii.length > 0, result: { ascii } };
Detects file types from file signatures (magic bytes). Works with Uint8Array buffers. Useful for validating uploads, detecting MIME types.
import { fileTypeFromBuffer } from 'file-type';
// Usage:
// PNG magic bytes: 89 50 4E 47 0D 0A 1A 0A (with some extra bytes for the tokenizer)
const pngBytes = new Uint8Array([
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
0x08, 0x06, 0x00, 0x00, 0x00, 0x1F, 0x15, 0xC4
]);
const result = await fileTypeFromBuffer(pngBytes);
return { success: result?.ext === 'png' && result?.mime === 'image/png', result };
Human-readable file sizes. Use named import: import { filesize } from filesize
import { filesize } from 'filesize';
filesize(1024); // '1.02 kB'
Flatten/unflatten nested objects. Use named imports: import { flatten, unflatten } from flat
import { flatten, unflatten } from 'flat';
const flat = flatten({ a: { b: 1 } });
// { 'a.b': 1 }
Node.js fs module is available but operates on a virtual in-memory filesystem. No persistent storage - files are lost between requests. Use R2, KV, or D1 for persistent storage.
import * as fs from 'node:fs';
// Usage:
const result = { existsSync: typeof fs.existsSync === 'function', readFileSync: typeof fs.readFileSync === 'function' };
return { success: result.existsSync && result.readFileSync, result };
Polyfill for accessing the global object across environments. Returns globalThis in Workers. Useful for cross-environment compatibility.
import global from 'global';
// Usage:
// global is a polyfill for accessing global variables across environments
// It returns the global object (globalThis in Workers)
const hasGlobal = typeof global === 'object';
const hasGlobalThis = global === globalThis;
return { success: hasGlobal && hasGlobalThis, result: { type: typeof global, isGlobalThis: hasGlobalThis } };
GraphQL schema building utilities - makeExecutableSchema, mergeSchemas, schema stitching
import { makeExecutableSchema } from 'graphql-tools';
// Usage:
// Create a simple GraphQL schema
const typeDefs = `
type Query {
hello: String
}
`;
const resolvers = {
Query: {
hello: () => 'Hello from Workers!'
}
};
const schema = makeExecutableSchema({ typeDefs, resolvers });
return {
success: schema != null && schema.getQueryType()?.name === 'Query',
result: { hasSchema: true, queryType: schema.getQueryType()?.name }
};
import hashSum from 'hash-sum';
// Usage:
const hash = hashSum({ foo: 'bar', nested: { value: 123 } });
return { success: typeof hash === 'string' && hash.length > 0, result: hash };
HTML entity encoder/decoder. Encode/decode HTML entities in strings.
import he from 'he';
// Usage:
const encoded = he.encode('<script>alert("xss")</script>');
const decoded = he.decode('<div>Hello</div>');
return { success: decoded === '<div>Hello</div>', result: { encoded, decoded } };
import H from 'highland';
// Usage:
const result: number[] = [];
H([1, 2, 3, 4])
.map((x: number) => x * 2)
.each((x: number) => result.push(x));
return { success: result.join(',') === '2,4,6,8', result };
Syntax highlighting library
import hljs from 'highlight.js';
// Usage:
const result = hljs.highlight('const x = 5;', { language: 'javascript' });
return { success: result.value.includes('const'), result: { highlighted: result.value.substring(0, 50) } };
History/routing library for SPAs
import { createMemoryHistory } from 'history';
// Usage:
const history = createMemoryHistory();
history.push('/test');
return { success: history.location.pathname === '/test', result: { pathname: history.location.pathname } };
Deprecated - use @hapi/hoek instead
π‘ Alternative: @hapi/hoek
Error: Failed to load url @hapi/hoek (resolved id: @hapi/hoek) in /Users/steve/works-on-workers/packages/test-harness/sandbox/hoek/src/index.ts. Does the file exist?
import Hogan from 'hogan.js';
// Usage:
const template = Hogan.compile('Hello {{name}}!');
const result = template.render({ name: 'World' });
return { success: result === 'Hello World!', result };
Copies non-React static properties
import hoistStatics from 'hoist-non-react-statics';
// Usage:
function Target() {}
function Source() {}
Source.foo = 'bar';
hoistStatics(Target, Source);
return { success: (Target as any).foo === 'bar', result: { foo: (Target as any).foo } };
import { encode, decode } from 'html-entities';
// Usage:
const encoded = encode('<div>Hello & goodbye</div>');
const decoded = decode('<div>Hello & goodbye</div>');
return { success: encoded === '<div>Hello & goodbye</div>' && decoded === '<div>Hello & goodbye</div>', result: { encoded, decoded } };
Create HTTP errors with proper status codes. Useful for API error responses.
import createError from 'http-errors';
// Usage:
const err = createError(404, 'User not found');
return { success: err.status === 404, result: { status: err.status, message: err.message } };
import { StatusCodes, getReasonPhrase } from 'http-status-codes';
// Usage:
const ok = StatusCodes.OK;
const notFound = StatusCodes.NOT_FOUND;
const phrase = getReasonPhrase(200);
return { success: ok === 200 && notFound === 404 && phrase === 'OK', result: { ok, notFound, phrase } };
Internationalization framework with interpolation, pluralization, language detection, fallbacks. Works on Workers for multi-language APIs.
import i18next from 'i18next';
export default {
async fetch(request) {
await i18next.init({
lng: 'en',
fallbackLng: 'en',
resources: {
en: { translation: { greeting: 'Hello, {{name}}!', welcome: 'Welcome' } },
es: { translation: { greeting: 'Β‘Hola, {{name}}!', welcome: 'Bienvenido' } }
}
});
const en = i18next.t('greeting', { name: 'World' });
await i18next.changeLanguage('es');
const es = i18next.t('greeting', { name: 'Mundo' });
return Response.json({ en, es });
}
};
import iconv from 'iconv-lite';
// Usage:
const encoded = iconv.encode('Hello', 'utf8');
const decoded = iconv.decode(encoded, 'utf8');
return { success: decoded === 'Hello', result: decoded };
Get image dimensions from buffer or file
import sizeOf from 'image-size';
// Usage:
// Create a simple 1x1 PNG (base64 encoded)
const pngData = Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==', 'base64');
const dimensions = sizeOf(pngData);
return { success: dimensions.width === 1 && dimensions.height === 1 && dimensions.type === 'png', result: dimensions };
Immutable state updates with mutable syntax. Supports nested objects, arrays, Maps, Sets. Great for state management in Workers.
import { produce, enableMapSet } from 'immer';
enableMapSet();
export default {
async fetch(request) {
const state = {
users: [{ id: 1, name: 'Alice' }],
settings: { theme: 'light' }
};
const nextState = produce(state, draft => {
draft.users.push({ id: 2, name: 'Bob' });
draft.settings.theme = 'dark';
});
// Curried producer
const addUser = produce((draft, user) => { draft.users.push(user); });
const withNewUser = addUser(nextState, { id: 3, name: 'Charlie' });
return Response.json({ original: state, updated: withNewUser });
}
};
Immutable state updates for React and other frameworks
import update from 'immutability-helper';
// Usage:
const state = { name: 'Alice', age: 30 };
const newState = update(state, { age: { $set: 31 } });
return { success: newState.age === 31 && state.age === 30, result: newState };
import { Map } from 'immutable';
// Usage:
const map = Map({ a: 1, b: 2 });
const map2 = map.set('c', 3);
return { success: map2.get('c') === 3 && map2.size === 3, result: map2.toObject() };
import inflection from 'inflection';
// Usage:
const plural = inflection.pluralize('person');
const singular = inflection.singularize('people');
const camel = inflection.camelize('hello_world');
return { success: plural === 'people' && singular === 'person' && camel === 'HelloWorld', result: { plural, singular, camel } };
import inherits from 'inherits';
// Usage:
function Parent() { this.name = 'parent'; }
Parent.prototype.getName = function() { return this.name; };
function Child() { Parent.call(this); this.name = 'child'; }
inherits(Child, Parent);
const child = new Child();
return { success: child.getName() === 'child', result: child.getName() };
import ini from 'ini';
// Usage:
const obj = { section: { key: 'value', number: 42 } };
const str = ini.stringify(obj);
const parsed = ini.parse(str);
return { success: parsed.section.key === 'value', result: parsed };
import invariant from 'invariant';
// Usage:
let error;
try {
invariant(false, 'This is an error');
} catch (e) {
error = e.message;
}
return { success: error === 'This is an error', result: error };
IoC container with dependency injection
import { Container, injectable, inject } from 'inversify';
// Usage:
@injectable()
class Warrior {
constructor() {}
fight() { return 'fight!'; }
}
const container = new Container();
container.bind(Warrior).toSelf();
const warrior = container.get(Warrior);
return { success: warrior.fight() === 'fight!', result: warrior.fight() };
IP address utilities - validation, parsing, subnet checking, IPv4/IPv6 conversion.
import ip from 'ip';
// Usage:
const isPrivate = ip.isPrivate('192.168.1.1');
const isPublic = ip.isPublic('8.8.8.8');
return { success: isPrivate && isPublic, result: { isPrivate, isPublic } };
import isNumber from 'is-number';
// Usage:
const results = [isNumber(123), isNumber('123'), isNumber('abc'), isNumber(null)];
return { success: results[0] && results[1] && !results[2] && !results[3], result: results };
import isPromise from 'is-promise';
// Usage:
const a = isPromise(Promise.resolve(123));
const b = isPromise({ then: () => {} });
const c = isPromise(123);
return { success: a === true && b === true && c === false, result: { a, b, c } };
import isObject from 'isobject';
// Usage:
const results = [isObject({}), isObject([]), isObject(null), isObject('test')];
return { success: results[0] && !results[1] && !results[2] && !results[3], result: results };
JavaScript image manipulation. Pure JS image processing - resize, crop, rotate, filters, etc.
import { Jimp } from 'jimp';
// Usage:
const image = new Jimp({ width: 100, height: 100, color: 0xff0000ff });
return { success: true, result: { width: image.width, height: image.height } };
import { Base64 } from 'js-base64';
// Usage:
const encoded = Base64.encode('hello');
const decoded = Base64.decode(encoded);
return { success: decoded === 'hello', result: { encoded, decoded } };
import beautify from 'js-beautify';
// Usage:
const result = beautify('var x=1;', { indent_size: 2 });
return { success: result.includes('var x'), result };
Browser cookie library - requires document.cookie. In Workers, parse Cookie header manually or use a server-side cookie library.
import Cookies from 'js-cookie';
// Usage: js-cookie needs document.cookie (browser only)
// In Workers, parse cookies manually from request headers
const cookieHeader = request.headers.get('Cookie') || '';
return { success: true, result: { note: 'Use request.headers.get("Cookie") in Workers' } };
import stringify from 'json-stable-stringify';
// Usage:
const result = stringify({ b: 2, a: 1 });
return { success: result === '{"a":1,"b":2}', result };
import stringify from 'json-stringify-safe';
// Usage:
const obj: any = { a: 1 };
obj.circular = obj;
const result = stringify(obj);
return { success: result.includes('"a":1'), result };
import JSON5 from 'json5';
// Usage:
const obj = JSON5.parse('{ key: "value", /* comment */ }');
return { success: obj.key === 'value', result: obj };
Works with Workers node:fs support. Can read/write JSON files to /tmp (ephemeral, per-request) or read from /bundle (bundled files, read-only). Not for persistent storage - use KV, R2, or D1 for that.
Error: no such file or directory
import jsonfile from 'jsonfile';
import { mkdirSync } from 'node:fs';
export default {
async fetch(request) {
// Write JSON to /tmp (ephemeral, per-request)
mkdirSync('/tmp/data', { recursive: true });
const data = { name: 'test', timestamp: Date.now() };
jsonfile.writeFileSync('/tmp/data/config.json', data, { spaces: 2 });
// Read it back
const result = jsonfile.readFileSync('/tmp/data/config.json');
return Response.json({ written: data, readBack: result });
}
};
import { Validator } from 'jsonschema';
// Usage:
const v = new Validator();
const result = v.validate({ name: 'test' }, { type: 'object', properties: { name: { type: 'string' } } });
return { success: result.valid, result: result.valid };
Streaming JSON parser
import JSONStream from 'JSONStream';
// Usage:
const stream = JSONStream.parse('*');
return { success: stream !== undefined && typeof stream.pipe === 'function', result: 'Stream created' };
import { jwtDecode } from 'jwt-decode';
// Usage:
const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
const decoded = jwtDecode(token);
return { success: decoded.sub === '1234567890' && decoded.name === 'John Doe', result: decoded };
import kindOf from 'kind-of';
// Usage:
const result = [kindOf('test'), kindOf(123), kindOf([]), kindOf({})];
return { success: result.join(',') === 'string,number,array,object', result };
Liquid template engine (Shopify templating). Use liquidjs package: import { Liquid } from "liquidjs"
import { Liquid } from 'liquidjs';
// Usage:
const engine = new Liquid();
const result = await engine.parseAndRender('Hello {{ name }}!', { name: 'World' });
return { success: result === 'Hello World!', result };
import _ from 'lodash';
// Usage:
const result = _.chunk(['a', 'b', 'c', 'd'], 2);
return { success: true, result };
import { chunk } from 'lodash-es';
// Usage:
const result = chunk(['a', 'b', 'c', 'd'], 2);
return { success: true, result };
import assign from 'lodash.assign';
// Usage:
const result = assign({}, { a: 1 }, { b: 2 });
return { success: result.a === 1 && result.b === 2, result };
import camelCase from 'lodash.camelcase';
// Usage:
const result = camelCase('foo-bar');
return { success: result === 'fooBar', result };
import cloneDeep from 'lodash.clonedeep';
// Usage:
const obj = { a: { b: 1 } };
const clone = cloneDeep(obj);
clone.a.b = 2;
return { success: obj.a.b === 1 && clone.a.b === 2, result: { original: obj, clone } };
Debounce function from lodash. Works in Workers for rate-limiting function calls.
import debounce from 'lodash.debounce';
// Usage:
let count = 0;
const fn = debounce(() => { count++; }, 50);
fn(); fn(); fn();
await new Promise(r => setTimeout(r, 100));
return { success: count === 1, result: { count } };
import defaults from 'lodash.defaults';
// Usage:
const result = defaults({ a: 1 }, { a: 2, b: 3 });
return { success: result.a === 1 && result.b === 3, result };
import flatten from 'lodash.flatten';
// Usage:
const result = flatten([[1, 2], [3, 4]]);
return { success: result.join(',') === '1,2,3,4', result };
import forEach from 'lodash.foreach';
// Usage:
const result: number[] = [];
forEach([1, 2, 3], (n) => result.push(n * 2));
return { success: result.join(',') === '2,4,6', result };
import get from 'lodash.get';
// Usage:
const obj = { a: { b: { c: 123 } } };
const result = get(obj, 'a.b.c');
const missing = get(obj, 'x.y.z', 'default');
return { success: result === 123 && missing === 'default', result: { result, missing } };
import isEmpty from 'lodash.isempty';
// Usage:
const result = [isEmpty({}), isEmpty([]), isEmpty(''), isEmpty({ a: 1 })];
return { success: result[0] && result[1] && result[2] && !result[3], result };
import isEqual from 'lodash.isequal';
// Usage:
const result1 = isEqual({ a: 1 }, { a: 1 });
const result2 = isEqual({ a: 1 }, { a: 2 });
return { success: result1 && !result2, result: { result1, result2 } };
import isFunction from 'lodash.isfunction';
// Usage:
const result = [isFunction(() => {}), isFunction({}), isFunction(null)];
return { success: result[0] && !result[1] && !result[2], result };
import isPlainObject from 'lodash.isplainobject';
// Usage:
const result = [isPlainObject({}), isPlainObject([]), isPlainObject(null)];
return { success: result[0] && !result[1] && !result[2], result };
import isString from 'lodash.isstring';
// Usage:
const result = [isString('hello'), isString(123), isString(null)];
return { success: result[0] && !result[1] && !result[2], result };
import map from 'lodash.map';
// Usage:
const result = map([1, 2, 3], n => n * 2);
return { success: result.join(',') === '2,4,6', result };
import merge from 'lodash.merge';
// Usage:
const result = merge({ a: 1, b: { c: 2 } }, { b: { d: 3 } });
return { success: result.a === 1 && result.b.c === 2 && result.b.d === 3, result };
import omit from 'lodash.omit';
// Usage:
const result = omit({ a: 1, b: 2, c: 3 }, ['a', 'c']);
return { success: result.b === 2 && !result.a, result };
import pick from 'lodash.pick';
// Usage:
const result = pick({ a: 1, b: 2, c: 3 }, ['a', 'c']);
return { success: result.a === 1 && result.c === 3 && !result.b, result };
import set from 'lodash.set';
// Usage:
const obj = {};
set(obj, 'a.b.c', 123);
return { success: obj.a?.b?.c === 123, result: obj };
import throttle from 'lodash.throttle';
// Usage:
const fn = throttle(() => 'throttled', 100);
const result = fn();
return { success: result === 'throttled', result };
import uniq from 'lodash.uniq';
// Usage:
const result = uniq([1, 2, 2, 3, 1, 4]);
return { success: result.join(',') === '1,2,3,4', result };
import logSymbols from 'log-symbols';
// Usage:
const result = {
success: typeof logSymbols.success === 'string',
error: typeof logSymbols.error === 'string',
warning: typeof logSymbols.warning === 'string',
info: typeof logSymbols.info === 'string',
};
return { success: result.success && result.error && result.warning && result.info, result };
import log from 'loglevel';
// Usage:
log.setLevel('info');
const level = log.getLevel();
log.info('test');
return { success: typeof level === 'number', result: { level } };
import Long from 'long';
// Usage:
const val = Long.fromNumber(123456789);
const result = val.toString();
return { success: result === '123456789', result };
import { LRUCache } from 'lru-cache';
// Usage:
const cache = new LRUCache({ max: 100 });
cache.set('key', 'value');
const result = cache.get('key');
return { success: result === 'value', result };
import LZString from 'lz-string';
// Usage:
const compressed = LZString.compress('hello world');
const decompressed = LZString.decompress(compressed);
return { success: decompressed === 'hello world', result: { compressed, decompressed } };
Stream mapping utility for transforming stream data
import mapStream from 'map-stream';
// Usage:
const stream = mapStream((data, callback) => {
callback(null, data * 2);
});
return { success: typeof stream === 'object', result: 'stream-utility' };
Markdown to HTML converter
import { markdown } from 'markdown';
// Usage:
const result = markdown.toHTML('# Hello');
return { success: result.includes('<h1>'), result };
Markdown parser and renderer
import MarkdownIt from 'markdown-it';
// Usage:
const md = new MarkdownIt();
const result = md.render('# Hello World');
return { success: result.includes('<h1>') && result.includes('Hello World'), result };
Fast markdown parser and compiler
import { marked } from 'marked';
// Usage:
const result = marked('# Hello **World**');
return { success: result.includes('<h1>') && result.includes('<strong>'), result };
Extensive math library - expressions, matrices, units, big numbers, complex numbers.
import { evaluate, sqrt, multiply, matrix } from 'mathjs';
// Usage:
const expr = evaluate('2 + 3 * 4');
const sqrtResult = sqrt(16);
const m = multiply(matrix([[1, 2], [3, 4]]), 2);
return { success: expr === 14, result: { expr, sqrt: sqrtResult, matrix: m.toArray() } };
Parse and format media types (MIME types). Does not accept parameters in parse() - use content-type package for full parsing.
import typer from 'media-typer';
// Usage:
const parsed = typer.parse('text/html');
const formatted = typer.format({ type: 'application', subtype: 'json' });
return { success: parsed.type === 'text', result: { parsed, formatted } };
Memoization with single result cache
import memoizeOne from 'memoize-one';
// Usage:
let calls = 0;
const fn = memoizeOne((a, b) => { calls++; return a + b; });
fn(1, 2); fn(1, 2); fn(2, 3);
return { success: calls === 2, result: { calls } };
Function memoization with TTL, max cache size, and async support.
π‘ Alternative: memoize-one
import memoize from 'memoizee';
// Usage:
let callCount = 0;
const expensive = memoize((x) => { callCount++; return x * 2; });
expensive(5); expensive(5); expensive(10);
return { success: callCount === 2, result: { callCount } };
import merge from 'merge';
// Usage:
const result = merge({ a: 1 }, { b: 2 });
return { success: result.a === 1 && result.b === 2, result };
Utility for merging multiple readable streams into one. Works with Workers node:stream support.
import mergeStream from 'merge-stream';
import { Readable } from 'node:stream';
export default {
async fetch(request) {
// Create readable streams
const stream1 = Readable.from(['Hello ', 'from ', 'stream1! ']);
const stream2 = Readable.from(['And ', 'stream2 ', 'too!']);
// Merge them
const merged = mergeStream(stream1, stream2);
// Collect all data
const chunks = [];
for await (const chunk of merged) {
chunks.push(chunk);
}
return Response.json({ result: chunks.join('''') });
}
};
HTTP method name constants
import methods from 'methods';
// Usage:
return { success: Array.isArray(methods) && methods.includes('get'), result: methods.slice(0, 5) };
import micromatch from 'micromatch';
// Usage:
const result = micromatch(['foo.js', 'bar.txt'], '*.js');
return { success: result.length === 1 && result[0] === 'foo.js', result };
MIME type lookup by file extension. Useful for setting Content-Type headers.
import mime from 'mime';
const type = mime.getType('file.json'); // 'application/json'
const ext = mime.getExtension('text/html'); // 'html'
return { success: type === 'application/json', type, ext };
ESM parsing issue with Workerd. Use 'mime' package instead which includes mime-db
π‘ Alternative: mime
MIME type lookup and extension detection. Works perfectly in Workers.
import mimeTypes from 'mime-types';
// Usage:
const type = mimeTypes.lookup('test.json');
const ext = mimeTypes.extension('application/json');
return { success: type === 'application/json', result: { type, ext } };
import { minimatch } from 'minimatch';
// Usage:
const result = minimatch('foo.js', '*.js');
return { success: result === true, result };
import minimist from 'minimist';
// Usage:
const args = minimist(['--foo', 'bar', '-n', '3']);
return { success: args.foo === 'bar' && args.n === 3, result: args };
import mitt from 'mitt';
// Usage:
const emitter = mitt();
let result = '';
emitter.on('test', (data) => { result = data; });
emitter.emit('test', 'hello');
return { success: result === 'hello', result };
import { observable, autorun } from 'mobx';
// Usage:
const state = observable({ count: 0 });
let result = 0;
autorun(() => { result = state.count; });
state.count = 5;
return { success: result === 5, result };
Parse/format milliseconds
import ms from 'ms';
// Usage:
const result = ms('2 days');
const str = ms(60000);
return { success: result === 172800000 && str === '1m', result: { parsed: result, formatted: str } };
MessagePack serialization
import msgpack from 'msgpack-lite';
// Usage:
const data = { hello: 'world', num: 42 };
const encoded = msgpack.encode(data);
const decoded = msgpack.decode(encoded);
return { success: decoded.hello === 'world' && decoded.num === 42, result: decoded };
Match files against glob patterns
import multimatch from 'multimatch';
// Usage:
const result = multimatch(['foo.js', 'bar.css', 'baz.html'], ['*.js', '*.css']);
return { success: result.length === 2 && result.includes('foo.js'), result };
Logic-less template syntax
import Mustache from 'mustache';
// Usage:
const template = 'Hello {{name}}!';
const result = Mustache.render(template, { name: 'World' });
return { success: result === 'Hello World!', result };
import Negotiator from 'negotiator';
// Usage:
const negotiator = new Negotiator({ headers: { accept: 'text/html,application/json;q=0.9' } });
const types = negotiator.mediaTypes();
return { success: types.includes('text/html'), result: types };
In-memory caching
import NodeCache from 'node-cache';
// Usage:
const cache = new NodeCache();
cache.set('key', 'value', 10);
const result = cache.get('key');
return { success: result === 'value', result };
Emoji utilities - find, replace, parse emojis in text.
import * as emoji from 'node-emoji';
// Usage:
const result = emoji.emojify('I :heart: :coffee:!');
const hasEmoji = emoji.has(':heart:');
return { success: hasEmoji, result: { text: result, hasHeart: hasEmoji } };
Object extend utility
import extend from 'node.extend';
// Usage:
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const result = extend(obj1, obj2);
return { success: result.a === 1 && result.b === 3 && result.c === 4, result };
Normalizes URLs by removing default ports, sorting query params, resolving paths, etc.
import normalizeUrl from 'normalize-url';
// Usage:
const url = normalizeUrl('https://example.com:443//foo/../bar?c=1&a=2');
return { success: url === 'https://example.com/bar?a=2&c=1', result: url };
Format and manipulate numbers (currency, percentages, etc.)
import numeral from 'numeral';
// Usage:
const formatted = numeral(1000).format('0,0');
const value = numeral('1,000').value();
return { success: formatted === '1,000' && value === 1000, result: { formatted, value } };
Use native Object.assign() instead
import objectAssign from 'object-assign';
// Usage:
const result = objectAssign({}, { a: 1 }, { b: 2 }, { a: 3 });
return { success: result.a === 3 && result.b === 2, result };
Access deep object properties using path strings
import objectPath from 'object-path';
// Usage:
const obj = { a: { b: { c: 1 } } };
const val = objectPath.get(obj, 'a.b.c');
objectPath.set(obj, 'a.b.d', 2);
return { success: val === 1 && obj.a.b.d === 2, result: { val, obj } };
import onFinished from 'on-finished';
// Usage:
const mockRes = {
finished: false,
headersSent: false,
on: function(event, cb) { if (event === 'finish') setTimeout(cb, 0); return this; },
once: function(event, cb) { return this.on(event, cb); },
removeListener: function() { return this; }
};
let called = false;
onFinished(mockRes, () => { called = true; });
return { success: true, result: 'onFinished called' };
import once from 'once';
// Usage:
let count = 0;
const fn = once(() => count++);
fn(); fn(); fn();
return { success: count === 1, result: count };
TypeScript type definitions for OpenAPI specifications
import type { OpenAPI, OpenAPIV3 } from 'openapi-types';
// Usage:
const schema: OpenAPIV3.SchemaObject = { type: 'string' };
return { success: schema.type === 'string', result: schema };
Run promise-returning functions concurrently with optional concurrency limit
import pAll from 'p-all';
// Usage:
const tasks = [
() => Promise.resolve(1),
() => Promise.resolve(2),
() => Promise.resolve(3)
];
const result = await pAll(tasks, { concurrency: 2 });
return { success: result.length === 3 && result[0] === 1, result };
Map over promises concurrently with optional concurrency limit
import pMap from 'p-map';
// Usage:
const input = [1, 2, 3];
const mapper = x => Promise.resolve(x * 2);
const result = await pMap(input, mapper, { concurrency: 2 });
return { success: result.length === 3 && result[0] === 2, result };
Retry failed promises with exponential backoff
import pRetry from 'p-retry';
// Usage:
let count = 0;
const run = async () => {
count++;
if (count < 3) throw new Error('fail');
return 'success';
};
const result = await pRetry(run, { retries: 5 });
return { success: result === 'success' && count === 3, result: { result, count } };
Throttle promise-returning/async functions. Limit concurrent executions over time.
import pThrottle from 'p-throttle';
// Usage:
const throttle = pThrottle({ limit: 2, interval: 1000 });
const throttled = throttle(async (x) => x * 2);
const result = await throttled(5);
return { success: result === 10, result: { value: result } };
import Papa from 'papaparse';
// Usage:
const csv = 'name,age\nJohn,30\nJane,25';
const result = Papa.parse(csv, { header: true });
return { success: result.data.length === 2, result: result.data };
import parseurl from 'parseurl';
// Usage:
const req = { url: '/path?foo=bar' };
const parsed = parseurl(req);
return { success: parsed.pathname === '/path', result: parsed.pathname };
Node.js path module (polyfilled in Workers)
import path from 'path';
// Usage:
const result = {
join: path.join('/foo', 'bar', 'baz.txt'),
dirname: path.dirname('/foo/bar/baz.txt'),
extname: path.extname('index.html')
};
return { success: result.join === '/foo/bar/baz.txt' && result.dirname === '/foo/bar' && result.extname === '.html', result };
Check if path is absolute
import pathIsAbsolute from 'path-is-absolute';
// Usage:
const abs = pathIsAbsolute('/foo/bar');
const rel = pathIsAbsolute('foo/bar');
return { success: abs === true && rel === false, result: { abs, rel } };
Path pattern matching - useful for routing in Workers
import { match } from 'path-to-regexp';
// Usage:
const matchFn = match('/user/:id');
const result = matchFn('/user/123');
return { success: result !== false && result.params.id === '123', result };
Fast glob matcher used by many tools
import picomatch from 'picomatch';
// Usage:
const isMatch = picomatch('*.js');
const result = { match: isMatch('test.js'), noMatch: !isMatch('test.css') };
return { success: result.match && result.noMatch, result };
Promisify callback-based functions
import pify from 'pify';
// Usage:
const fn = (arg: string, callback: (err: null, result: string) => void) => {
callback(null, arg.toUpperCase());
};
const promisified = pify(fn);
const result = await promisified('hello');
return { success: result === 'HELLO', result };
Pluralization/singularization utility
import pluralize from 'pluralize';
// Usage:
const result1 = pluralize('person'); // 'people'
const result2 = pluralize('person', 1); // 'person'
const result3 = pluralize('person', 5); // 'people'
return {
success: result1 === 'people' && result2 === 'person' && result3 === 'people',
result: { result1, result2, result3 }
};
CSS-in-JS utility library
import { darken, lighten } from 'polished';
// Usage:
const darker = darken(0.1, '#CCCCCC');
const lighter = lighten(0.1, '#333333');
return { success: typeof darker === 'string' && typeof lighter === 'string', result: { darker, lighter } };
Convert bytes to human readable string
import prettyBytes from 'pretty-bytes';
// Usage:
const result = prettyBytes(1337);
return { success: result === '1.34 kB', result };
Pretty print error stack traces with colors and formatting.
import PrettyError from 'pretty-error';
// Usage:
const pe = new PrettyError();
const err = new Error('Something went wrong');
const rendered = pe.render(err);
return { success: rendered.includes('Something went wrong'), result: { length: rendered.length } };
Format JSON with colors and indentation for readable output.
π‘ Alternative: JSON.stringify(obj, null, 2)
import prettyjson from 'prettyjson';
// Usage:
const data = { name: 'test', count: 42 };
const pretty = prettyjson.render(data);
return { success: pretty.includes('name'), result: { length: pretty.length } };
Pipe streams together with proper error handling
import pump from 'pump';
// Usage:
const { Readable, Writable } = await import('node:stream');
const source = Readable.from(['hello', ' ', 'world']);
const chunks: string[] = [];
const dest = new Writable({
write(chunk, encoding, callback) {
chunks.push(chunk.toString());
callback();
}
});
await new Promise((resolve, reject) => {
pump(source, dest, (err) => {
if (err) reject(err);
else resolve(undefined);
});
});
return {
success: chunks.join('') === 'hello world',
result: chunks.join('')
};
Query string parsing (use URLSearchParams instead)
import querystring from 'querystring';
// Usage:
const parsed = querystring.parse('foo=bar&abc=xyz&abc=123');
const stringified = querystring.stringify({ foo: 'bar', baz: ['qux', 'quux'] });
return {
success: parsed.foo === 'bar' && stringified.includes('foo=bar'),
result: { parsed, stringified }
};
Simple LRU cache implementation
import QuickLRU from 'quick-lru';
// Usage:
const lru = new QuickLRU({ maxSize: 100 });
lru.set('foo', 'bar');
lru.set('hello', 'world');
return {
success: lru.has('foo') && lru.get('foo') === 'bar' && lru.get('hello') === 'world',
result: { foo: lru.get('foo'), hello: lru.get('hello'), size: lru.size }
};
requestAnimationFrame polyfill
import raf from 'raf';
// Usage:
let executed = false;
const id = raf(() => { executed = true; });
// Wait a bit for the callback to execute
await new Promise(resolve => setTimeout(resolve, 50));
return {
success: executed,
result: { executed, id }
};
import * as R from 'ramda';
// Usage:
const result = R.map(x => x * 2, [1, 2, 3]);
return { success: true, result };
Random string generation
import randomstring from 'randomstring';
// Usage:
const str = randomstring.generate(10);
return { success: str.length === 10, result: { length: str.length, sample: str } };
Get raw body from a stream. For most cases, use native Request.text() or Request.arrayBuffer() instead.
π‘ Alternative: Request.text() or stream.text()
import getRawBody from 'raw-body';
import { Readable } from 'node:stream';
// Usage:
const stream = Readable.from(['Hello ', 'World']);
const body = await getRawBody(stream, { encoding: 'utf8' });
return { success: body === 'Hello World', result: { body } };
Configuration file loader with defaults
import rc from 'rc';
// Usage:
const config = rc('myapp', { port: 8080, host: 'localhost' });
return { success: config.port === 8080 && config.host === 'localhost', result: config };
Redux state management - can be used in Workers
import { createStore } from 'redux';
// Usage:
const reducer = (state = 0, action) => action.type === 'INC' ? state + 1 : state;
const store = createStore(reducer);
store.dispatch({ type: 'INC' });
return { success: store.getState() === 1, result: store.getState() };
Redux logging middleware
import { createLogger } from 'redux-logger';
// Usage:
const logger = createLogger();
return { success: typeof logger === 'function', result: { isFunction: typeof logger === 'function' } };
Redux middleware for side effects
import createSagaMiddleware from 'redux-saga';
// Usage:
const sagaMiddleware = createSagaMiddleware();
return { success: typeof sagaMiddleware === 'function', result: { isFunction: typeof sagaMiddleware === 'function' } };
Redux middleware for async actions
import { thunk } from 'redux-thunk';
// Usage:
const middleware = thunk;
return { success: typeof middleware === 'function', result: { isFunction: typeof middleware === 'function' } };
Metadata reflection API for decorators
import 'reflect-metadata';
// Usage:
const metadataKey = Symbol('test');
class Test {}
Reflect.defineMetadata(metadataKey, 'value', Test);
const result = Reflect.getMetadata(metadataKey, Test);
return { success: result === 'value', result };
Generate JavaScript-compatible regular expressions
import regenerate from 'regenerate';
// Usage:
const set = regenerate().addRange(0x61, 0x7A); // a-z
const result = set.toString();
return { success: result.includes('[a-z]'), result };
Runtime for generators/async functions (often unnecessary in modern Workers)
import 'regenerator-runtime/runtime';
// Usage:
async function* asyncGen() { yield 1; yield 2; }
const gen = asyncGen();
const result = await gen.next();
return { success: result.value === 1, result: result.value };
Memoized selectors for Redux
import { createSelector } from 'reselect';
// Usage:
const selectItems = state => state.items;
const selectTotal = createSelector(
[selectItems],
items => items.reduce((sum, item) => sum + item, 0)
);
const state = { items: [1, 2, 3, 4] };
const result = selectTotal(state);
return { success: result === 10, result };
Node.js module resolution. isCore() works; sync/async resolve need filesystem access.
import resolve from 'resolve';
// Usage:
const fsIsCore = resolve.isCore('fs');
const fakeIsCore = resolve.isCore('nonexistent');
return { success: fsIsCore && !fakeIsCore, result: { fsIsCore, fakeIsCore } };
Fast deep cloning utility
import rfdc from 'rfdc';
// Usage:
const clone = rfdc();
const obj = { a: 1, b: { c: 2 } };
const cloned = clone(obj);
cloned.b.c = 3;
return {
success: obj.b.c === 2 && cloned.b.c === 3,
result: { original: obj, cloned }
};
Promise library (native promises preferred)
import { Promise as RSVPPromise } from 'rsvp';
// Usage:
const p = new RSVPPromise((resolve) => resolve(42));
const result = await p;
return { success: result === 42, result };
Reactive extensions for JavaScript
import { of, map } from 'rxjs';
// Usage:
const observable = of(1, 2, 3).pipe(
map(x => x * 2)
);
let result = [];
await new Promise((resolve) => {
observable.subscribe({
next: value => result.push(value),
complete: () => resolve(undefined)
});
});
return { success: result.join(',') === '2,4,6', result };
Safe Buffer API (use native Buffer)
import { Buffer } from 'safe-buffer';
// Usage:
const buf = Buffer.from('hello', 'utf8');
const result = buf.toString('base64');
return { success: result === 'aGVsbG8=', result };
import sanitize from 'sanitize-filename';
// Usage:
const result = sanitize('hello/world.txt');
return { success: result === 'helloworld.txt', result };
Semantic version parser and comparator
import semver from 'semver';
// Usage:
const valid = semver.valid('1.2.3');
const gt = semver.gt('2.0.0', '1.0.0');
const satisfies = semver.satisfies('1.5.0', '^1.0.0');
return { success: valid === '1.2.3' && gt === true && satisfies === true, result: { valid, gt, satisfies } };
Serialize Error objects to JSON-friendly format
import { serializeError } from 'serialize-error';
// Usage:
const error = new Error('Test error');
error.name = 'TestError';
const serialized = serializeError(error);
return { success: serialized.message === 'Test error' && serialized.name === 'TestError', result: serialized };
import shallowEqual from 'shallowequal';
// Usage:
const result = shallowEqual({ a: 1, b: 2 }, { a: 1, b: 2 });
return { success: result === true, result };
import { parse } from 'shell-quote';
// Usage:
const result = parse('echo "hello world"');
return { success: result.length === 2, result };
Convert Windows backslashes to forward slashes
import slash from 'slash';
// Usage:
const result = slash('foo\\bar\\baz');
return { success: result === 'foo/bar/baz', result };
Fixes stack traces for files with source maps
import sourceMapSupport from 'source-map-support';
// Usage:
// Install source map support
sourceMapSupport.install();
return { success: true, result: 'installed' };
Split text streams into line streams
import split from 'split';
// Usage:
// Split is a stream transformer
const hasSplit = typeof split === 'function';
return { success: hasSplit, result: { hasSplit } };
Split streams by newline
import split from 'split2';
// Usage:
const stream = split();
return { success: typeof stream.pipe === 'function', result: 'stream created' };
Get V8 stack traces as structured data. Use namespace import: import * as stackTrace
import * as stackTrace from 'stack-trace';
// Usage:
const err = new Error('test');
const trace = stackTrace.parse(err);
return { success: trace.length > 0, result: { frames: trace.length } };
HTTP status code utilities. Get status codes by message or message by code.
import statuses from 'statuses';
// Usage:
const code = statuses('OK');
const msg = statuses(404);
return { success: code === 200 && msg === 'Not Found', result: { code, msg } };
Detect terminal color support
import supportsColor from 'supports-color';
// Usage:
const result = supportsColor.stdout;
return { success: true, result: { hasBasic: result !== false } };
Generate text tables
import table from 'text-table';
// Usage:
const t = table([['master', 'now', 'origin/master'], ['0.1.0', '4 minutes ago']]);
return { success: t.includes('master'), result: t };
Throttle and debounce functions
import { throttle, debounce } from 'throttle-debounce';
// Usage:
const fn = () => 42;
const throttled = throttle(100, fn);
const debounced = debounce(100, fn);
return { success: typeof throttled === 'function' && typeof debounced === 'function', result: { throttled: typeof throttled, debounced: typeof debounced } };
Stream transformer utility
import through from 'through';
// Usage:
// through is a stream transformer
const stream = through((data) => data);
return { success: typeof stream.write === 'function', result: { hasWrite: typeof stream.write } };
Stream transformer utility (wrapper for through)
import through2 from 'through2';
// Usage:
// through2 is a stream transformer
const stream = through2((chunk, enc, callback) => {
callback(null, chunk);
});
return { success: typeof stream.write === 'function', result: { hasWrite: true } };
Lightweight event emitter
import Emitter from 'tiny-emitter';
// Usage:
const emitter = new Emitter();
let called = false;
emitter.on('test', () => { called = true; });
emitter.emit('test');
return { success: called, result: { emitted: called } };
Assertion utility
import invariant from 'tiny-invariant';
// Usage:
try {
invariant(true, 'should not throw');
invariant(false, 'should throw');
return { success: false, result: 'did not throw' };
} catch (e) {
return { success: true, result: 'threw as expected' };
}
Color manipulation library
import tinycolor from 'tinycolor2';
// Usage:
const color = tinycolor('#ff0000');
const hex = color.toHexString();
return { success: hex === '#ff0000', result: hex };
Object traversal utility
import traverse from 'traverse';
// Usage:
const obj = { a: 1, b: { c: 2 } };
const result = traverse(obj).map(function(x) {
if (typeof x === 'number') this.update(x * 2);
});
return { success: result.a === 2 && result.b.c === 4, result };
TypeScript utility types (no runtime)
// ts-essentials is type-only
// Usage:
return { success: true, result: 'ts-essentials is type-only' };
TypeScript runtime helpers
import * as tslib from 'tslib';
// Usage:
return { success: typeof tslib.__extends === 'function', result: { hasExtends: true } };
Content-Type checking utility. Used by body-parser and Express middleware.
import typeis from 'type-is';
const isJson = typeis.is('application/json', ['json']); // 'json'
const isHtml = typeis.is('text/html', ['html']); // 'html'
return { success: isJson === 'json' };
import _ from 'underscore';
// Usage:
const result = _.flatten([[1, 2], [3, 4]]);
return { success: true, result };
String manipulation utilities
import s from 'underscore.string';
// Usage:
const result = s.capitalize('hello');
return { success: result === 'Hello', result };
Install failed - use crypto.getRandomValues()
π‘ Alternative: crypto.getRandomValues()
AST utility for traversing unist trees
import { visit } from 'unist-util-visit';
// Usage:
const tree = { type: 'root', children: [{ type: 'text', value: 'hello' }] };
const values: string[] = [];
visit(tree, 'text', (node: any) => values.push(node.value));
return { success: values[0] === 'hello', result: values };
URI parsing and manipulation
import URI from 'urijs';
// Usage:
const uri = new URI('http://example.com/path?query=value');
return { success: uri.hostname() === 'example.com', result: { host: uri.hostname(), path: uri.path() } };
Use built-in node:url module or URL global
Error: __vite_ssr_import_0__.parse is not a function
URL path joining utility
import urljoin from 'url-join';
// Usage:
const result = urljoin('https://example.com', 'path', 'to', 'file.html');
return { success: result === 'https://example.com/path/to/file.html', result };
URL parsing library
import URL from 'url-parse';
// Usage:
const parsed = new URL('https://example.com/path?q=1');
return { success: parsed.hostname === 'example.com', result: { hostname: parsed.hostname } };
Node.js util module
import * as util from 'util';
// Usage:
const result = util.format('Hello %s', 'World');
return { success: result === 'Hello World', result };
Simple object merging utility
import merge from 'utils-merge';
// Usage:
const result = merge({ a: 1 }, { b: 2 });
return { success: result.a === 1 && result.b === 2, result };
Validate npm package names according to npm registry rules.
import validate from 'validate-npm-package-name';
// Usage:
const valid = validate('my-package');
const invalid = validate('INVALID NAME');
return { success: valid.validForNewPackages && !invalid.validForNewPackages, result: { valid: valid.validForNewPackages, errors: invalid.errors } };
HTTP Vary header utility
import vary from 'vary';
// Usage:
// vary.append() appends field to header value
const result = vary.append('Accept', 'Accept-Encoding');
return { success: result === 'Accept, Accept-Encoding', result };
Rich error objects
import VError from 'verror';
// Usage:
const err = new VError('test error');
return { success: err.message === 'test error', result: { message: err.message } };
import warning from 'warning';
// Usage:
// warning is a dev-only warning utility
// Just check that it's a function
const result = typeof warning === 'function';
warning(true, 'This should not warn');
return { success: result, result: 'warning is callable' };
Extended regular expressions with Unicode support, named capture groups, and more.
import XRegExp from 'xregexp';
// Usage:
const pattern = XRegExp('(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})');
const match = XRegExp.exec('2026-01-08', pattern);
return { success: match.groups.year === '2026', result: match.groups };
import xtend from 'xtend';
// Usage:
const result = xtend({ a: 1 }, { b: 2 }, { c: 3 });
return { success: result.a === 1 && result.b === 2 && result.c === 3, result };
Many popular npm packages are build tools (webpack, babel), test frameworks (jest, mocha), or CLI utilities (chalk, commander) that run during developmentβnot in production. Cloudflare Workers is a runtime environment for production code. These tools still work great for building your Workers project, they just don't run inside Workers themselves.
Yes! As of September 2025, Workers supports node:http server APIs.
Use httpServerHandler from cloudflare:node to wrap Express, Koa, or other Node.js HTTP frameworks.
For new projects, we recommend lightweight alternatives like Hono or itty-router which are built for edge environments.
Workers supports database clients like pg (PostgreSQL) and mysql2 when connecting to public endpoints.
For production, use edge-optimized solutions: Cloudflare D1 (SQLite), Neon (serverless Postgres), PlanetScale (MySQL), or Upstash Redis.
Common reasons: Native modules (C++ bindings like sharp, bcrypt) don't workβuse alternatives like bcryptjs or Cloudflare Images.
Filesystem access (fs module for local files) isn't availableβuse KV, R2, or D1 instead.
TCP sockets (raw socket.io, redis) aren't supportedβuse Durable Objects, WebSockets, or HTTP-based alternatives.