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