Reference: Import options: The options that make an import condition or a table apply to fewer imports, and the options for chains of imports.
# Import options
> The options that make an import condition or a table apply to fewer imports, and the options for chains of imports.
Add one of these options to an import condition (`mayNotImport`, `mayOnlyImport`, `mayOnlyBeImportedBy`) or to a table. The condition then applies only to some imports.
| Option | Values | The condition applies only to |
| --------------------------- | ------------------------------------------------ | ------------------------------------------------------ |
| [`names`](#names) | list of names | imports that bring in one of these names |
| [`specifier`](#specifier) | `'relative'`, `'parent'`, `'alias'`, `'package'` | imports whose specifier has this form |
| [`instance`](#instance) | `'same'`, `'different'` | imports inside one instance, or between two instances |
| [`dependency`](#dependency) | `'dev'`, `'undeclared'` | packages with this entry in the nearest `package.json` |
| [`within`](#within) | set of files | imports into an area, or importers in an area |
| [`imports`](#imports) | `'all'`, `'runtime'`, `'static'`, `'types'` | imports of this kind |
An import that one of these options leaves out does not count as judged by the rule. `archangel rules` lists it under the imports that no rule judges.
## `names`
```ts
rule('no-effects-in-views', { files: 'view', mayNotImport: { packages: ['react'] }, names: ['useEffect'], examples: { rejected: [{ 'src/view/a.ts': "import { useEffect } from 'react';" }] } })
```
* A default import brings in the name `default`.
* A namespace import (`import * as x`), an `export *`, a dynamic `import()` and a `require()` bring in each name of the module, because archangel cannot see which names the code uses.
* For a module in a package, archangel reads the names that the module exports, through its relative `export * from` statements too. `import * as fr from 'date-fns/locale/fr'` brings in only the names of that locale. When archangel cannot see every name (a CommonJS module, an `export =`, an `export *` from another package), the import brings in each name there is.
## `specifier`
```ts
rule('no-parent-imports', { files: 'feature', mayNotImport: 'feature', specifier: 'parent', examples: { rejected: [{ 'src/features/login/ui/a.ts': "import '../b';", 'src/features/login/b.ts': '' }] } })
```
| Value | The specifier |
| ------------ | ------------------------------------------------------------- |
| `'relative'` | starts with `./` or `../` |
| `'parent'` | starts with `../` |
| `'alias'` | resolves through a tsconfig path or a package `imports` field |
| `'package'` | is a package name |
## `instance`
```ts
rule('features-apart', { files: 'feature', mayNotImport: 'feature', instance: 'different', examples: { rejected: ['src/features/login/a.ts imports src/features/cart/b.ts'] } })
```
* `'same'`: imports whose two ends are in one instance of the part in `files`.
* `'different'`: imports between two instances of that part.
`files` must be one part with a capture. Other `files` give [`rule-needs-capture`](/archangel/reference/diagnostics/rule-needs-capture/).
## `dependency`
```ts
rule('no-dev-packages-in-src', { files: 'src/**', mayNotImport: { packages: ['*'] }, dependency: 'dev', examples: { rejected: [{ 'package.json': '{ "devDependencies": { "react": "1.0.0" } }', 'src/a.ts': "import 'react';" }] } })
```
| Value | The package |
| -------------- | -------------------------------------------------------------------------------- |
| `'dev'` | is only in `devDependencies` of the nearest `package.json` of the importing file |
| `'undeclared'` | is not in the nearest `package.json` of the importing file |
The nearest `package.json` is the first one at or above the importing file. In a monorepo, this is the `package.json` of the workspace package. Read [Monorepos](/archangel/guides/monorepos/).
## `within`
`within` gives a rule an area. The rule then permits each import outside the area.
```ts
rule('entity-imports', { files: 'entity', mayOnlyImport: ['value-object', 'error'], within: 'src/**', examples: { rejected: ['src/entity/a.ts imports src/use-case/a.ts'] } })
```
| On | `within` limits |
| --------------------- | ------------------------------------------------------------------ |
| `mayOnlyImport` | the targets: the rule judges only imports into the area |
| `mayOnlyBeImportedBy` | the importers: the rule judges only imports from files in the area |
| a table | the targets: each row judges only imports into the area |
* Without `within`, `mayOnlyImport` judges each import, packages too.
* `within` can name an externals set. Then `mayOnlyImport` judges the imports of those packages.
* With `within`, the list of `mayOnlyImport` can be empty. The rule then refuses each import into the area, except into its own files.
* Archangel refuses `within` on `mayNotImport`, and on a condition that judges no import. To limit `mayNotImport` to an area, write the area on the other side: `mayNotImport: { all: ['use-case', 'src/**'] }`.
* An area that finds no file is an error.
## `imports`
| Value | The rule counts |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `'all'` | each import. This is the default. |
| `'runtime'` | the imports that stay in the compiled code. This is the default for `noCycles` and for a transitive rule. |
| `'static'` | the runtime imports other than `import()`: the imports that load with the file, in its bundle chunk. A `require()` is static. |
| `'types'` | only type imports, such as `import type` |
An `import type`, and an import that names only types with `import { type A }`, is a type import. With `verbatimModuleSyntax` in your tsconfig, `import { type A } from './a'` stays in the compiled code, so it is a runtime import.
## `transitively`
Add `transitively: true` to `mayNotImport`. The rule then finds chains of imports of each length, not only direct imports. The report shows the shortest chain.
```ts
rule('client-stays-client', {
files: { directive: 'use client' },
mayNotImport: { packages: ['node:*'] },
transitively: true,
stopAt: { directive: 'use server' },
examples: {
rejected: [{ 'src/view/a.tsx': "'use client';\nimport '../shared/a';", 'src/shared/a.ts': "import 'node:fs';" }],
},
})
```
* A chain stops at a package, and at each file in `stopAt`.
* A transitive rule’s side cannot name a package subpath, such as `lodash-es/*`, because a chain ends at a package.
* With `imports: 'static'`, a chain also stops at each `import()`. A bundler starts a new chunk there, so the rule then means “the initial bundle may not reach this”: `rule('initial-bundle-no-carousel', { files: 'feature', mayNotImport: { packages: ['carousel'] }, transitively: true, imports: 'static' })`.
* A transitive rule counts only runtime imports by default. `imports: 'types'` is refused, because a chain of type imports never runs.
* A transitive rule cannot also have `names`, `specifier`, `instance`, `dependency` or `within`.
* For each file that reaches the other side, archangel reports one problem with the shortest chain. Among chains of one length, it shows the first in path order.
`archangel why ` shows the shortest chain between two files, or from a file to a package. It does not know `stopAt`, so it can show a chain that the rule stops.