Batch Operations
Your team is migrating from moment.js to date-fns. There are 147 files importing moment, each using a different subset of the API. A find-and-replace will not work because moment().format('YYYY-MM-DD') becomes format(new Date(), 'yyyy-MM-dd') — the API surface is completely different. Doing this manually takes a week. With the right batch operation pattern, it takes an afternoon.
What You Will Walk Away With
Section titled “What You Will Walk Away With”- Subagent-based parallel processing for multi-file changes
- The plan-then-execute pattern for safe large-scale modifications
- Headless batch scripts for codemod-style operations
- Verification strategies that catch errors before they hit production
The Plan-Then-Execute Pattern
Section titled “The Plan-Then-Execute Pattern”Never let Claude make 50 file changes without reviewing the plan first.
-
Scope the change
Find all files that import from 'moment'. List each file, the specific moment functions used,and the equivalent date-fns function. Output as a table. Do not make any changes yet. -
Review the plan Claude shows you a table of every file, every import, and the planned replacement. Review for edge cases.
-
Execute in batches
Good. Now migrate the files in src/utils/ first (there are 8 of them).After each file, run the tests in that directory to verify. -
Verify and continue
All tests pass. Continue with src/components/ (23 files). Same approach:migrate, test, report any failures.
Subagent-Based Parallel Processing
Section titled “Subagent-Based Parallel Processing”For large codebases, delegate batch work to subagents so each file group gets its own context window:
Migrate the moment.js imports to date-fns across the entire project. Use subagents toprocess each directory in parallel:
1. src/utils/ (8 files) -- delegate to a subagent2. src/components/ (23 files) -- delegate to a subagent3. src/api/ (12 files) -- delegate to a subagent4. src/services/ (15 files) -- delegate to a subagent
Each subagent should: migrate the imports, update the function calls, and run thetests in that directory. Report back with: files changed, tests passed/failed.This works because subagents have independent context windows, so they do not crowd out the main session with 50 files worth of diffs.
Headless Batch Scripts
Section titled “Headless Batch Scripts”For repeatable operations, use print mode to build automated scripts:
#!/bin/bash# migrate-moment.sh -- Run headless migration across directories
DIRS=("src/utils" "src/components" "src/api" "src/services")
for dir in "${DIRS[@]}"; do echo "Migrating $dir..." claude -p "Migrate all moment.js imports in $dir/ to date-fns. \ Update function calls to match the date-fns API. \ After migration, run: npx jest $dir/ --no-coverage" \ --max-turns 20 \ --dangerously-skip-permissions \ --output-format json > "results/$dir.json" 2>&1
echo "Completed $dir"done
echo "Migration complete. Review results in results/"Common Batch Operations
Section titled “Common Batch Operations”API Version Migration
Section titled “API Version Migration”We are deprecating /api/v1/ and all clients have been migrated to /api/v2/.Remove all v1 route handlers, their tests, and any middleware specific to v1.Keep shared middleware that both versions use.
Process:1. List all files in src/api/v1/2. For each v1 route, verify a v2 equivalent exists3. Remove v1 files and their tests4. Remove v1 entries from the router configuration5. Run the full test suite to verify nothing breaksRename Refactoring
Section titled “Rename Refactoring”Rename the UserService class to AccountService across the entire codebase.This includes:- The class definition and file name- All imports referencing UserService- All variable names that use userService or UserService- Test files and test descriptions- CLAUDE.md and documentation references
Use git mv for file renames so git tracks the history.Run the full test suite and TypeScript compiler after all changes.Adding Boilerplate to Multiple Files
Section titled “Adding Boilerplate to Multiple Files”Every API route in src/api/routes/ needs to have:1. An OpenAPI JSDoc comment block above the handler2. Input validation using the Zod schema pattern from src/api/routes/orders.ts3. Error handling wrapped in the asyncHandler utility
Process: Read src/api/routes/orders.ts as the reference implementation.Then apply the same patterns to all other route files that are missing them.List each file and what you added before proceeding.Verification Strategies
Section titled “Verification Strategies”Progressive Testing
Section titled “Progressive Testing”Run tests after each batch of changes, not at the end:
For each directory you migrate:1. Make the changes2. Run: npx jest [directory] --no-coverage3. If tests fail, fix the failures before moving to the next directory4. Report: directory name, files changed, tests passed, tests failedType Checking as Guard Rail
Section titled “Type Checking as Guard Rail”After making all changes, run: npx tsc --noEmitIf there are type errors, fix them. The TypeScript compiler is the source of truthfor whether imports and function signatures are correct.Git-Based Verification
Section titled “Git-Based Verification”After completing the migration:1. Run: git diff --stat to show all changed files2. Run: git diff to show the actual changes3. Verify there are no unintended modifications4. Run the full test suite5. If everything passes, create a commit with a descriptive messageWhen This Breaks
Section titled “When This Breaks”Claude modifies files it should not touch: Use constraints at the top of your prompt: “Only modify files in src/api/. Do not touch src/core/ or any configuration files.” For extra safety, use --disallowedTools "Edit(src/core/**)" to block edits to specific paths.
Batch operation runs out of context: Long batch operations fill the context window. Use subagents for parallel work, or split the operation into multiple sessions with /clear between batches.
Tests pass but behavior changes: Batch operations can introduce subtle behavior changes that tests do not catch. Always do a manual review of the git diff before committing batch changes.
Claude gets stuck in a loop: If Claude keeps fixing one file’s errors only to break another, stop the operation. The changes need a different approach — likely a plan that accounts for the dependency order between files.
What is Next
Section titled “What is Next”- Script Automation — Turn your batch patterns into reusable automation scripts
- Review Automation — Automate the review of batch-generated changes
- Large Codebase Tips — Tips for managing Claude Code in large codebases