Architecture rules in TypeScript projects are almost always hand-authored. Teams write lint configurations and dependency constraints manually, then hope those rules stay in sync with the actual codebase as it evolves. A new open-source tool called archprint takes the opposite approach: it scans a repository's real import graph, identifies the boundaries the code already respects, and generates ready-to-install lint rules for the ones that pass a statistical confidence gate. Every rule ships with evidence showing how many files conform, how many break it, and how confident the inference is.
Mining rules from what the code already does
The core idea is simple but underexploited. Most TypeScript repositories already follow implicit architecture rules. Production code does not import test files. UI components do not reach into the database layer. Feature modules do not import each other's internals. These patterns exist in the import graph whether or not anyone has written a lint rule to enforce them. Archprint detects these patterns, measures their consistency, and promotes the ones that are statistically reliable into deterministic enforcement.
The tool uses a Wilson score lower bound on the true conformance rate, which fuses the observed ratio and the sample size into a single confidence number. This means five out of five clean files does not get treated as equivalent to 40 out of 40. A rule needs a 95% lower bound of at least 90% conformance with at most three exceptions to qualify as auto-enforceable. Patterns with weaker evidence surface as suggestions for human review rather than being silently enforced.
Mechanical families versus structural inference
Archprint distinguishes between two categories of rules. Mechanical families are grounded in unambiguous signals: no circular dependencies, production must not import tests, no console calls in library code, no undeclared dependencies, no reaching into a dependency's internals, and public-API barrel boundaries. An adversarial correctness audit across three rounds and four real repositories found zero false positives for these mechanical rules, so they auto-generate as enforcement without human review.
Structural-inference families, on the other hand, infer a layer or role from file paths and directory structure. These include layer boundaries, role layering, UI and data separation, feature-slice isolation, and app isolation. Because the inferred layer can be wrong, archprint holds these for human review by default. Nothing whose inferred classification could be incorrect is written as enforcement unless the user explicitly opts in. This conservative approach prioritizes trust over completeness.
Validated across tens of thousands of repositories
The tool's scan and recommend commands ran across all 92,861 public TypeScript repositories with zero crashes. A 2,000-repo stratified sample tested the full init, wire, and eject lifecycle cleanly. A companion benchmark called AgentRuleBench measures the guidance versus enforcement question directly with a pre-registered, honest null result on the boundary it tested.
The recommend command sorts every rule family into three tiers: rules the code already follows and should enforce now, rules with thin evidence worth reviewing and adopting, and rules that comparable repositories commonly enforce but the current project does not yet follow. Each recommendation carries evidence from a census of tens of thousands of public TypeScript repositories, giving stack-aware baselines even for fresh projects with little code to infer from.
Integration with existing tooling
Archprint does not replace dependency-cruiser, ESLint, or ts-arch. It emits into their formats. Generated rules write directly into dependency-cruiser forbidden rulesets, ESLint plugin-boundaries configuration, and ts-arch test files. A shareable ESLint preset inlines the inferred rules as a self-contained module that needs only eslint to run. The generate command also produces Mermaid and Graphviz diagrams of the layer dependency graph so the inferred architecture is visible and its violations are marked.
The wire command detects which enforcement tools a repository already uses and inserts a single managed reference into each configuration. The eject command removes those references cleanly, restoring each config to its original state. For tool configurations that archprint cannot safely edit, it prints the exact snippet to paste. This lifecycle means adoption is reversible at any point.
Framework awareness and the CLI workflow
The tool recognizes common TypeScript stacks including Next.js, Nest, SvelteKit, Nuxt, and Remix. It classifies UI components across React TSX files, Angular component and directive files, and Vue and Svelte single-file components by reading their script blocks. This means component-aware rules apply regardless of which framework the project uses.
The typical workflow starts with archprint init, which detects the stack, enforces the rules the code already follows, and writes an archprint.json recording what to adopt next. From there, scan shows the rules with evidence, generate writes the auto-trusted rules and tool configs, explain shows the gate breakdown for any individual rule, and recommend suggests a rule set from the evidence and detected stack. The tool is published on npm as a pre-stable 0.x package and requires Node 20 or later.