Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit

* chore(tsc): move `assert` util to shared file

* chore(tsc): remove `skipLibCheck` config;

- prevents intellisense "*.d.ts" checks?

* chore(tsc): split `types/check.ts` into smaller files

Git stats


Failed to load latest commit information.
Latest commit message
Commit time
The next generation web framework for Cloudflare Workers


  • Super lightweight
  • First-class TypeScript support
  • Custom Middleware Support
  • Well-organized submodules for à la carte functionality*
  • Includes Router with support for pattern definitions
  • Familiar Request-Response handler API
  • Supports async/await handlers
  • Fully treeshakable

*More to come!


$ npm install --save worktop


Check out /examples for a list of working demos!

import { Router } from 'worktop';
import * as Cache from 'worktop/cache';
import { uid as toUID } from 'worktop/utils';
import { read, write } from 'worktop/kv';
import type { KV } from 'worktop/kv';

declare var DATA: KV.Namespace;

interface Message {
  id: string;
  text: string;
  // ...

// Initialize
const API = new Router();

API.add('GET', '/messages/:id', async (req, res) => {
  // Pre-parsed `req.params` object
  const key = `messages::${}`;

  // Assumes JSON (can override)
  const message = await read<Message>(DATA, key);

  // Alter response headers directly
  res.setHeader('Cache-Control', 'public, max-age=60');

  // Smart `res.send()` helper
  // ~> automatically stringifies JSON objects
  // ~> auto-sets `Content-Type` & `Content-Length` headers
  res.send(200, message);

API.add('POST', '/messages', async (req, res) => {
  try {
    // Smart `req.body` helper
    // ~> parses JSON header as JSON
    // ~> parses form-like header as FormData, ...etc
    var input = await req.body<Message>();
  } catch (err) {
    return res.send(400, 'Error parsing request body');

  if (!input || !input.text.trim()) {
    return res.send(422, { text: 'required' });

  const value: Message = {
    id: toUID(16),
    text: input.text.trim(),
    // ...

  // Assumes JSON (can override)
  const key = `messages::${}`;
  const success = await write<Message>(DATA, key, value);
  //    ^ boolean

  // Alias for `event.waitUntil`
  // ~> queues background task (does NOT delay response)
    fetch('https://.../logs', {
      method: 'POST',
      headers: { 'content-type': 'application/json '},
      body: JSON.stringify({ success, value })

  if (success) res.send(201, value);
  else res.send(500, 'Error creating record');

API.add('GET', '/alive', (req, res) => {
  res.end('OK'); // Node.js-like `res.end`

// Attach "fetch" event handler
// ~> use `Cache` for request-matching, when permitted
// ~> store Response in `Cache`, when permitted


Module: worktop

View worktop API documentation

The main module – concerned with routing.
This is core of most applications. Exports the Router class.

Module: worktop/kv

View worktop/kv API documentation

The worktop/kv submodule contains all classes and utilities related to Workers KV.

Module: worktop/cache

View worktop/cache API documentation

The worktop/cache submodule contains all utilities related to Cloudflare's Cache.

Module: worktop/request

View worktop/request API documentation

The worktop/request submodule contains the ServerRequest class, which provides an interface similar to the request instance(s) found in most other Node.js frameworks.

Note: This module is used internally and will (very likely) never be imported by your application.

Module: worktop/response

View worktop/response API documentation

The worktop/response submodule contains the ServerResponse class, which provides an interface similar to the IncomingMessage (aka, "response") object that Node.js provides.

Note: This module is used internally and will (very likely) never be imported by your application.

Module: worktop/base64

View worktop/base64 API documentation

The worktop/base64 submodule contains a few utilities related to the Base 64 encoding.

Module: worktop/cookie

View worktop/cookie API documentation

The worktop/cookie submodule contains parse and stringify utilities for dealing with cookie header(s).

Module: worktop/cors

View worktop/cors API documentation

The worktop/cors submodule offers utilities for dealing with Cross-Origin Resource Sharing (CORS) headers.

Module: worktop/crypto

View worktop/crypto API documentation

The worktop/crypto submodule is a collection of cryptographic functionalities.

Module: worktop/utils

View worktop/utils API documentation

The worktop/utils submodule is a collection of standalone, general-purpose utilities that you may find useful. These may include – but are not limited to – hashing functions and unique identifier generators.

Module: worktop/ws

View worktop/ws API documentation

The worktop/ws submodule contains the WebSocket and WebSocketPair class definitions, as well as two middleware handlers for validating and/or setting up a SocketHandler for the WebSocket connection.


MIT © Luke Edwards