vite-plugin-app-boundaries
v0.1.0
Published
Enforce architectural boundaries between app folders in Vite
Readme
vite-plugin-app-boundaries
Enforce strict architectural boundaries between application folders in Vite.
This plugin prevents one app (e.g. Front) from importing code from
another app (e.g. Pro) at build time and dev time, not just via
linting.
If a boundary is violated, Vite errors immediately.
Why this exists
Lint rules are easy to bypass. Aliases hide real paths. Large multi-front apps rot over time.
This plugin makes architecture non-negotiable by enforcing rules directly in Vite's module resolution graph.
Features
- ✅ Enforce boundaries between any number of apps
- ✅ Errors in dev AND build
- ✅ Alias-aware (uses Vite's resolver)
- ✅ Configurable allowlists
- ✅ Zero runtime cost
- ✅ Works with Vite 5 / 6 / 7
Example use case
resources/js/Apps/
├── Front/
├── Pro/
└── Shared/Rules:
- ❌
Frontcannot import fromPro - ❌
Procannot import fromFront - ✅ Both can import from
Shared
Installation
npm install -D vite-plugin-app-boundariesor
pnpm add -D vite-plugin-app-boundariesBasic usage
vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { enforceAppBoundaries } from "vite-plugin-app-boundaries";
export default defineConfig({
plugins: [
enforceAppBoundaries({
root: "resources/js/Apps",
apps: {
Front: {
path: "Front",
allowImportsFrom: ["Shared"],
},
Pro: {
path: "Pro",
allowImportsFrom: ["Shared"],
},
Shared: {
path: "Shared",
},
},
}),
react(),
],
});What happens on violation
// Apps/Front/pages/welcome.tsx
import Editor from "@/Apps/Pro/components/editorjs";⬇️
🚫 App boundary violation
Importer:
.../Apps/Front/pages/welcome.tsx
(app: Front)
Imported:
.../Apps/Pro/components/editorjs.tsx
(app: Pro)
Allowed imports for Front:
SharedVite stops immediately.
Configuration reference
root
Root directory that contains all apps.
root: "resources/js/Apps"apps
Each app has:
path: folder name underrootallowImportsFrom: optional list of app names it may import from
apps: {
Front: {
path: "Front",
allowImportsFrom: ["Shared"],
},
Admin: {
path: "Admin",
allowImportsFrom: ["Shared", "Pro"],
},
}debug (optional)
Enable verbose logging to see exactly how Vite resolves imports.
enforceAppBoundaries({
debug: true,
...
});Useful when diagnosing aliases or unexpected resolution.
ESLint mirror rules (recommended)
This plugin enforces boundaries at build time.
For editor errors, mirror the rules using ESLint.
Install
npm install -D eslint-plugin-boundariesExample .eslintrc.cjs
module.exports = {
plugins: ["boundaries"],
settings: {
"boundaries/include": ["resources/js/**/*"],
"boundaries/elements": [
{ type: "front", pattern: "resources/js/Apps/Front/**" },
{ type: "pro", pattern: "resources/js/Apps/Pro/**" },
{ type: "shared", pattern: "resources/js/Apps/Shared/**" },
],
},
rules: {
"boundaries/element-types": [
"error",
{
default: "disallow",
rules: [
{ from: "front", allow: ["shared"] },
{ from: "pro", allow: ["shared"] },
{ from: "shared", allow: ["shared"] },
],
},
],
},
};What this plugin does NOT do
- ❌ It does not replace ESLint
- ❌ It does not rewrite imports
- ❌ It does not enforce runtime isolation
Recommended setup:
- This plugin → build-time enforcement
- ESLint boundaries rules → editor feedback
License
MIT
