Migrating from good-fences
good-fences segments a TypeScript project into areas and controls what each can import, using fence.json files. rev-dep expresses the same boundaries as central module boundaries and restricted imports checks.
Why migrate​
- Speed. rev-dep is Go-based and runs in a single parallel pass - faster on large codebases.
- One config, more checks. good-fences only does boundaries. rev-dep enforces boundaries and detects circular imports, unused exports, unused/missing dependencies, and more.
What carries over, what changes​
- Covered well: controlling which areas may import which, and which npm dependencies an area may use.
- Different model. good-fences uses tags and per-directory
fence.jsonfiles; rev-dep uses path patterns in one central config. You express the same intent ("UI may not import API") as a path-pattern boundary instead of tagging directories. - No per-directory files. Boundaries live in
rev-dep.config.jsonc, not scatteredfence.jsonfiles - simpler to review, but a different workflow.
Feature mapping​
good-fences (fence.json) | rev-dep |
|---|---|
tags + imports (which tags may be imported) | moduleBoundaries (pattern + allow / deny) |
exports (accessibleTo) - who may import this area | moduleBoundaries / restrictedImportsDetection |
dependencies (allowed npm packages) | restrictedImportsDetection (denyModules) |
| - | circular, unused exports, unused/missing dependencies, conventions |
Translating your config​
A fence.json in src/ui that may only be imported by app and forbids importing api:
{
"tags": ["ui"],
"exports": [{ "modules": "*", "accessibleTo": ["app"] }],
"imports": ["ui", "shared"]
}
becomes a path-pattern boundary in rev-dep.config.jsonc:
{
"rules": [
{
"path": ".",
"moduleBoundaries": [
{
"name": "ui-imports",
"pattern": "src/ui/**",
"allow": ["src/ui/**", "src/shared/**"]
},
{
"name": "only-app-imports-ui",
"pattern": "src/!(app|ui)/**",
"deny": ["src/ui/**"]
}
]
}
]
}
To restrict which npm packages an area may import (good-fences dependencies), use restrictedImportsDetection with denyModules.
Running it​
# good-fences
npx gf
# rev-dep
rev-dep config run
Next steps​
- Module boundaries - the core mapping for fences.
- Monorepo integration guide.