@promise-inc/fs-guard
v0.1.1
Published
Validate project folder and file structure. Enforce conventions in CI and locally.
Maintainers
Readme
@promise-inc/fs-guard
Validate project folder and file structure. Enforce conventions in CI and locally.
Why?
Teams lose consistency over time:
- Random files appearing in
src/ - Missing required entry points (
index.tsx,routes.ts) - Files that don't follow naming conventions (
useFetch.jsxinstead ofuseFetch.ts) - Nested folders going too deep
fs-guard catches structural violations before they reach your codebase.
Install
npm install @promise-inc/fs-guard --save-devUsage
# Validate using config file
npx fs-guard
# Validate using a built-in preset
npx fs-guard --preset nestjs
# List all available presets
npx fs-guard --listAs a Git Hook
{
"husky": {
"hooks": {
"pre-commit": "fs-guard"
}
}
}Or with lint-staged:
{
"lint-staged": {
"*": "fs-guard"
}
}Presets
Built-in presets for popular stacks — use directly or extend with custom rules.
| Category | Presets |
|----------|--------|
| Backend | nestjs, node-ts, node-js |
| Frontend | react-ts, react-js, nextjs, vite-react |
| Mobile | react-native-ts, react-native-js, expo |
# Use a preset directly
npx fs-guard --preset nestjsExtend a preset
{
"preset": "nextjs",
"rules": {
"app/dashboard": {
"required": ["page.tsx", "layout.tsx"]
}
}
}Preset rules are merged with your custom rules. Your rules take priority on conflicts.
See the
examples/folder for a config file per stack.
Configuration
Create fs-guard.config.json, fs-guard.config.ts, fs-guard.config.js, or add an fs-guard field to package.json:
export default {
root: "src",
rules: {
"pages": ["index.tsx", "*"],
"components": "*",
"services": ["*.ts"],
"hooks": ["use*.ts"],
},
ignore: ["node_modules", "dist", ".git"],
};Rule Syntax
| Syntax | Meaning | Example |
|--------|---------|---------|
| "*" | Directory must exist, any files allowed | "components": "*" |
| ["file.ts"] | Specific file must exist | "pages": ["index.tsx"] |
| ["*.ts"] | All files must match pattern | "services": ["*.ts"] |
| ["index.tsx", "*"] | Required file + allow others | "pages": ["index.tsx", "*"] |
| ["use*.ts"] | Files must match naming convention | "hooks": ["use*.ts"] |
Config Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| root | string | — | Root directory to validate |
| rules | Record<string, RuleValue> | — | Validation rules per directory |
| ignore | string[] | ["node_modules", "dist", ".git"] | Directories to skip |
| preset | string | — | Built-in preset to extend |
Advanced Rules (object syntax)
export default {
root: "src",
rules: {
"hooks": {
required: ["index.ts"],
pattern: "use*.ts",
maxDepth: 1,
},
},
};| Field | Type | Description |
|-------|------|-------------|
| required | string[] | Files that must exist |
| pattern | string | Naming pattern for all files |
| maxDepth | number | Max nesting depth allowed |
Programmatic API
import { fsGuard, loadConfig } from "@promise-inc/fs-guard";
const config = await loadConfig(process.cwd());
const result = await fsGuard(config);
console.log(result.passed); // true | false
console.log(result.violations); // Violation[]
console.log(result.checked); // string[]Exit Codes
| Code | Meaning |
|------|---------|
| 0 | All rules passed |
| 1 | Violations found |
| 2 | Internal error (missing config, etc.) |
Design Principles
- Zero dependencies — Only Node.js built-ins (
fs/promises,path) - Deterministic — Same structure always produces same output
- CI-friendly — Exit codes, no interactive prompts
- Fast — Direct filesystem checks, no AST parsing
- Simple — Solve one problem well
How to report bugs
To report a bug, please first read our guide on opening issues.
How to contribute code
To open a pull request, please first read our guide on opening pull requests, which outlines our process for RFCs and pull requests.
Also by Promise Inc.
| Package | Description |
|---------|-------------|
| @promise-inc/ai-guard | Detect AI-generated code patterns |
| @promise-inc/ps-guard | Lighthouse-based performance guard |
| @promise-inc/devlog | Logger with automatic context (file + line) |
| @promise-inc/ui-states | Auto-generated skeleton loading states |
| @promise-inc/dev-reel | Animated SVG previews for READMEs |
Developed by Promise Inc.
License
MIT © Promise Inc.
