Skip to content
Development
Skill

/writing-dev-server-tests

Guides writing HMR/Dev Server tests in test/bake/. Use when creating or modifying dev server, hot reloading, or bundling tests.

From plugin
bun
97k8 skills5 commands

Claude Code

$ npx -y skills add oven-sh/bun --skill writing-dev-server-tests --agent claude-code

SKILL.md

writing-dev-server-tests.SKILL.md
name: writing-dev-server-tests
description: Guides writing HMR/Dev Server tests in test/bake/. Use when creating or modifying dev server, hot reloading, or bundling tests.

Writing HMR/Dev Server Tests

Dev server tests validate hot-reloading robustness and reliability.

File Structure

  • `test/bake/bake-harness.ts` - shared utilities: `devTest`, `prodTest`, `devAndProductionTest`, `Dev` class, `Client` class
  • `test/bake/client-fixture.mjs` - subprocess for `Client` (page loading, IPC queries)
  • `test/bake/dev/*.test.ts` - dev server and hot reload tests
  • `test/bake/dev-and-prod.ts` - tests running on both dev and production mode

Test Categories

  • `bundle.test.ts` - DevServer-specific bundling bugs
  • `css.test.ts` - CSS bundling issues
  • `plugins.test.ts` - development mode plugins
  • `ecosystem.test.ts` - library compatibility (prefer concrete bugs over full package tests)
  • `esm.test.ts` - ESM features in development
  • `html.test.ts` - HTML file handling
  • `react-spa.test.ts` - React, react-refresh transform, server components
  • `sourcemap.test.ts` - source map correctness

devTest Basics

import { devTest, emptyHtmlFile } from "../bake-harness";

devTest("html file is watched", {
  files: {
    "index.html": emptyHtmlFile({
      scripts: ["/script.ts"],
      body: "<h1>Hello</h1>",
    }),
    "script.ts": `console.log("hello");`,
  },
  async test(dev) {
    await dev.fetch("/").expect.toInclude("<h1>Hello</h1>");
    await dev.patch("index.html", { find: "Hello", replace: "World" });
    await dev.fetch("/").expect.toInclude("<h1>World</h1>");

    await using c = await dev.client("/");
    await c.expectMessage("hello");

    await c.expectReload(async () => {
      await dev.patch("index.html", { find: "World", replace: "Bar" });
    });
    await c.expectMessage("hello");
  },
});

Key APIs

  • **`files`**: Initial filesystem state
  • **`dev.fetch()`**: HTTP requests
  • **`dev.client()`**: Opens browser instance
  • **`dev.write/patch/delete`**: Filesystem mutations (wait for hot-reload automatically)
  • **`c.expectMessage()`**: Assert console.log output
  • **`c.expectReload()`**: Wrap code that causes hard reload

**Important**: Use `dev.write/patch/delete` instead of `node:fs` - they wait for hot-reload.

Testing Errors

devTest("import then create", {
  files: {
    "index.html": `<!DOCTYPE html><html><head></head><body><script type="module" src="/script.ts"></script></body></html>`,
    "script.ts": `import data from "./data"; console.log(data);`,
  },
  async test(dev) {
    const c = await dev.client("/", {
      errors: ['script.ts:1:18: error: Could not resolve: "./data"'],
    });
    await c.expectReload(async () => {
      await dev.write("data.ts", "export default 'data';");
    });
    await c.expectMessage("data");
  },
});

Specify expected errors with the `errors` option:

await dev.delete("other.ts", {
  errors: ['index.ts:1:16: error: Could not resolve: "./other"'],
});
Read more
@oven-sh
Ships withbun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one

Stars on GitHub

Momentum

stars in total
96.7k
Star history of oven-sh/bun on GitHub, a chart by star-history.com

Other skills on bun.

implementing-jsc-classes-cpp

implementing-jsc-class…

Implements JavaScript classes in C++ using JavaScriptCore. Use when creating new JS classes with C++ bindings, prototypes, or…

@oven-sh@oven-shInstall Skill
implementing-jsc-classes-rust

implementing-jsc-class…

Creates JavaScript classes using Bun's bindings generator (.bind.ts). Use when implementing new JS APIs in Rust with JSC…

@oven-sh@oven-shInstall Skill
rust-system-calls

rust-system-calls

Guides using bun_sys for system calls and file I/O in Rust. Use when implementing file operations, opening fds, or any syscall…

@oven-sh@oven-shInstall Skill
slowest-tests

slowest-tests

Find the top-N slowest test files in CI from a recent BuildKite run, optionally posting the results to a Slack channel as a…

@oven-sh@oven-shInstall Skill
verify

verify

Verify a Bun runtime change by driving the debug binary end-to-end.

@oven-sh@oven-shInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about writing-dev-server-tests.

Which coding agents can use writing-dev-server-tests?
writing-dev-server-tests installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.