Preflight Manager
A distributable preflight validation system that supports:
- Core checks bundled with the package
- App-specific checks discovered from
scripts/active/preflights/
- Configuration via
preflight.config.ts
- Category-based filtering
- Parallel execution
- Beautiful progress reporting
Table of Contents
Installation
npm install @empline/preflight
pnpm add @empline/preflight
Quick Start
npx preflight
npx preflight security
npx preflight security database
npx preflight --quick
npx preflight --parallel
npx preflight --verbose
Applying to an Existing App
Follow these steps to add preflight checks to an existing repository:
Step 1: Install the Package
cd C:\apps\website-webanto
pnpm add @empline/preflight
Step 2: Create Configuration File
Copy the template or create preflight.config.ts in your app root:
cp node_modules/@empline/preflight/templates/preflight.config.ts.template preflight.config.ts
Or create manually:
import type { AppConfig } from "@empline/preflight";
const config: AppConfig = {
appName: "website-webanto",
categories: ["security", "typescript", "runtime", "ui"],
excludeCategories: ["business"],
excludeChecks: [],
pluginDir: "scripts/active/preflights",
};
export default config;
Step 3: Create App-Specific Checks Directory
mkdir -p scripts/active/preflights
Step 4: Add to Build/CI Pipeline
{
"scripts": {
"preflight": "preflight",
"preflight:quick": "preflight --quick",
"build": "preflight && next build"
}
}
Step 5: (Optional) Add App-Specific Checks
Create checks specific to your app in scripts/active/preflights/:
import { PreflightCheckResult, emoji } from "@empline/preflight";
export const id = "business/my-validation";
export const name = "My Custom Validation";
export const category = "business";
export const blocking = true;
export const description = "Validates my app-specific rules";
export async function run(): Promise<PreflightCheckResult> {
return { passed: true, findings: [], duration: 0 };
}
Configuration
Full configuration options for preflight.config.ts:
import type { AppConfig } from "@empline/preflight";
const config: AppConfig = {
appName: "my-app",
categories: ["security", "typescript", "runtime"],
excludeCategories: ["ui"],
excludeChecks: ["business/price-calculation-validation"],
includeChecks: [],
pluginDir: "scripts/active/preflights",
customCategories: {
"my-domain": {
pattern: "MyPattern|OtherPattern",
description: "Domain-specific checks",
},
},
respectCiOnly: true,
defaultTimeout: 30000,
concurrency: 4,
output: {
json: ".preflight/report.json",
sarif: ".preflight/report.sarif",
},
};
export default config;
Writing Custom Checks
Create a new check in scripts/active/preflights/:
import {
PreflightCheckResult,
PreflightFinding,
STANDARD_EXCLUDES,
emoji,
writeFindings,
fileCache,
} from "@empline/preflight";
export const id = "business/my-check";
export const name = "My Custom Check";
export const category = "business";
export const blocking = true;
export const description = "Validates something important";
export const tags = ["custom", "validation"];
export async function run(): Promise<PreflightCheckResult> {
const startTime = Date.now();
const findings: PreflightFinding[] = [];
const files = await fileCache.getCodeFiles();
for (const file of files) {
}
return {
passed: findings.filter(f => f.level === "error").length === 0,
findings,
duration: Date.now() - startTime,
};
}
Built-in Preflight Checks
The package ships with 449 preflight checks organized into 42 categories:
| ai | 3 | AI/ML code quality and recognition pipeline validation |
| api | 7 | API completeness, contracts, pagination, response consistency |
| architecture | 7 | Component architecture, page consistency, orphaned pages |
| auth | 7 | Authentication, session security, role validation |
| business | 12 | Business invariants, pricing, inventory, order validation |
| code-hygiene | 15 | Console logs, dead code, TODO tracking, comment hygiene |
| code-quality | 7 | TypeScript safety, magic numbers, duplicate logic |
| config | 1 | Configuration validation |
| css | 2 | Dead CSS detection, sticky header validation |
| database | 18 | Prisma schema, migrations, seed validation, query patterns |
| data-integrity | 5 | Cart integrity, product flow, store data validation |
| dependencies | 3 | Dependency health, deprecated packages |
| deployment | 6 | Production config, environment validation, rollback safety |
| drift-prevention | 9 | Breaking changes, consistency patterns, performance regression |
| e2e | 10 | E2E test quality, performance baselines, resource monitoring |
| email | 3 | Email template validation and verification |
| environment | 1 | Environment variable validation |
| framework | 2 | Framework compatibility, Turbopack enforcement |
| governance | 5 | Codeowners, naming conventions, route naming |
| image | 2 | Card edge protection, orientation validation |
| integrations | 2 | Platform feed integrity, integration validation |
| nextjs | 7 | Next.js routes, metadata, image optimization |
| observability | 1 | Centralized logging validation |
| organization | 12 | File organization, API routes, script organization |
| payments | 2 | Stripe/PayPal webhook validation (auto-detect) |
| performance | 6 | Bundle optimization, Core Web Vitals, runtime regression |
| prisma | 1 | Prisma 7 compatibility |
| quality | 13 | Lint, syntax, unused imports, file validation |
| react | 5 | React best practices, error boundaries, memory leaks |
| runtime | 11 | Client env usage, JSON safety, Tailwind runtime |
| security | 15 | CSRF, env leakage, injection prevention, rate limiting |
| seo | 1 | Missing metadata detection |
| tailwind | 1 | Tailwind 4 compatibility |
| tanstack | 1 | TanStack Query compatibility |
| testing | 14 | E2E best practices, test coverage, flakiness detection |
| ui | 54 | Spacing, accessibility, component patterns, dark mode |
| zod | 1 | Zod schema validation |
Highlighted Checks
Security:
security/env-value-leakage - Detects secrets hardcoded outside .env files
security/csrf-protection - Validates CSRF protection on forms
security/sql-injection-prevention - Scans for SQL injection vulnerabilities
Business:
business/price-calculation-validation - Ensures Decimal.js for monetary calculations
business/inventory-atomicity-validation - Validates inventory operations
business/order-state-machine-validation - Validates order state transitions
Payments:
payments/stripe-webhook-validation - Validates Stripe webhook signatures
payments/paypal-webhook-validation - Validates PayPal webhook/IPN signatures
Database:
database/prisma-schema-syntax - Validates Prisma schema before build
database/migration-safety - Checks for safe migration patterns
database/seed-coverage-validation - Ensures seed data completeness
UI:
ui/accessibility-critical - Critical accessibility checks
ui/spacing-check - Validates consistent spacing patterns
ui/tailwind-consistency - Ensures Tailwind usage patterns
CI Integration
GitHub Actions
name: Preflight Checks
on: [push, pull_request]
jobs:
preflight:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'
- run: pnpm install
- run: pnpm preflight --parallel
env:
CI: true
Vercel
Add to your build command in package.json:
{
"scripts": {
"build": "preflight && next build"
}
}
Or in vercel.json:
{
"buildCommand": "pnpm preflight && pnpm build"
}
Automatic Updates with Dependabot/Renovate
This package is designed to be automatically updated across all your apps using Dependabot or Renovate.
Using Dependabot
Create .github/dependabot.yml in each app repository:
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "daily"
groups:
preflight:
patterns:
- "@empline/preflight"
commit-message:
prefix: "chore(deps)"
Using Renovate
Create renovate.json in each app repository:
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended"],
"packageRules": [
{
"matchPackageNames": ["@empline/preflight"],
"automerge": true,
"automergeType": "pr",
"schedule": ["every weekday"]
}
]
}
How Updates Flow
- You update this package (add new checks, fix bugs, add features)
- Publish to npm with a new version
- Dependabot/Renovate detects the new version in each app
- PRs are auto-created in each app repository
- CI runs preflight checks on the PR
- Auto-merge (if configured) merges the update
Contributing & Making Enhancements
Repository Structure
preflight-manager/
├── src/
│ ├── core/ # Types, categories, config loader
│ ├── utils/ # Console, findings, progress, plugin loader
│ ├── shared/ # Glob patterns, file cache, concurrency
│ ├── checks/ # Core checks (shipped with package)
│ ├── runner.ts # Main orchestrator
│ └── index.ts # Package exports
├── templates/
│ ├── preflight.config.ts.template # Config template for apps
│ ├── new-check.ts.template # Generic check template
│ └── domain-specific/
│ └── trading-card-system/ # Domain-specific check templates
└── package.json
Adding a New Core Check
- Create the check file in
src/checks/<category>/:
export const id = "security/new-check";
export const name = "New Security Check";
export const category = "security";
export const blocking = true;
export const description = "Checks for something important";
export async function run(): Promise<PreflightCheckResult> {
}
- The check is automatically discovered by the runner.
Adding New Utilities
- Add to the appropriate file in
src/utils/ or src/shared/
- Export from
src/index.ts
- Update the README if it's a public API
Publishing Updates
npm version patch
npm run build
npm publish
git push --tags
Versioning Guidelines
- Patch (1.0.x): Bug fixes, non-breaking check improvements
- Minor (1.x.0): New checks, new utilities, new features
- Major (x.0.0): Breaking changes to config format or API
Testing Changes Locally
Before publishing, test in a consuming app:
npm run build
npm link
npm link @empline/preflight
npx preflight
Core Exports
The package exports utilities for use in your checks:
import {
PreflightCheckResult,
PreflightFinding,
AppConfig,
STANDARD_EXCLUDES,
CODE_FILE_PATTERN,
PRODUCTION_CODE_EXCLUDES,
fileCache,
emoji,
createProgressBar,
createDivider,
writeFindings,
createFinding,
createUniversalProgressReporter,
loadAppConfig,
shouldRunCheck,
} from "@empline/preflight";
License
MIT