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 14 packages
OpenAPI/Swagger parser. parse() and dereference() work, but validate() fails because it uses ajv internally (code generation). Use for parsing specs, not validation.
import SwaggerParser from '@apidevtools/swagger-parser';
// Usage: Parse OpenAPI/Swagger specs (validation uses ajv which fails)
const spec = {
openapi: '3.0.0',
info: { title: 'My API', version: '1.0.0' },
paths: { '/users': { get: { responses: { '200': { description: 'OK' } } } } }
};
const parsed = await SwaggerParser.parse(spec);
return { success: true, result: { title: parsed.info.title } };
Extra assertions on top of Node.js assert module - provides type checking utilities
import assert from 'assert-plus';
// Usage:
assert.string('hello', 'value');
assert.number(42, 'value');
assert.object({ foo: 'bar' }, 'value');
return { success: true, result: 'All assertions passed' };
Async form validation library - commonly used with Ant Design forms
import Schema from 'async-validator';
// Usage:
const descriptor = {
name: { type: 'string', required: true, message: 'Name is required' },
age: { type: 'number', min: 0, max: 120 }
};
const validator = new Schema(descriptor);
const result = await validator.validate({ name: 'Alice', age: 30 });
return { success: true, result };
Decorator-based validation. Decorators require TypeScript with experimentalDecorators and special bundler config. Consider using zod instead for simpler setup.
💡 Alternative: zod
import { ValidationError } from 'class-validator';
// Usage: Decorators need TypeScript experimentalDecorators
const err = new ValidationError();
err.property = 'email';
err.constraints = { isEmail: 'must be valid email' };
return { success: true, result: { note: 'Use zod for Workers - decorators need special bundler config' } };
Simple email validation
import validator from 'email-validator';
// Usage:
const valid = validator.validate('test@example.com');
const invalid = validator.validate('notanemail');
return { success: valid && !invalid, result: { valid, invalid } };
Validate if a string is a valid URL
import isUrl from 'is-url';
// Usage:
const results = [
isUrl('https://example.com'),
isUrl('http://example.com/path'),
isUrl('not a url'),
isUrl('example.com')
];
return { success: results[0] && results[1] && !results[2] && !results[3], result: results };
Powerful schema validation with nested objects, arrays, conditionals, custom messages. Works on Workers unlike ajv (which uses new Function).
import Joi from 'joi';
export default {
async fetch(request) {
const userSchema = Joi.object({
username: Joi.string().alphanum().min(3).max(30).required(),
email: Joi.string().email().required(),
age: Joi.number().integer().min(0).max(120),
role: Joi.string().valid('admin', 'user').default('user')
});
const body = await request.json();
const { error, value } = userSchema.validate(body, { abortEarly: false });
if (error) {
return Response.json({ errors: error.details.map(d => d.message) }, { status: 400 });
}
return Response.json({ valid: true, data: value });
}
};
React PropTypes - runtime type checking for React components
import PropTypes from 'prop-types';
// Usage:
const stringType = PropTypes.string.isRequired;
const numberType = PropTypes.number;
const objectShape = PropTypes.shape({
name: PropTypes.string,
age: PropTypes.number
});
return {
success: typeof stringType === 'function' && typeof numberType === 'function',
result: { hasString: !!stringType, hasNumber: !!numberType, hasShape: !!objectShape }
};
Data validation library
import { object, string, number } from 'superstruct';
// Usage:
const User = object({ name: string(), age: number() });
try {
const result = User.create({ name: 'Alice', age: 30 });
return { success: result.name === 'Alice', result };
} catch (e) {
return { success: false, result: e.message };
}
import * as v from 'valibot';
// Usage:
const schema = v.object({ name: v.string() });
const result = v.safeParse(schema, { name: 'Alice' });
return { success: result.success, result: result.output };
URL validation
import validUrl from 'valid-url';
// Usage:
const valid = validUrl.isUri('http://example.com');
const invalid = validUrl.isUri('not a url');
return { success: valid && !invalid, result: { valid, invalid } };
String validation library
import validator from 'validator';
// Usage:
const email = validator.isEmail('test@example.com');
const notEmail = validator.isEmail('not-an-email');
return { success: email && !notEmail, result: { email, notEmail } };
import * as yup from 'yup';
// Usage:
const schema = yup.object({ name: yup.string().required() });
const result = await schema.validate({ name: 'Alice' });
return { success: true, result };
import { z } from 'zod';
// Usage:
const schema = z.object({ name: z.string(), age: z.number() });
const result = schema.safeParse({ name: 'Alice', age: 30 });
return { success: result.success, result: result.data };
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.