ts-boundaries-cli
v0.3.0
Published
A TypeScript architectural boundary enforcement tool that analyzes import statements to prevent unwanted dependencies between different parts of your codebase.
Maintainers
Readme
ts-boundaries-cli
A TypeScript architectural boundary enforcement tool that analyzes import statements to prevent unwanted dependencies between different parts of your codebase.
Installation
pnpm install ts-boundaries-cliOr use directly with npx et al.:
pnpm dlx ts-boundaries-cli init
pnpm dpx ts-boundaries-cli checkQuick Start
- Initialize configuration:
ts-boundaries initThis creates a ts-boundaries.config.json file with an empty rules array.
- Add rules to your config:
{
"$schema": "https://raw.githubusercontent.com/maxwihlborg/ts-boundaries-cli/refs/heads/main/schema.json",
"rules": [
{
"from": ["./src/!(shared|server)/**"],
"disallow": ["./src/server/**"],
"message": "Client code cannot import from server code"
},
{
"from": ["./src/shared/**"],
"disallow": ["./src/!(shared)/**"],
"message": "Shared code can only import shared code"
},
{
"from": ["./src/server/**"],
"disallow": ["./src/!(shared|server)/**"],
"message": "Server code cannot import from client code"
}
]
}- Check your codebase:
ts-boundaries checkConfiguration
Basic Rules
Rules define which imports are forbidden from specific locations:
{
"rules": [
{
"from": ["./src/components/**"],
"disallow": ["./src/utils/internal/**"],
"message": "Components should not import internal utilities"
}
]
}Path Aliases
Configure path aliases for import resolution:
{
"resolve": {
"alias": {
"~": "./src",
"@components": "./src/components",
"@utils": "./src/utils"
}
}
}This allows the tool to properly resolve imports like ~/components/Button to ./src/components/Button.
Ignoring Specific Imports
You can opt-out of boundary checking for specific imports using the // ts-boundaries-ignore comment:
// ts-boundaries-ignore
import { ServerAPI } from "../server/api"; // This import will be ignored
import { ClientUtils } from "../client/utils"; // This import will still be checked
// ts-boundaries-ignore
const serverModule = await import("../server/auth"); // Dynamic import ignored tooThe comment must appear directly before the import statement and works with both static imports and dynamic import() calls.
Commands
ts-boundaries init
Creates a new configuration file with an empty rules array.
ts-boundaries check
Analyzes your TypeScript files and reports boundary violations.
Options:
--vimgrep: Output errors in vimgrep format
Output Formats
Default Format
Human-readable output with detailed error information:
./src/client/app.ts:5:10
Client code cannot import from server code
Import: src/server/api
[ERROR] Found 1 fence violation(s)Vimgrep Format
Machine-readable format compatible with vim quickfix and other tools:
ts-boundaries check --vimgrepOutput:
/Users/user/projects/package/src/client/app.ts:5:10: Client code cannot import from server codeUse Cases
Layered Architecture
Enforce architectural layers (presentation, business, data):
{
"rules": [
{
"from": ["./src/presentation/**"],
"disallow": ["./src/data/**"],
"message": "Presentation layer cannot directly access data layer"
},
{
"from": ["./src/data/**"],
"disallow": ["./src/presentation/**"],
"message": "Data layer cannot depend on presentation layer"
}
]
}Feature-Based Boundaries
Prevent features from importing from each other:
{
"rules": [
{
"from": ["./src/features/auth/**"],
"disallow": ["./src/features/billing/**"],
"message": "Auth feature cannot import from billing feature"
},
{
"from": ["./src/features/billing/**"],
"disallow": ["./src/features/auth/**"],
"message": "Billing feature cannot import from auth feature"
}
]
}Integration
CI/CD
Add to your build process:
# GitHub Actions
- name: Check boundaries
run: pnpm dlx ts-boundaries-cli check# npm script
{
"scripts": {
"lint:boundaries": "ts-boundaries check"
}
}Vim/Neovim
Use vimgrep format for quickfix integration:
:cexpr system('pnpm dlx ts-boundaries-cli check --vimgrep')License
MIT
