Skip to main content

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​

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.json files; 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 scattered fence.json files - 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 areamoduleBoundaries / 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​