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-lintscope.
# 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