Codebase Migration
Convert an entire codebase from one pattern to another — JavaScript to TypeScript, class components to hooks, CommonJS to ESM — processing each file independently and fixing cross-file type errors at the end.
Workflow
From demos/convert-folder-to-ts:
runPipeline(
pipe(
setup,
listFiles
.forEach(migrate({ to: "Typescript" }))
.drop(),
typeCheckFix,
),
);
Stages
- Setup — determine input and output directories.
- List files — find all files to migrate.
- Migrate each file —
forEachprocesses every file concurrently. Each migration agent receives a single file and the target format — it doesn't know about other files. - Type-check/fix loop — after all files are migrated, run the compiler and fix errors in a loop:
export const typeCheckFix = loop((recur) =>
pipe(typeCheck, classifyErrors).branch({
HasErrors: pipe(forEach(fix).drop(), recur),
Clean: drop,
}),
);
Key points
- Per-file migration runs in parallel — the agent migrating
utils.tsdoesn't seeapi.ts. - The type-check/fix loop runs after all migrations, catching cross-file issues (changed exports, missing types).
createHandlerWithConfigletsmigrateaccept a step config ({ to: "Typescript" }) separate from the per-file input, keeping the handler reusable across migration types.- The same structure works for any file-by-file transformation: just swap the
migratehandler.