npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@onezlinks/architecture-audit

v0.2.5

Published

> Config-driven architecture convention checks for TypeScript and React projects.

Readme

Architecture Audit CLI

Config-driven architecture convention checks for TypeScript and React projects.

@onezlinks/architecture-audit is a reusable command-line tool for enforcing architecture conventions that are difficult to express with TypeScript or ESLint alone. It checks how files, directories, barrels, hooks, and component exports are organized, while keeping project-specific policy in configuration instead of hardcoded rule logic.

Why use it

Large React codebases often drift in ways that normal linting does not catch:

  • component directories without public barrels
  • component implementations hidden inside index.tsx
  • child components exported as defaults instead of named exports
  • hook files that export non-hook runtime symbols
  • duplicate component names inside the same owner directory
  • broad eslint-disable comments without a clear reason

This package turns those conventions into repeatable local and CI checks.

Installation

yarn add -D @onezlinks/architecture-audit

The package requires Node.js 18 or newer.

{
  "engines": {
    "node": ">=18.0.0"
  }
}

Quick start

Add scripts to the target project:

{
  "scripts": {
    "audit:arch": "arch-audit",
    "audit:arch:all": "arch-audit --all",
    "audit:arch:changed": "arch-audit --changed"
  }
}

Create audit.config.json at the project root:

{
  "changedBase": "origin/main",
  "rulePolicy": {
    "componentRoots": ["components"],
    "hookRoots": ["hooks"],
    "ignoredPathSegments": ["__tests__", "__mocks__", "__stories__"],
    "componentExtensions": [".tsx"],
    "hookExtensions": [".ts", ".tsx"],
    "barrelFileNames": ["index.ts", "index.tsx"],
    "indexComponentFileName": "index.tsx",
    "singularTypeFileName": "type.ts",
    "pluralTypeFileName": "types.ts",
    "childComponentSegments": ["components"],
    "mainComponentKinds": ["page-component", "component"],
    "ignoredClassificationKinds": ["namespace", "test", "tooling"],
    "componentFileNamePattern": "^[A-Z][A-Za-z0-9]*$",
    "componentSymbolPattern": "^[A-Z][A-Za-z0-9]*$",
    "hookExportPattern": "^use[A-Z0-9]",
    "hookFileNamePattern": "^use[A-Z0-9].*\\.(ts|tsx)$"
  },
  "ignore": ["node_modules/", ".next/"],
  "classify": {
    "components/shared/primitives": "namespace"
  },
  "namespaceNames": ["primitives", "overlays", "data-display"],
  "supportNames": ["state", "adapters"]
}

Run the audit:

yarn audit:arch
yarn audit:arch --changed --base origin/main
yarn audit:arch components/pages/ExamplePage
yarn audit:arch --json
yarn audit:arch --markdown
yarn audit:arch --output-path reports/architecture-audit.json

Install the bundled Agent Skill into a supported agent directory:

yarn audit:arch install-skill
yarn audit:arch install-skill --list-targets
yarn audit:arch install-skill --target cursor --target codex
yarn audit:arch install-skill --target claude-code
yarn audit:arch install-skill --target-dir .agents/skills --force

CLI options

|Option|Description| |---|---| |install-skill|Install the bundled architecture-audit-configurator Agent Skill| |--changed|Run changed-file mode and report only findings introduced since the selected git base; existing findings are informational| |--base <ref>|Git base ref for --changed; defaults to changedBase, then origin/main| |--root <path>|Project root directory| |--target <agent>|Supported agent slug for install-skill; repeatable, comma-separated, or all| |--list-targets|Print supported install targets and project paths| |--target-dir <path>|Custom skill install directory that will contain the skill folder| |--force|Replace an existing installed skill when using install-skill| |--all|Run on the full codebase| |--rule <id>|Run one or more specific rules; repeatable| |--category <name>|Run one or more categories; repeatable| |--format <fmt>|Print as stylish, compact, json, or markdown| |--json|Write audit-architecture-report.json| |--markdown|Write audit-architecture-report.md| |--output-path <path>|Write a report to a custom path; format is inferred from extension| |--severity <level>|Minimum severity for a non-zero exit; all new findings are reported: error, warning| |--fix|Show suggestions only; does not modify files| |--verbose|Include ignored findings and diagnostics| |--help, -h|Show CLI help|

Exit codes

|Command|Exit code behavior| |---|---| |arch-audit|Exits 1 when findings match the selected severity| |arch-audit --severity error|Exits 1 only when new errors are found; in --changed mode, existing findings do not affect the exit code| |arch-audit --json|Writes a JSON report and exits 0| |arch-audit --markdown|Writes a Markdown report and exits 0| |arch-audit --output-path file.json|Writes a report and exits 0|

Report-generation modes are designed for CI artifact collection. Use console modes when the audit should block a build.

Rule reference

Barrel rules

|Rule|Severity|What it checks|How to fix| |---|---|---|---| |BARREL-001|error|Page component directories must expose an index.ts or index.tsx barrel|Add an index barrel that re-exports the main component| |BARREL-002|warning|Component subdirectories with two or more source files should expose a barrel|Add index.ts or index.tsx for the grouped component files| |BARREL-003|error|Hook subdirectories must expose an index.ts barrel|Add an index.ts file that re-exports the hook module API| |BARREL-004|warning|Re-export-only barrels should use .ts, not .tsx|Rename re-export-only index.tsx files to index.ts|

Naming rules

|Rule|Severity|What it checks|How to fix| |---|---|---|---| |NAMING-001|error|A main component file should match its directory name, such as Button/Button.tsx|Rename the main component file to match the directory| |NAMING-002|error|index.tsx should be a re-export barrel, not a component implementation|Move component code into a named component file and keep index.ts slim| |NAMING-003|warning|Child components should use named exports instead of default exports|Replace default exports with export const or export function| |NAMING-004|warning|Component source files should use PascalCase filenames|Rename component files to PascalCase| |NAMING-005|warning|Type definition files should use the configured plural name, usually types.ts|Rename type.ts to types.ts| |NAMING-006|error|Exported component runtime symbols must be unique inside the same owner directory|Rename duplicate exported component symbols|

Hook rules

|Rule|Severity|What it checks|How to fix| |---|---|---|---| |HOOK-001|error|Runtime exports from hook source files must start with use|Rename the exported hook or move non-hook runtime code elsewhere| |HOOK-002|warning|Hook files should use use*.ts or use*.tsx unless they are barrels|Rename the file or keep grouped re-exports in an index barrel only|

Structure rules

|Rule|Severity|What it checks|How to fix| |---|---|---|---| |STRUCT-001|error|Page component files and directories must follow the matching directory pattern|Move the main page component into components/pages/<Name>/<Name>.tsx| |STRUCT-002|warning|Directories with many loose component files should use a components/ subdirectory|Group child components under components/| |STRUCT-003|warning|Shared composite components should follow the component directory pattern|Add a dedicated component directory with a main file and public barrel|

Import rules

|Rule|Severity|What it checks|How to fix| |---|---|---|---| |IMPORT-001|warning|Component files should import from a barrel when the barrel exports that symbol|Import from the public or internal barrel instead of a deep path|

Export rules

|Rule|Severity|What it checks|How to fix| |---|---|---|---| |EXPORT-001|warning|Main component files should export the component as default|Add a default export for the main component| |EXPORT-002|warning|Child component files should not export components as default|Convert child component default exports into named exports|

Anti-pattern rules

|Rule|Severity|What it checks|How to fix| |---|---|---|---| |ANTI-001|warning|Component files should stay under the configured line limit|Split the component into smaller units| |ANTI-002|warning|eslint-disable comments must be line-level and include a reason after --|Replace broad disables with a targeted line-level disable and reason| |ANTI-003|warning|TSX files should not live in non-component directories|Move UI code into a component directory or update classifier config if valid| |ANTI-004|warning|Component nesting should not exceed the configured depth|Flatten nested component ownership or extract shared pieces|

Recommended component structure

The default policy assumes a component directory shape like this:

ComponentName/
├── index.ts
├── types.ts
├── ComponentName.tsx
├── __tests__/
└── components/
    ├── index.ts
    └── ChildComponent.tsx

Recommended exports:

// ComponentName/index.ts
export { default } from "./ComponentName";
export type { ComponentNameProps } from "./types";
// ComponentName/ComponentName.tsx
export default function ComponentName() {
  return <div />;
}
// ComponentName/components/ChildComponent.tsx
export function ChildComponent() {
  return <div />;
}

Configuration reference

|Key|Purpose| |---|---| |changedBase|Default git ref used by --changed| |ignore|Project-level source roots to exclude from auditing| |classify|Exact directory classification overrides| |namespaceNames|Directory names treated as namespace/grouping directories| |supportNames|Directory names treated as support directories| |rulePolicy.componentRoots|Root directories that contain component source files| |rulePolicy.hookRoots|Root directories that contain hook source files| |rulePolicy.ignoredPathSegments|Path segments skipped by component and hook rules| |rulePolicy.componentExtensions|Extensions considered component source files| |rulePolicy.hookExtensions|Extensions considered hook source files| |rulePolicy.barrelFileNames|Filenames treated as barrels| |rulePolicy.indexComponentFileName|Filename checked for hidden component implementation| |rulePolicy.singularTypeFileName|Disallowed singular type filename| |rulePolicy.pluralTypeFileName|Preferred plural type filename| |rulePolicy.childComponentSegments|Directory segments that mark child component files| |rulePolicy.mainComponentKinds|Classifier kinds treated as main components| |rulePolicy.ignoredClassificationKinds|Classifier kinds skipped by selected rules| |rulePolicy.componentFileNamePattern|Regular expression for component filenames| |rulePolicy.componentSymbolPattern|Regular expression for exported component symbols| |rulePolicy.hookExportPattern|Regular expression for hook export names| |rulePolicy.hookFileNamePattern|Regular expression for hook filenames| |rulePolicy.looseComponentFileThreshold|Minimum loose component files before STRUCT-002 triggers| |rulePolicy.compositeComponentFileThreshold|Minimum shared component files before STRUCT-003 triggers| |rulePolicy.componentLineLimit|Maximum line count before ANTI-001 triggers| |rulePolicy.componentNestingLimit|Maximum components/ nesting depth before ANTI-004 triggers|

Directory classification

The classifier helps rules understand whether a directory is a component, page component, namespace, support folder, test folder, or tooling folder.

Use classify for explicit overrides when a valid architecture pattern should not be treated as debt:

{
  "classify": {
    "components/shared/primitives": "namespace",
    "hooks/state": "support"
  }
}

Use .auditignore only for known debt or temporary suppressions, not for valid architecture patterns.

Audit ignore file

Create .auditignore only when a finding needs to be suppressed temporarily. Each entry should have a preceding reason comment.

# Legacy component tree scheduled for migration in Q3
components/legacy/OldDashboard

Broad wildcard ignores are intentionally discouraged so that important architecture drift remains visible.

CI examples

Block pull requests on newly introduced changed-file errors only. Existing findings from the git base are reported as informational and do not block:

yarn audit:arch --changed --severity error

Generate a JSON artifact without blocking the build:

yarn audit:arch --json --severity warning

Generate a Markdown report for review comments or CI summaries:

yarn audit:arch --markdown --severity warning

Design principles

  • Keep rule logic reusable and project-neutral.
  • Put project-specific structure in audit.config.json.
  • Prefer classifier/configuration changes for valid patterns.
  • Use .auditignore only for documented suppressions.
  • Keep --fix suggestion-only so the audit never rewrites source code unexpectedly.
  • Report parse failures as diagnostics instead of crashing the full audit.

Checklist

  • [x] Install the package from the npm scope
  • [x] Add audit scripts to the target project
  • [x] Configure project conventions in audit.config.json
  • [x] Run local architecture checks
  • [x] Run changed-file checks in CI
  • [x] Generate JSON or Markdown reports when artifacts are needed