This document explains the dependency validation system that enforces clean architecture rules.
The project uses a custom validation script (scripts/validate-dependencies.ts) that runs as part of the linting process to ensure all packages follow the dependency architecture rules.
The linter enforces these strict dependency rules:
| Package Type | Can Depend On |
|---|---|
| Common plugins | Common plugins ONLY |
| Frontend plugins | Frontend plugins OR common plugins |
| Backend plugins | Backend plugins OR common plugins |
| Core packages | Common packages (minimal dependencies) |
The script automatically detects package types based on naming conventions:
-common or named @checkstack/common-frontend, -frontend-plugin, or starting with @checkstack/frontend or @checkstack/ui-backend, -backend-plugin, or starting with @checkstack/backend@checkstack/common package@checkstack/* packages (always allowed)core/* and plugins/* directoriespackage.json filedependencies and peerDependenciesThe dependency validation runs automatically with the regular linting:
bun run lint
This command runs:
bun run lint:code - ESLint for code qualitybun run lint:deps - Dependency architecture validationYou can run just the dependency validation:
bun run lint:deps
Or directly:
bun run scripts/validate-dependencies.ts
{
"name": "@checkstack/catalog-common",
"dependencies": {
"@checkstack/backend-api": "workspace:*" // ❌ VIOLATION
}
}
Error:
❌ Dependency Architecture Violations Found:
@checkstack/catalog-common
→ depends on @checkstack/backend-api
→ common packages cannot depend on backend packages
Fix: Depend on @checkstack/common instead:
{
"name": "@checkstack/catalog-common",
"dependencies": {
"@checkstack/common": "workspace:*" // ✅ OK
}
}
{
"name": "@checkstack/catalog-frontend-plugin",
"dependencies": {
"@checkstack/catalog-backend-plugin": "workspace:*" // ❌ VIOLATION
}
}
Error:
❌ Dependency Architecture Violations Found:
@checkstack/catalog-frontend-plugin
→ depends on @checkstack/catalog-backend-plugin
→ frontend packages cannot depend on backend packages
Fix: Depend on common package instead:
{
"name": "@checkstack/catalog-frontend-plugin",
"dependencies": {
"@checkstack/catalog-common": "workspace:*" // ✅ OK
}
}
{
"name": "@checkstack/catalog-common",
"dependencies": {
"@checkstack/common": "workspace:*"
}
}
{
"name": "@checkstack/catalog-frontend-plugin",
"dependencies": {
"@checkstack/frontend-api": "workspace:*",
"@checkstack/catalog-common": "workspace:*",
"@checkstack/ui": "workspace:*"
}
}
{
"name": "@checkstack/catalog-backend-plugin",
"dependencies": {
"@checkstack/backend-api": "workspace:*",
"@checkstack/catalog-common": "workspace:*"
}
}
All packages can depend on external (non-@checkstack/*) packages:
{
"name": "@checkstack/catalog-common",
"dependencies": {
"zod": "^4.2.1",
"react": "^18.2.0"
}
}
The lint check runs in CI/CD pipelines. If dependency violations are detected, the build will fail, preventing broken architectures from being merged.
If you have a package that doesn’t follow naming conventions, it will be treated as “unknown” and won’t be validated. To fix this:
getPackageType() in scripts/validate-dependencies.ts to recognize your packageTo add support for new package types (e.g., *-node, *-react):
PackageType union in the scriptgetPackageType() to recognize the patternisDependencyAllowed()