DEV Community

teaganga
teaganga

Posted on

How to Add Vitest to a Cloudflare Worker Project (TypeScript)

Cloudflare Workers are fast, lightweight, and TypeScript-friendly — but testing them often feels confusing at first.
This guide walks through adding Vitest to an existing Cloudflare Worker project, explains why each step exists, and clears up common confusions (like jsdom, coverage packages, and where tests should live).

By the end, you’ll have:

  • Vitest running cleanly
  • A sensible folder structure
  • Zero unnecessary dependencies
  • A setup that fits Cloudflare Workers (not browsers)

Starting Point: Existing Worker Project

Assume your project looks like this:

.
├── package.json
├── package-lock.json
├── public/
│   └── index.html
├── src/
│   └── index.ts
├── tsconfig.json
├── worker-configuration.d.ts
└── wrangler.jsonc
Enter fullscreen mode Exit fullscreen mode

This is a TypeScript Cloudflare Worker, likely using Wrangler.


Why Vitest?

Vitest is a modern test runner built on Vite. It’s a great fit because:

  • TypeScript works out of the box
  • Very fast startup and watch mode
  • Jest-style API (describe, it, expect)
  • Minimal configuration
  • Works cleanly with Worker / Node-style environments

For new TypeScript projects, Vitest is usually the best choice.


Step 1: Install Vitest (and Only What You Need)

Run this once:

npm install -D vitest @vitest/coverage-v8
Enter fullscreen mode Exit fullscreen mode

What this actually installs

  • vitest
    The test runner itself. This is required.

  • @vitest/coverage-v8
    Optional but useful. It enables code-coverage reporting using V8’s native engine.

Both are installed as dev dependencies (-D) because:

  • tests run locally or in CI
  • they are never deployed to Cloudflare

❌ What you do not need

You might see advice to install jsdom.
Do not install it for Cloudflare Workers.

Workers:

  • do not have document or window
  • are not browser environments

So skip:

npm install -D jsdom   ❌
Enter fullscreen mode Exit fullscreen mode

Step 2: Add a Vitest Config

Create vitest.config.ts at the project root:

import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    environment: 'node'
  }
})
Enter fullscreen mode Exit fullscreen mode

Why environment: 'node'?

Cloudflare Workers behave much closer to Node-style runtimes than browsers.

  • No DOM
  • No window
  • No document

Using node avoids fake browser APIs and keeps tests honest.


Step 3: Add Test Scripts

Update package.json:

{
  "scripts": {
    "test": "vitest",
    "test:run": "vitest run",
    "test:coverage": "vitest run --coverage"
  }
}
Enter fullscreen mode Exit fullscreen mode

When to use which

  • npm test → watch mode (great during development)
  • npm run test:run → one-off run (CI-friendly)
  • npm run test:coverage → generates coverage stats

Step 4: Where Should Tests Live?

Put tests inside src/, next to the code they test.

Recommended structure

src/
├── index.ts
├── index.test.ts
Enter fullscreen mode Exit fullscreen mode

As the project grows:

src/
├── handlers/
│   ├── auth.ts
│   └── auth.test.ts
├── utils/
│   ├── math.ts
│   └── math.test.ts
Enter fullscreen mode Exit fullscreen mode

Why this works best

  • Tests stay close to the code
  • Imports are simple (./index)
  • Easy to refactor
  • Vitest finds these files automatically

Vitest already looks for:

**/*.test.ts
**/*.spec.ts
Enter fullscreen mode Exit fullscreen mode

No extra configuration needed.


Step 5: Example Test

src/index.ts

export function add(a: number, b: number) {
  return a + b
}
Enter fullscreen mode Exit fullscreen mode

src/index.test.ts

import { describe, it, expect } from 'vitest'
import { add } from './index'

describe('add', () => {
  it('adds two numbers', () => {
    expect(add(2, 3)).toBe(5)
  })
})
Enter fullscreen mode Exit fullscreen mode

Run it:

npm test
Enter fullscreen mode Exit fullscreen mode

Or once:

npx vitest run
Enter fullscreen mode Exit fullscreen mode

Step 6: Make Sure Tests Aren’t Deployed

Ensure your tsconfig.json excludes test files:

{
  "include": ["src/**/*.ts"],
  "exclude": ["src/**/*.test.ts", "src/**/*.spec.ts"]
}
Enter fullscreen mode Exit fullscreen mode

This guarantees:

  • test files are never bundled
  • Workers stay lean

Summary

  • ✅ Use Vitest for Cloudflare Workers
  • ✅ Install vitest (coverage optional)
  • ❌ Do not install jsdom
  • 📁 Put tests inside src/
  • ⚙️ Use environment: 'node'
  • 🚀 You’re production-ready and CI-friendly

This setup is minimal, modern, and scales cleanly as your Worker grows.

Top comments (0)