working-effectively-with-legacy-code

Apply Feathers's dependency-breaking techniques and characterization tests to change untested legacy code safely.

1|Updated May 21, 2026
One-click install
npx skills add https://github.com/vnovakovits/claude-skills --skill working-effectively-with-legacy-code-vnovakovits
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: working-effectively-with-legacy-code
Source: https://github.com/vnovakovits/claude-skills/tree/main/plugins/engineering-practices/skills/working-effectively-with-legacy-code
Command: npx skills add https://github.com/vnovakovits/claude-skills --skill working-effectively-with-legacy-code-vnovakovits

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Changing code without tests is risky: you need tests to change safely, but the code often must change before it can be tested. This Skill breaks that cycle by guiding you through Michael Feathers's Legacy Code Change Algorithm — finding seams, breaking dependencies, and writing characterization tests before modifying behavior. ## Core Features & Use Cases - Dependency-Breaking Catalog: Apply techniques like Sprout Method, Extract Interface, Subclass and Override, Wrap Method, and Break Out Method Object to introduce testable seams. - Characterization Testing: Capture what code currently does (including bugs) so you can refactor without silently changing behavior. - Effect Sketches & Pinch Points: Map which variables and methods a change affects to decide where tests belong. - Use Case: You inherit a 500-line method that writes directly to a database and has zero tests. Use this Skill to extract the database call behind a seam, subclass and override it in tests, write characterization tests for current outputs, and only then fix the reported bug. ## Quick Start Ask Claude to help you safely modify a specific untested method or class, for example by requesting characterization tests and dependency-breaking refactorings before changing its behavior.

Frequently Asked Questions about working-effectively-with-legacy-code

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I add tests to legacy code that has none?▼

Write characterization tests that capture what the code currently does, not what it should do. First find a seam where behavior can be altered, break dependencies blocking the test point, then assert observed outputs so refactoring becomes safe.

What is a seam in legacy code refactoring?▼

A seam is a place where you can alter behavior without editing the code at that point. Object seams use polymorphism or dependency injection, link seams swap libraries at link time, and preprocessor seams use conditional compilation in C/C++.

How do I break dependencies on a database in unit tests?▼

Use Subclass and Override Method to replace the awkward database call with canned data in test code, or Extract Interface so a fake can be substituted. Parameterize Constructor also works by injecting the collaborator instead of constructing it.

Should I rewrite legacy code or refactor it incrementally?▼

Incremental refactoring under tests is preferred because rewrites underestimate the implicit knowledge encoded in old systems. The Strangler Fig pattern routes new behavior to new code behind a façade and migrates old behavior slice by slice.

What is the difference between characterization tests and unit tests?▼

Characterization tests document current behavior, including bugs, by asserting observed outputs. Traditional unit tests assert intended behavior. Characterization tests act as a safety net before changing code you do not yet understand.