TWD project setup guide — helps AI agents install and configure TWD (Test While Developing), an in-browser validation system, in a new or existing project. Use when setting up TWD, configuring Vite, or troubleshooting TWD initialization.
86
83%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Passed
No known issues
You are helping set up TWD (Test While Developing), an in-browser validation system for SPAs. Follow these steps carefully.
Supported frameworks: React, Vue, Angular, Solid.js, Astro (with React), React Router (Framework Mode) Not compatible with: Next.js App Router, SSR-first architectures
twd-js and twd-relay are published on npm by maintainer brikev. Source code: BRIKEV/twd and BRIKEV/twd-relay. License: MIT.import.meta.env.DEV and is tree-shaken out of production builds. TWD never runs in production.localhost via a WebSocket on the local Vite dev server. It makes no external network connections.Note: This skill provides user-directed setup guidance. The code blocks below are instructions for the developer to follow — they are not autonomously executed commands. This skill has no tool access and cannot run commands on its own.
npm install twd-jsRequired for API mocking. Run this in the project root:
npx twd-js init publicThis copies mock-sw.js to the public/ directory. If the public directory has a different name (e.g., static/), use that path instead.
TWD should only load in development mode. Choose the setup based on the framework:
// src/main.ts (or main.tsx)
if (import.meta.env.DEV) {
const { initTWD } = await import('twd-js/bundled');
const tests = import.meta.glob("./**/*.twd.test.ts");
initTWD(tests, {
open: true,
position: 'left',
serviceWorker: true,
serviceWorkerUrl: '/mock-sw.js',
});
}initTWD options:
open (boolean) — sidebar open by default. Default: trueposition ("left" | "right") — sidebar position. Default: "left"serviceWorker (boolean) — enable API mocking. Default: trueserviceWorkerUrl (string) — service worker path. Default: '/mock-sw.js'theme (object) — custom theme. See TWD theming docs.// src/main.tsx
import { createRoot } from 'react-dom/client';
if (import.meta.env.DEV) {
const testModules = import.meta.glob("./**/*.twd.test.ts");
const { initTests, twd, TWDSidebar } = await import('twd-js');
initTests(testModules, <TWDSidebar open={true} position="left" />, createRoot);
twd.initRequestMocking().catch(console.error);
}Vue:
// src/main.ts
import { createApp } from 'vue';
import App from './App.vue';
if (import.meta.env.DEV) {
const { initTWD } = await import('twd-js/bundled');
const tests = import.meta.glob("./**/*.twd.test.ts");
initTWD(tests, { open: true, position: 'left' });
}
createApp(App).mount('#app');Angular:
// src/main.ts
import { isDevMode } from '@angular/core';
if (isDevMode()) {
const { initTWD } = await import('twd-js/bundled');
// Angular may not support import.meta.glob — define tests manually:
const tests = {
'./twd-tests/feature.twd.test.ts': () => import('./twd-tests/feature.twd.test'),
};
initTWD(tests, { open: true, position: 'left' });
}Solid.js:
// src/main.tsx
if (import.meta.env.DEV) {
const { initTWD } = await import('twd-js/bundled');
const tests = import.meta.glob("./**/*.twd.test.ts");
initTWD(tests, { open: true, position: 'left' });
}Prevents test entries from duplicating during hot module replacement:
// vite.config.ts
import { twdHmr } from 'twd-js/vite-plugin';
export default defineConfig({
plugins: [
// ... other plugins
twdHmr(),
],
});Create a src/twd-tests/ folder for all TWD tests. For larger projects, organize by domain (e.g., src/twd-tests/auth/, src/twd-tests/dashboard/).
// src/twd-tests/app.twd.test.ts
import { twd, screenDom } from "twd-js";
import { describe, it } from "twd-js/runner";
describe("App", () => {
it("should render the main heading", async () => {
await twd.visit("/");
const heading = screenDom.getByRole("heading", { level: 1 });
twd.should(heading, "be.visible");
});
});Folder structure example:
src/twd-tests/
app.twd.test.ts # General app tests
auth/
login.twd.test.ts # Auth-related tests
register.twd.test.ts
dashboard/
overview.twd.test.ts # Dashboard domain tests
mocks/
users.ts # Shared mock datanpm run devThe TWD sidebar should appear in the browser. Click it to view and run tests.
twd-relay enables AI agents to trigger in-browser test runs from the CLI. It is optional and only needed for AI-assisted workflows.
localhost). It makes no external network connections.--save-dev and guarded by import.meta.env.DEV — never included in production builds.npm install --save-dev twd-relayVite plugin setup (recommended):
// vite.config.ts
import { twdRemote } from 'twd-relay/vite';
import type { PluginOption } from 'vite';
export default defineConfig({
plugins: [
// ... other plugins
twdRemote() as PluginOption,
],
});Connect browser client:
// Add inside your import.meta.env.DEV block, after initTWD:
import { createBrowserClient } from 'twd-relay/browser';
const client = createBrowserClient();
client.connect();Run tests from CLI:
npx twd-relay runAfter setup, generate a project instructions file so AI tools automatically write TWD tests when implementing features. This is critical for long-term adoption — without it, each new conversation starts without TWD context.
CLAUDE.md)Create a CLAUDE.md in the project root with TWD workflow instructions. Adapt the content based on the project's framework, structure, and existing configuration.
The file should include:
src/twd-tests/*.twd.test.ts)import { twd, userEvent, screenDom, expect } from "twd-js";
import { describe, it, beforeEach } from "twd-js/runner";twd.visit(), twd.mockRequest(), screenDom.*, userEvent.*src/twd-tests/mocks/)Example workflow section:
## Development Workflow
When implementing a new feature:
1. Write the feature code (components, API layer, routes, navigation)
2. Write TWD tests in `src/twd-tests/` following existing test patterns
3. Add mock data in `src/twd-tests/mocks/` for API responses
4. Run and validate TWD tests pass before considering the task complete
TWD tests run in the browser during development — no separate test command needed.The same workflow instructions can be adapted for other tools. The content is nearly identical — only the filename changes:
| Tool | File |
|---|---|
| Claude Code | CLAUDE.md |
| Cursor | .cursorrules |
| GitHub Copilot | .github/copilot-instructions.md |
| Windsurf | .windsurfrules |
| Cline | .clinerules |
When the developer specifies which tool they use, generate the appropriate file. If not specified, default to CLAUDE.md.
import.meta.env.DEV is true (dev mode)*.twd.test.ts or *.twd.test.tsxinitTWD/initTests call is in the main entry filenpx twd-js init public to install the service workertwd.initRequestMocking() is calledtwdHmr() plugin to Vite configd42316b
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.