Works on Workers

Discover which npm packages work in Cloudflare Workers. 395+ packages tested and working.

395+
Packages Working
992
Packages Tested
80
💡 Alternatives

Browse by Category

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 21 packages

cheerio

✅ Works
v1.1.2 12,843,962 weekly downloads parsing

jQuery-like HTML parsing and manipulation. Perfect for web scraping, HTML transformation, and extracting data from webpages on Workers. Supports full CSS selectors.

View Example
import * as cheerio from 'cheerio';

export default {
  async fetch(request) {
    // Fetch and parse a webpage
    const response = await fetch('https://example.com');
    const html = await response.text();
    const $ = cheerio.load(html);
    
    // Extract data with jQuery-like selectors
    const title = $('title').text();
    const h1 = $('h1').text();
    const links = $('a').map((i, el) => $(el).attr('href')).get();
    
    // Manipulate HTML
    $('h1').addClass('scraped').text('Modified');
    
    return Response.json({ title, h1, links });
  }
};

csv

✅ Works
v6.4.1 1,388,451 weekly downloads parsing

Full-featured CSV parsing and generation. Supports headers, custom delimiters (TSV), quoted values, escaped characters, and both sync and streaming APIs.

View Example
import { parse, stringify } from 'csv/sync';

export default {
  async fetch(request) {
    // Parse CSV with headers as column names
    const csvData = 'name,age,city\nAlice,30,NYC\nBob,25,LA';
    const records = parse(csvData, { columns: true, skip_empty_lines: true });
    
    // Generate CSV from objects
    const data = [{ id: 1, product: 'Widget', price: 9.99 }];
    const csv = stringify(data, { header: true });
    
    // TSV support with custom delimiter
    const tsv = 'name\tvalue\nfoo\t100';
    const tsvRecords = parse(tsv, { columns: true, delimiter: '\t' });
    
    return Response.json({ records, csv, tsvRecords });
  }
};
v5.3.3 46,575,790 weekly downloads parsing

Fast XML parser, builder, and validator. Supports attributes, CDATA, namespaces, and various XML formats (RSS, SOAP, etc.). No DOM required - pure string parsing.

View Example
import { XMLParser, XMLBuilder, XMLValidator } from 'fast-xml-parser';

export default {
  async fetch(request) {
    // Parse XML to JSON
    const parser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: '@_' });
    const xml = '<catalog><book id="1"><title>JS Guide</title></book></catalog>';
    const parsed = parser.parse(xml);
    
    // Build XML from JSON
    const builder = new XMLBuilder({ ignoreAttributes: false, attributeNamePrefix: '@_' });
    const built = builder.build({ root: { item: [{ '@_id': '1', name: 'Item' }] } });
    
    // Validate XML
    const isValid = XMLValidator.validate(xml);
    
    return Response.json({ parsed, built, isValid });
  }
};

front-matter

✅ Works
v4.0.2 4,731,919 weekly downloads parsing

Extracts YAML front matter from markdown files. Commonly used in static site generators.

View Example
import fm from 'front-matter';

// Usage:
const content = `---
title: Hello World
date: 2026-01-09
tags: [test, markdown]
---

# Article Content

This is the body of the article.
`;
const parsed = fm(content);
return { 
  success: parsed.attributes.title === 'Hello World' && parsed.body.includes('Article Content'),
  result: { attributes: parsed.attributes, bodyLength: parsed.body.length }
};

graphql

✅ Works
v16.12.0 21,372,329 weekly downloads parsing

Full GraphQL implementation: schema building (SDL or programmatic), query parsing, validation, and execution. Build complete GraphQL APIs on Workers.

View Example
import { graphql, buildSchema, parse, validate, GraphQLSchema, GraphQLObjectType, GraphQLString } from 'graphql';

export default {
  async fetch(request) {
    // SDL-based schema
    const schema = buildSchema(`
      type Query {
        hello: String
        user(id: Int!): User
      }
      type User { id: Int, name: String }
    `);
    const root = {
      hello: () => 'Hello from Workers!',
      user: ({ id }) => ({ id, name: 'User ' + id })
    };
    
    const result = await graphql({
      schema,
      source: '{ hello user(id: 1) { name } }',
      rootValue: root
    });
    
    return Response.json(result);
  }
};

graphql-tag

✅ Works
v2.12.6 8,110,539 weekly downloads parsing

GraphQL query parser for template literals

View Example
import gql from 'graphql-tag';

// Usage:
const query = gql`
  query GetUser($id: ID!) {
    user(id: $id) {
      name
      email
    }
  }
`;
return { success: query.kind === 'Document' && query.definitions.length > 0, result: { kind: query.kind, definitions: query.definitions.length } };

gray-matter

✅ Works
v4.0.3 2,672,665 weekly downloads parsing

Parse YAML/JSON front matter from markdown strings. Supports custom delimiters, stringify for generating front matter, and excerpts. TOML requires additional engine config.

View Example
import matter from 'gray-matter';

export default {
  async fetch(request) {
    // Parse YAML front matter
    const markdown = `---
title: My Post
date: 2024-01-15
tags: [js, workers]
---

# Content Here`;
    const { data, content } = matter(markdown);
    
    // JSON front matter
    const json = `---json
{"title": "JSON"}
---
Content`;
    const jsonParsed = matter(json);
    
    // Stringify back to front matter
    const output = matter.stringify('New content', { title: 'Generated' });
    
    return Response.json({ yaml: data, json: jsonParsed.data, output });
  }
};

htmlparser2

✅ Works
v10.0.0 43,886,770 weekly downloads parsing

Fast streaming HTML/XML parser with DOM utilities. Use with dom-serializer for HTML output. Good alternative to cheerio for lower-level parsing.

View Example
import { parseDocument, DomUtils } from 'htmlparser2';
import render from 'dom-serializer';

export default {
  async fetch(request) {
    const response = await fetch('https://example.com');
    const html = await response.text();
    const dom = parseDocument(html);
    
    // Find elements
    const h1 = DomUtils.findOne(el => el.name === 'h1', dom.children, true);
    const title = h1 ? DomUtils.textContent(h1) : null;
    const links = DomUtils.findAll(el => el.name === 'a', dom.children, true);
    
    // Serialize back to HTML
    const serialized = render(dom);
    
    return Response.json({ title, linkCount: links.length });
  }
};

js-yaml

✅ Works
v4.1.1 133,314,380 weekly downloads parsing
View Example
import yaml from 'js-yaml';

// Usage:
const obj = yaml.load('name: Alice\nage: 30');
return { success: true, result: obj };

plist

✅ Works
v3.1.0 4,954,375 weekly downloads parsing

Parse/build Apple plist files

View Example
import plist from 'plist';

// Usage:
const obj = { name: 'test', version: 1 };
const xml = plist.build(obj);
const parsed = plist.parse(xml);
return { success: parsed.name === 'test', result: parsed };

qs

✅ Works
v6.14.1 94,050,307 weekly downloads parsing
View Example
import qs from 'qs';

// Usage:
const parsed = qs.parse('a=1&b=2');
const stringified = qs.stringify({ c: 3, d: 4 });
return { success: true, result: { parsed, stringified } };

query-string

✅ Works
v9.3.1 13,119,516 weekly downloads parsing
View Example
import queryString from 'query-string';

// Usage:
const parsed = queryString.parse('a=1&b=2');
return { success: true, result: parsed };

range-parser

✅ Works
v1.2.1 63,952,802 weekly downloads parsing

Parse HTTP Range header (used in streaming/partial content)

View Example
import rangeParser from 'range-parser';

// Usage:
const result = rangeParser(1000, 'bytes=0-499');
return { success: Array.isArray(result) && result[0].start === 0 && result[0].end === 499, result };

sax

✅ Works
v1.4.4 42,321,887 weekly downloads parsing
View Example
import sax from 'sax';

// Usage:
const parser = sax.parser(true);
let tagName = '';
parser.onopentag = (node) => { tagName = node.name; };
parser.write('<xml>').close();
return { success: tagName === 'xml', result: tagName };

toml

✅ Works
v3.0.0 2,448,021 weekly downloads parsing
View Example
import TOML from 'toml';

// Usage:
const obj = TOML.parse('name = "Alice"\nage = 30');
return { success: true, result: obj };

xlsx

✅ Works
v0.18.5 4,917,586 weekly downloads parsing
View Example
import * as XLSX from 'xlsx';

// Usage:
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.aoa_to_sheet([['Name', 'Age'], ['Alice', 30]]);
XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');
const csv = XLSX.utils.sheet_to_csv(ws);
return { success: csv.includes('Alice'), result: csv };

xml2js

✅ Works
v0.6.2 24,690,803 weekly downloads parsing
View Example
import { parseString } from 'xml2js';

// Usage:
let result: any;
parseString('<root><name>test</name></root>', (err, res) => { result = res; });
return { success: result?.root?.name?.[0] === 'test', result };

xmlbuilder

✅ Works
v15.1.1 35,374,414 weekly downloads parsing
View Example
import builder from 'xmlbuilder';

// Usage:
const xml = builder.create('root').ele('name', 'test').end();
return { success: xml.includes('<name>test</name>'), result: xml };

xmldom

✅ Works
v0.6.0 1,292,604 weekly downloads parsing

XML DOM parser and serializer. Parse and manipulate XML documents in Workers.

View Example
import { DOMParser, XMLSerializer } from '@xmldom/xmldom';

const parser = new DOMParser();
const doc = parser.parseFromString('<root><item>test</item></root>', 'text/xml');
const item = doc.getElementsByTagName('item')[0].textContent;
return { success: item === 'test', item };

yaml

✅ Works
v2.8.2 82,200,174 weekly downloads parsing
View Example
import YAML from 'yaml';

// Usage:
const obj = { name: 'test', age: 30 };
const str = YAML.stringify(obj);
const parsed = YAML.parse(str);
return { success: parsed.name === 'test' && parsed.age === 30, result: parsed };

yamljs

✅ Works
v0.3.0 1,708,221 weekly downloads parsing
View Example
import YAML from 'yamljs';

// Usage:
const obj = { name: 'test', age: 30 };
const str = YAML.stringify(obj);
const parsed = YAML.parse(str);
return { success: parsed.name === 'test' && parsed.age === 30, result: parsed };

Common Questions

Why are so many packages marked "Build/Dev Tool"?

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.

Can I use Express/Koa/Hapi in Workers?

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.

What about databases like PostgreSQL or MySQL?

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.

Why doesn't package X work?

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.