Problem
A TS developer with a new Vite project wants httptape as their dev backend proxy — record once, replay deterministically, edit JSON fixtures by hand. Today the only path (in httptape/httptape's examples/ts-frontend-first) is docker-compose with three services, requires Docker, and lives outside vite.config.ts. Not competitive with Vite's native DX.
User story
As a TS developer with a Vite project, I want to add httptape() to my vite.config.ts plugins array so that during vite dev my API calls are transparently proxied through httptape — recorded on first hit, replayed from local JSON fixtures on subsequent runs, with secrets redacted before they hit disk.
Public API (the whole surface for v0.0.1)
```ts
import { defineConfig } from 'vite'
import httptape from 'vite-plugin-httptape'
export default defineConfig({
plugins: [
httptape({
upstream: 'https://api.example.com', // required when mode: 'proxy'
fixtures: './mocks', // default: './mocks'
sanitize: './sanitize.json', // default: undefined (no sanitization)
mode: 'proxy', // 'proxy' | 'serve' — default: 'proxy'
route: '/api', // Vite server.proxy key — default: '/api'
port: 0, // 0 = pick free port — default: 0
}),
],
})
```
That's the whole surface — six options, CORS hardcoded on, no DSL.
What the plugin does
- On `vite dev` start: spawn the httptape binary with the right CLI flags as a child process. If `port: 0`, picks a free port first via `net.createServer().listen(0)`.
- Wires `vite.config.server.proxy[route]` so requests forward to the local httptape port.
- Pipes httptape's stdout/stderr through Vite's logger with a `[httptape]` prefix.
- On `vite dev` stop (SIGINT, file-triggered restart, etc.): graceful shutdown of the httptape child (SIGTERM with 3s grace, then SIGKILL).
- `mode: 'serve'` swaps `httptape proxy` for `httptape serve` (no upstream needed) — frontend-first dev when there's no backend yet.
Out of scope for v0.0.1
- Recording control (always records on miss in proxy mode; no per-route opt-out)
- Hot-reload of `sanitize.json` (Vite restart picks it up)
- `freeze: true` / replay-only mode (punted to v0.0.2)
- Multiple upstreams (one plugin instance, one upstream)
- Testcontainers-style usage from Vitest tests (separate package later)
- Next.js / Remix / webpack integrations (separate packages later)
Acceptance criteria
Validation gate
v0.0.1 is not published to npm until the converted `examples/ts-frontend-first` demo runs cleanly and the dev-server lifecycle is verified by hand. Same gating pattern as `httptape-jvm`.
Status
READY_FOR_DEV — see first comment for ADR-1 (architectural design).
Problem
A TS developer with a new Vite project wants httptape as their dev backend proxy — record once, replay deterministically, edit JSON fixtures by hand. Today the only path (in httptape/httptape's
examples/ts-frontend-first) is docker-compose with three services, requires Docker, and lives outsidevite.config.ts. Not competitive with Vite's native DX.User story
As a TS developer with a Vite project, I want to add
httptape()to myvite.config.tsplugins array so that duringvite devmy API calls are transparently proxied through httptape — recorded on first hit, replayed from local JSON fixtures on subsequent runs, with secrets redacted before they hit disk.Public API (the whole surface for v0.0.1)
```ts
import { defineConfig } from 'vite'
import httptape from 'vite-plugin-httptape'
export default defineConfig({
plugins: [
httptape({
upstream: 'https://api.example.com', // required when mode: 'proxy'
fixtures: './mocks', // default: './mocks'
sanitize: './sanitize.json', // default: undefined (no sanitization)
mode: 'proxy', // 'proxy' | 'serve' — default: 'proxy'
route: '/api', // Vite server.proxy key — default: '/api'
port: 0, // 0 = pick free port — default: 0
}),
],
})
```
That's the whole surface — six options, CORS hardcoded on, no DSL.
What the plugin does
Out of scope for v0.0.1
Acceptance criteria
Validation gate
v0.0.1 is not published to npm until the converted `examples/ts-frontend-first` demo runs cleanly and the dev-server lifecycle is verified by hand. Same gating pattern as `httptape-jvm`.
Status
READY_FOR_DEV — see first comment for ADR-1 (architectural design).