TypeScript import-boundary linter. Declare layers, say which layers may import which, and fail CI when someone reaches across the fence.
npm install -g @magnexis/modfence
npx @magnexis/modfence --helpRequires Node.js 20+.
eslint-plugin-import can ban paths, but teams usually want a layer story: UI may talk to domain, domain must not talk to infra, infra may implement domain. Cycles still sneak in. modfence is a dedicated CLI for that policy — including why (explain a file) and graph (Mermaid of observed layer edges).
npx @magnexis/modfence init
npx @magnexis/modfence checkmodfence.json:
{
"root": ".",
"forbidCycles": true,
"layers": [
{ "name": "ui", "glob": "src/ui/**" },
{ "name": "domain", "glob": "src/domain/**" },
{ "name": "infra", "glob": "src/infra/**" }
],
"allow": [
{ "from": "ui", "to": ["domain"] },
{ "from": "domain", "to": [] },
{ "from": "infra", "to": ["domain"] }
]
}Same-layer imports are always allowed. External packages (react, node:fs) are ignored.
modfence init Write starter modfence.json
modfence check [--json] Exit 1 on layer or cycle violations
modfence why <file> Layer + outbound relative imports
modfence graph Mermaid flowchart of layer → layer edges
CI:
- run: npx @magnexis/modfence check --jsonimport { checkLayers, collectEdges, defaultConfig } from "@magnexis/modfence";
const config = defaultConfig();
const edges = await collectEdges({ ...config, root: process.cwd() });
const violations = checkLayers(config, edges);git clone https://github.com/theworker02/modfence.git
cd modfence
npm install
npm test
npm run buildMIT. Sponsor via GitHub or thanks.dev.
