A Claude Code plugin for detecting and eliminating code duplication using jscpd.
DRY = Don't Repeat Yourself
This was motivated by the observation that coding agents, including Claude Code, have a bias towards producing new code over reusing existing code or extracting common code. The resulting creeping code duplication weighs down AI-native codebases. This is a tool to make ongoing deduplication quick and easy from within Claude Code.
Because DRYwall detects code duplication using a deterministic toolchain (the awesome jscpd), this plugin is significantly more effective and cheaper in tokens than just telling an agent to find and refactor duplication.
Prerequisite: Node.js must be installed on your system (with node and npx binaries available to Claude Code).
Open Claude Code and add the marketplace, then install the plugin:
/plugin marketplace add nikhaldi/drywall
/plugin install drywall@drywall
To start refactoring duplicated code with manual supervision, run the scan skill within Claude Code:
/drywall:scan
If you just want Claude Code to take care of everything, prompt it with something like this after installing the plugin (it will launch a dedicated subagent):
Deduplicate code in this codebase
Create a .drywallrc.json in your project root to set defaults. Values correspond to jscpd CLI options, except for the DRYwall-specific ones listed below:
{
"minTokens": 50,
"minLines": 5,
"ignore": ["**/node_modules/**", "**/dist/**", "**/*.generated.*"],
"respectGitignore": true,
"jscpdVersion": "4.0.8"
}The configuration options specific to DRYwall are:
respectGitignore—trueby default. Passes--gitignoreto jscpd so that files excluded by.gitignoreare automatically skipped (but: jscpd's implementation of this is buggy - some lines from your gitignore may not work as expected). Set tofalseto disable.jscpdVersion— Pin the jscpd version used vianpx. Defaults to4.0.8if not set.maxDuplicates— Maximum number of duplicate pairs to return, ranked by impact. Defaults to20. (This needs to be restricted to avoid blowing past context limits right away in large codebases.)maxFragmentLength— Maximum character length of each code fragment before truncation. Defaults to500.
If you want to exclude some code from all of DRYwall's refactoring, you can use jscpd:ignore-start and jscpd:ignore-end markers in the code. JavaScript example:
/* jscpd:ignore-start */
import lodash from 'lodash';
import React from 'react';
import {User} from './models';
import {UserService} from './services';
/* jscpd:ignore-end */
Scans the current codebase for duplication and shows a ranked report of suggested deduplication refactorings. This is the simplest way to tackle some refactorings with manual control.
Invoke within a Claude Code session with:
/drywall:scan
/drywall:scan --min-tokens=100 --min-lines=10
Arguments are passed through as is to jscpd. These arguments are additive (or override) defaults configured in .drywallrc.json (see Configuration above).
An autonomous agent that detects duplication and refactors it end-to-end — extracting shared utilities, updating call sites, and verifying the changes. Claude delegates to this agent for large deduplication tasks.
Automatically invoked by Claude Code when your task involves refactoring or deduplication. Runs jscpd under the hood and returns structured results.
Parameters:
path— directory to scan (default:.)options— object of jscpd options passed as CLI flags. Keys are camelCase and converted to--kebab-caseflags (e.g.,{"minTokens": 30, "minLines": 5, "ignore": ["**/test/**"], "format": ["javascript", "typescript"], "threshold": 10})maxDuplicates— maximum number of duplicate pairs to return, ranked by impact (default:20)maxFragmentLength— maximum character length of each code fragment before truncation (default:500)
This project is licensed under the MIT License.