# Archangel > Architecture tests for TypeScript. Make architecture verifiable. Archangel tests the structure of TypeScript code: which code may import which code, cycles, file and folder names, and exports. Its config is `archangel.config.ts`. To answer a question, read one page below, not the complete documentation. Start with "Start: Getting started" for a first config, "Concepts" for what the words of a config mean, and "Reference" for every key and option. For a diagnostic code such as `may-import`, read "Diagnostic codes: may-import", or run `npx archangel docs may-import`, which prints the same text with no network. Every config and command output in these pages comes from a small repository that a test runs on the published package `@enhance-eng/archangel`, so the outputs are what archangel prints. ## Documentation Sets - [Abridged documentation](https://enhancelabs.ai/archangel/llms-small.txt): a compact version of the documentation for Archangel, with non-essential content removed - [Complete documentation](https://enhancelabs.ai/archangel/llms-full.txt): the full documentation for Archangel - [Start](https://enhancelabs.ai/archangel/_llms-txt/start.txt): what archangel is, how it works, and a first table - [Guides](https://enhancelabs.ai/archangel/_llms-txt/guides.txt): one task each, from adding archangel to a repository to migrating from another tool - [Concepts](https://enhancelabs.ai/archangel/_llms-txt/concepts.txt): parts, groups, captures, kinds, tables, rules and examples - [Reference](https://enhancelabs.ai/archangel/_llms-txt/reference.txt): every config key, condition, option, command and output format - [Diagnostic codes](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes.txt): what each code means, an example, and what to do - [Start: Getting started](https://enhancelabs.ai/archangel/_llms-txt/start-getting-started.txt): Install archangel, write a first table, see it find a problem, and prove a rule with an example. - [Start: How archangel works](https://enhancelabs.ai/archangel/_llms-txt/start-how-archangel-works.txt): The map of the code, how a rule asks a question about it, the loop of check, test and rules, and why it is fast. - [Start: Introduction](https://enhancelabs.ai/archangel/_llms-txt/start-introduction.txt): What archangel is, what it checks, what it does not check, and why architecture needs tests. - [Guides: Layer a backend](https://enhancelabs.ai/archangel/_llms-txt/guides-layer-a-backend.txt): Write the layers of a backend as a table, keep the database driver in one layer, give the domain files kinds, and stop import cycles. - [Guides: Use archangel in CI](https://enhancelabs.ai/archangel/_llms-txt/guides-use-archangel-in-ci.txt): Fail a pull request that breaks an architecture test, and show each problem on its line in the pull request. - [Guides: Give these docs to a coding agent](https://enhancelabs.ai/archangel/_llms-txt/guides-give-these-docs-to-a-coding-agent.txt): Point a coding agent at the Markdown of these docs, tell it to use archangel in your repository, and let it read each diagnostic code without a network. - [Guides: Editors and coding agents](https://enhancelabs.ai/archangel/_llms-txt/guides-editors-and-coding-agents.txt): See each problem as you type, in VS Code, Neovim or another editor, and give a coding agent the result of each change. - [Guides: Exceptions and baselines](https://enhancelabs.ai/archangel/_llms-txt/guides-exceptions-and-baselines.txt): Permit one import that breaks a rule on purpose, with a reason. Record the old problems of a codebase in a baseline that only gets smaller. - [Guides: Add archangel to an existing repository](https://enhancelabs.ai/archangel/_llms-txt/guides-add-archangel-to-an-existing-repository.txt): Turn on a rule today in a repository that already breaks it. Record the old problems in a baseline, and stop each new problem. - [Guides: Feature-Sliced Design](https://enhancelabs.ai/archangel/_llms-txt/guides-feature-sliced-design.txt): Check a Feature-Sliced Design front end with the fsd preset, which holds the rules of Steiger, each with examples. - [Guides: Migrate from dependency-cruiser](https://enhancelabs.ai/archangel/_llms-txt/guides-migrate-from-dependency-cruiser.txt): Move forbidden rules from dependency-cruiser to archangel, and know which results change. - [Guides: Migrate from eslint-plugin-boundaries](https://enhancelabs.ai/archangel/_llms-txt/guides-migrate-from-eslint-plugin-boundaries.txt): Turn boundaries elements into parts, element-types into a table, and entry-point into the entry shorthand. - [Guides: Migrate from eslint-plugin-check-file](https://enhancelabs.ai/archangel/_llms-txt/guides-migrate-from-eslint-plugin-check-file.txt): Move file and folder naming rules from eslint-plugin-check-file to mustBeNamed and mustNotExist rules. - [Guides: Migrate from Steiger](https://enhancelabs.ai/archangel/_llms-txt/guides-migrate-from-steiger.txt): Replace Steiger with the fsd preset. Each Steiger rule has a rule of the same name, with examples, and the differences are listed. - [Guides: Monorepos and workspace tables](https://enhancelabs.ai/archangel/_llms-txt/guides-monorepos-and-workspace-tables.txt): Check which apps and packages of a workspace may use which, and make each app list the packages that it imports. - [Guides: File and folder names](https://enhancelabs.ai/archangel/_llms-txt/guides-file-and-folder-names.txt): Check the style of file and folder names, permit a list of names, make a file export the name of its file, and make each folder hold its entry file. - [Guides: Next.js](https://enhancelabs.ai/archangel/_llms-txt/guides-nextjs.txt): Keep server code out of client components with the nextjs preset, which follows chains of imports from each 'use client' file. - [Guides: Write a plugin](https://enhancelabs.ai/archangel/_llms-txt/guides-write-a-plugin.txt): Write your own condition in TypeScript, use it in a rule, prove it with examples, and publish it. - [Concepts: Captures and instances](https://enhancelabs.ai/archangel/_llms-txt/concepts-captures-and-instances.txt): A capture such as {feature} makes each folder one instance of a part. Rules can treat an import inside one instance differently from one between two. - [Concepts: Examples prove rules](https://enhancelabs.ai/archangel/_llms-txt/concepts-examples-prove-rules.txt): A rule can be wrong and still pass. Examples are code that a rule must accept or reject, and archangel test checks them in memory, laid over your repository. - [Concepts: Kinds](https://enhancelabs.ai/archangel/_llms-txt/concepts-kinds.txt): A kind is a row name that one pattern gives to each file, such as entity for order.entity.ts. Kinds let one table cover many files with no declarations. - [Concepts: Parts, groups and externals](https://enhancelabs.ai/archangel/_llms-txt/concepts-parts-groups-and-externals.txt): The three kinds of names that a config gives to code. A file is in one part at most, in many groups, and an externals set names outside packages. - [Concepts: Rules and conditions](https://enhancelabs.ai/archangel/_llms-txt/concepts-rules-and-conditions.txt): A rule has a set of files and one condition, and reads as a sentence. Tables, shorthands, folder rules and plugin rules are forms of rules. - [Concepts: Tables, rows and cells](https://enhancelabs.ai/archangel/_llms-txt/concepts-tables-rows-and-cells.txt): How a table decides. Each row is a set of files, and its cells are what those files may import. The table refuses each other import into the repository. - [Concepts: What a rule judges](https://enhancelabs.ai/archangel/_llms-txt/concepts-what-a-rule-judges.txt): A rule judges an import when it decides to permit or refuse it. archangel rules and archangel explain show what each rule judged, and what no rule judges. - [Reference: Commands](https://enhancelabs.ai/archangel/_llms-txt/reference-commands.txt): Each archangel command, its arguments and options, and what it prints. - [Reference: Conditions](https://enhancelabs.ai/archangel/_llms-txt/reference-conditions.txt): Each condition of a rule, for files and for folders, and the rule forms that hold them. - [Reference: Config file](https://enhancelabs.ai/archangel/_llms-txt/reference-config-file.txt): Where archangel finds its config, the two formats, and each top-level key. - [Reference: Diagnostic codes](https://enhancelabs.ai/archangel/_llms-txt/reference-diagnostic-codes.txt): Every diagnostic code that archangel gives, by group: rule violations, config problems, repository problems, exceptions, the baseline and examples. - [Reference: Examples](https://enhancelabs.ai/archangel/_llms-txt/reference-examples.txt): How to write the examples that prove a rule, the one-line form and its limits, and what archangel test checks. - [Reference: Import options](https://enhancelabs.ai/archangel/_llms-txt/reference-import-options.txt): The options that make an import condition or a table apply to fewer imports, and the options for chains of imports. - [Reference: Output and exit codes](https://enhancelabs.ai/archangel/_llms-txt/reference-output-and-exit-codes.txt): The text, JSON, GitHub and SARIF formats, the work counts of --stats, and the exit codes. - [Reference: Plugin API](https://enhancelabs.ai/archangel/_llms-txt/reference-plugin-api.txt): defineCondition, definePlugin, the view that a condition receives, and what it returns. - [Reference: Presets](https://enhancelabs.ai/archangel/_llms-txt/reference-presets.txt): The fsd and nextjs presets, their options and rules, how to change a preset, and how to write one. - [Reference: Rule options](https://enhancelabs.ai/archangel/_llms-txt/reference-rule-options.txt): The options that every rule, table and shorthand can have: name, because, link, severity, imports and examples, with their types and defaults. - [Reference: Sets of files](https://enhancelabs.ai/archangel/_llms-txt/reference-sets-of-files.txt): Each way to write a set of files, and the path patterns that archangel uses. - [Reference: Shorthands](https://enhancelabs.ai/archangel/_llms-txt/reference-shorthands.txt): The shorthands layers, isolate and entry: what each one writes for you, its options, its JSON form and the problems it reports. - [Reference: Tables](https://enhancelabs.ai/archangel/_llms-txt/reference-tables.txt): The mayImport table, its rows, cells and options, and the rules that it makes. - [Diagnostic codes: baseline-invalid](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-baseline-invalid.txt): The baseline file, `archangel.baseline.json`, does not parse. - [Diagnostic codes: baseline-stale](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-baseline-stale.txt): A baseline entry permits more violations than the code has, because they were fixed, or it names a rule that no longer exists. A check never rewrites the baseline. - [Diagnostic codes: config-invalid](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-config-invalid.txt): The config has a field archangel does not know, a value of the wrong type, or text that is not valid JSON. The diagnostic names the field, such as `rules[0].reasn`. - [Diagnostic codes: config-load-failed](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-config-load-failed.txt): The config's code threw while it loaded, has no default export, or uses TypeScript that Node cannot strip, such as an enum. - [Diagnostic codes: config-missing](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-config-missing.txt): Archangel found no config in the current folder or any folder above it. - [Diagnostic codes: config-needs-node](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-config-needs-node.txt): The config is TypeScript or JavaScript, and Node 22.18 or later is not on the search path. - [Diagnostic codes: element-empty](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-element-empty.txt): A part or an externals set matches nothing, so no rule about it can fire. For a part, no file matches its patterns. For an externals set, no import uses its packages and no package manifest lists them. - [Diagnostic codes: entry](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-entry.txt): Code outside an instance of a part imports a file inside it that is not one of the instance's entry files. A sibling instance counts as outside. - [Diagnostic codes: every-file-has-a-kind](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-every-file-has-a-kind.txt): A file in the `files` of an import table has no row in that table. - [Diagnostic codes: example-failed](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-example-failed.txt): A rule did not judge an example as the example says: it accepted a rejected example, or rejected an accepted one. When another rule rejected the example instead, the message names it. - [Diagnostic codes: example-proves-nothing](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-example-proves-nothing.txt): An accepted example passed, but its rule never looked at it, so it proves nothing. An import rule looks at imports, a rule about files at files, a folder rule at folders, a `mustContain` rule on a part at its instances, and a plugin rule at the files of its view. The message says which one the rule never looked at. - [Diagnostic codes: exception-unknown-rule](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-exception-unknown-rule.txt): An `archangel-allow` comment names a rule that the config does not have. The message lists the rules that exist. - [Diagnostic codes: exception-unused](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-exception-unused.txt): An `archangel-allow` comment permits nothing, because the import after it does not break the rule it names. The import after it is the one whose specifier is on the next line, or whose statement starts on the next line. Exceptions go away when the code is fixed. - [Diagnostic codes: exception-without-reason](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-exception-without-reason.txt): An `archangel-allow` comment gives no reason after the colon, so it permits nothing. - [Diagnostic codes: exports-unknown](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-exports-unknown.txt): A `mustExport` rule needs the names a file exports, and the file passes names on through an `export *` from a package or from a specifier that does not resolve, so archangel cannot know them. - [Diagnostic codes: file-unreadable](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-file-unreadable.txt): Archangel cannot open a folder or a file, or a source file is not UTF-8 or UTF-16 text. - [Diagnostic codes: ignore-line-invalid](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-ignore-line-invalid.txt): A line of the config's `ignore` list is not valid `.gitignore` syntax. - [Diagnostic codes: import-unresolved](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-import-unresolved.txt): Archangel cannot find the file or package that an import names. The message says why in plain words. - [Diagnostic codes: isolate](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-isolate.txt): A file in one instance of a part imports a file in a different instance of the same part, such as one feature importing another. - [Diagnostic codes: layers](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-layers.txt): An import goes from one part of a layers rule to a part earlier in its list. - [Diagnostic codes: may-import](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-may-import.txt): A file of a row of an import table imports something that its row does not list. - [Diagnostic codes: may-not-export](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-may-not-export.txt): A file in a `mayNotExport` rule has an export of the kind the rule refuses: a default export, an `export *` or `export * as`, or a named export whose name matches the rule's pattern. - [Diagnostic codes: may-not-import](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-may-not-import.txt): A file in the `files` of a `mayNotImport` rule imports a file or package on the rule's other side, directly or, for a transitive rule, through a chain of imports. - [Diagnostic codes: may-only-be-imported-by](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-may-only-be-imported-by.txt): A file imports a file in the `files` of a `mayOnlyBeImportedBy` rule, and the importing file is neither on the rule's list nor in those files. A file in no part counts as outside the list. - [Diagnostic codes: may-only-import](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-may-only-import.txt): A file in the `files` of a `mayOnlyImport` rule imports a file or package that is neither on the rule's list nor in those files. When `files` is a part with a capture, only the files of the same instance count as those files. - [Diagnostic codes: must-be-named](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-must-be-named.txt): A file or folder in a `mustBeNamed` rule has a name that is not in the rule's style, or a full name that does not match the rule's name pattern. For a rule with a list, the name matches no entry in the list. - [Diagnostic codes: must-contain](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-must-contain.txt): An instance of a part, or a folder, in a `mustContain` rule has no file that matches the rule's pattern. - [Diagnostic codes: must-export](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-must-export.txt): A file in a `mustExport` rule exports no name that matches the rule's name pattern. - [Diagnostic codes: must-not-exist](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-must-not-exist.txt): A file is in the `files` of a `mustNotExist` rule, such as a file in no part or in a reserved folder. - [Diagnostic codes: must-only-re-export](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-must-only-re-export.txt): A file in a `mustOnlyReExport` rule has a top-level statement of its own: a declaration, a type included, or code that runs. It may hold only imports, exports from other files, directives, and `export { … }` of names it imported. - [Diagnostic codes: no-cycles](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-no-cycles.txt): A group of files import each other, so each can reach the others. The diagnostic lists every file in the group and shows its shortest cycle. - [Diagnostic codes: parse-failed](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-parse-failed.txt): A source file has syntax errors, uses Flow syntax, or is larger than the parser accepts. Archangel uses none of its imports, because a parser that recovers from errors can invent or lose imports. - [Diagnostic codes: part-overlap](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-part-overlap.txt): A file is in two of the config's own parts. A file can be in one part at most, so a rule about parts cannot know which part judges the file. - [Diagnostic codes: pattern-invalid](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-pattern-invalid.txt): A pattern has an empty folder name, a `**` that is not a whole folder name, a capture without a name, or the same capture name twice. - [Diagnostic codes: plugin](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-plugin.txt): A file breaks a rule whose condition a plugin defines, such as `team/one-store-per-entity`. The plugin's condition wrote the message. - [Diagnostic codes: plugin-failed](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-plugin-failed.txt): A plugin could not give its condition's result: the condition threw, it reported a file that was not in its view, or the plugin's Node process stopped. - [Diagnostic codes: preset-empty](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-preset-empty.txt): A preset the config extends matches no file with any of its parts, so none of its rules can fire. - [Diagnostic codes: resolution-file-invalid](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-resolution-file-invalid.txt): A tsconfig or package manifest that resolution needs is not valid: it does not parse, cannot be read, or extends a package that is not installed. Archangel reports it once, not once per import. - [Diagnostic codes: rule-name-duplicate](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-rule-name-duplicate.txt): Two rules have the same name, often the default name of two rules about the same files, such as `mayNotImport(entity, react)`. Exceptions and the baseline refer to rules by name, so each needs its own. - [Diagnostic codes: rule-needs-capture](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-rule-needs-capture.txt): An isolate rule names a part whose pattern captures nothing, so it has only one instance. - [Diagnostic codes: rule-unknown-element](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-rule-unknown-element.txt): A rule or a group names a part, a group or an externals set that the config does not declare. A string without a `/` or a `*` is a name, not a path pattern. The message lists the declared names. - [Diagnostic codes: rule-unproven](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-rule-unproven.txt): A rule has no rejected example, so nothing proves that it can find a violation. - [Diagnostic codes: selector-empty](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-selector-empty.txt): A group that the config declares, a path pattern written inline in a rule, or the `folders` of a folder rule matches nothing, so no rule about it can fire. - [Diagnostic codes: table-empty](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-table-empty.txt): A table has no row, or its rows together have no file, so the table checks nothing. - [Diagnostic codes: table-row-overlap](https://enhancelabs.ai/archangel/_llms-txt/diagnostic-codes-table-row-overlap.txt): A file in a table's files is in two rows of that table. Each of the two rows judges the file. ## Notes - The complete documentation includes all content from the official documentation - The content is automatically generated from the same source as the official documentation ## Optional - [Source](https://github.com/enhance-labs-builds/archangel): the Rust core, the npm package and the editor extension - [npm package](https://www.npmjs.com/package/@enhance-eng/archangel)