dry-lint
is a plugin‑driven framework for detecting duplicate or overlapping declarations across any source format — TypeScript, JSON, SQL, Terraform, OpenAPI, … you name it.
@dry-lint/dry-lint
).npx dry
).Performance‑first: incremental file caching, parallel parsing, and optional fuzzy grouping.
Package | npm | What it extracts |
---|---|---|
core | @dry-lint/dry-lint |
Engine & public API (replaces deprecated @dry-lint/core ) |
cli | @dry-lint/cli |
Command‑line interface & Ink UI |
asyncapi | @dry-lint/asyncapi |
AsyncAPI operations & schemas |
avro | @dry-lint/avro |
Avro records / enums / unions |
cloudformation | @dry-lint/cloudformation |
CloudFormation stacks |
css | @dry-lint/css |
CSS selectors & variables |
graphql | @dry-lint/graphql |
GraphQL types & operations |
json | @dry-lint/json |
Generic JSON shapes |
k8s | @dry-lint/k8s |
Kubernetes manifests |
mongoose | @dry-lint/mongoose |
Mongoose models |
openapi | @dry-lint/openapi |
OpenAPI operations & schemas |
prisma | @dry-lint/prisma |
Prisma models |
prop‑types | @dry-lint/prop-types |
React PropTypes |
proto | @dry-lint/proto |
Protocol‑Buffers IDL |
sql | @dry-lint/sql |
SQL DDL (tables, indexes) |
terraform | @dry-lint/terraform |
Terraform HCL |
thrift | @dry-lint/thrift |
Thrift IDL |
typeorm | @dry-lint/typeorm |
TypeORM entities |
typescript | @dry-lint/typescript |
TS interfaces / types / enums |
xsd | @dry-lint/xsd |
XML Schema |
zod | @dry-lint/zod |
Zod validators |
All extractor packages live under
packages/
and are published under the@dry-lint
scope.
# 1 – install CLI + the plugins you need
bun add -D @dry-lint/cli \
@dry-lint/typescript \
@dry-lint/zod
# 2 – tell dry‑lint which plugins to load
echo '{ "plugins": ["@dry-lint/typescript", "@dry-lint/zod"] }' > .drylintrc.json
# 3 – run it
npx dry src/ # or just `npx dry` for the current folder
Flag | Description |
---|---|
-t, --threshold |
Similarity threshold (0‑1, default 1 ) |
--ignore |
Glob patterns to exclude |
--json / --sarif |
Machine‑readable reports |
--fix |
Generate alias stubs for exact matches |
--no-cache |
Disable file‑level caching |
--ui |
Launch interactive Ink UI |
If no .drylintrc
is found, the CLI auto‑discovers every installed @dry-lint/*
package (excluding dry-lint
and cli
).
import { registerExtractor, findDuplicates, Declaration } from '@dry-lint/dry-lint';
registerExtractor((filePath, text): Declaration[] => {
// produce your own declarations here
return [];
});
const groups = await findDuplicates(['src/**/*.ts']);
console.log(groups);
bun add -D @dry-lint/dry-lint
in a new package under packages/
.
Add it to peerDependencies
and devDependencies
:
{
"peerDependencies": { "@dry-lint/dry-lint": "^1" },
"devDependencies": { "@dry-lint/dry-lint": "^1" },
}
Implement registerExtractor
in your entry‑file.
Publish as @dry-lint/your‑plugin
. Users just add it to .drylintrc.json
.
import { registerExtractor, Declaration } from '@dry-lint/dry-lint';
registerExtractor((filePath, source): Declaration[] => {
// analyse `source` → return Declaration[]
return [];
});
We use Turborepo for fast, cached pipelines.
bun run build # builds every package (cache‑aware)
bun run test # runs Vitest across the monorepo
packages/
.MIT © dry‑lint