Remove unused JavaScript and CSS based on Chrome coverage collected via Playwright.
npm install -D coverkill playwright
npx playwright install chromium- Create
coverkill.config.ts:
import { defineConfig } from 'coverkill';
export default defineConfig({
baseURL: 'http://localhost:3000',
scenarios: ['./e2e/scenarios/*.ts'],
webServer: {
command: 'npm run dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
},
include: ['src/**/*.{js,ts,css}'],
sourcePath(url) {
// Map browser URLs to files on disk
const path = new URL(url).pathname;
if (path === '/app.js') return './dist/app.js';
return null;
},
});- Add a scenario (Playwright-style
PageAPI):
import type { ScenarioContext } from 'coverkill';
export default async function ({ page, baseURL }: ScenarioContext) {
await page.goto(baseURL);
await page.getByRole('button', { name: 'Submit' }).click();
}- Run (dry-run first):
npx coverkill --dry-run
npx coverkillBy default, matching files are modified in place. Use git so you can revert.
| Command | Description |
|---|---|
coverkill / coverkill run |
Collect coverage and prune |
coverkill collect |
Collect coverage only |
coverkill prune --report <file> |
Prune from a saved JSON report |
--config <path>— config file path--dry-run— show what would be removed without writing--save-report <path>— write coverage JSON
| Option | Description |
|---|---|
baseURL |
Base URL for scenarios |
scenarios |
Glob paths to scenario modules |
webServer |
Dev server command + URL (Playwright-style) |
include |
Allowlist globs; only these files are pruned |
exclude |
Deny globs applied after include |
sourcePath(url) |
Map coverage URL → local file path |
coverage.js |
resetOnNavigation, reportAnonymousScripts |
coverage.css |
Enable CSS coverage (default true) |
preserveLicenseHeader |
Keep leading license comments (default true) |
- Launches Chromium and starts JS/CSS coverage.
- Runs each scenario module (default export or
scenarionamed export). - Merges executed byte ranges per file.
- Removes uncovered ranges from allowlisted files (in place).
Coverage reflects what the browser executed (often built assets). To prune original src/, either serve sources directly, point sourcePath at the built files you want to shrink, or wait for future source-map support.
pnpm install
pnpm build
pnpm test
pnpm start -- --config examples/minimal-vite/coverkill.config.ts --dry-run
pnpm example -- --dry-runRun the example app manually:
cd examples/minimal-vite && npm install && npm run startimport { run, collect, prune, defineConfig } from 'coverkill';
await run({ configPath: './coverkill.config.ts', dryRun: true });MIT