---
# Don't modify this file manually. This file is auto generated from source, and you will lose your changes next time the website is built.
# Head to the `biomejs/biome` repository, and modify the source code in there.

title: noImportCycles
description: Learn more about noImportCycles
---
import { Tabs, TabItem } from '@astrojs/starlight/components';

<Tabs>
<TabItem label="JavaScript (and super languages)" icon="seti:javascript">
:::caution
This rule is part of the [nursery](/linter/#nursery) group. This means that it is experimental and the behavior can change at any time.
:::
:::note
This rule belongs to the project domain. This means that its activation will activate the Biome Scanner, which might affect the performance. Read more about it in the [documentation page](/linter/domains#project)
:::
## Summary
- Rule available since: `v2.0.0`
- Diagnostic Category: [`lint/nursery/noImportCycles`](/reference/diagnostics#diagnostic-category)
- This rule doesn't have a fix.
- The default severity of this rule is [**warning**](/reference/diagnostics#warning).
- This rule belongs to the following domains:
  - [`project`](/linter/domains#project)
- Sources: 
  - Same as [`import/no-cycle`](https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-cycle.md)

## How to configure
```json title="biome.json"
{
	"linter": {
		"rules": {
			"nursery": {
				"noImportCycles": "error"
			}
		}
	}
}

```
## Description
Prevent import cycles.

This rule warns when a file imports another file that, either directly
or indirectly, imports the original file again.

Cycles can lead to symbols that are unexpectedly `undefined` and are
generally considered poor code hygiene.

If a cycle is detected, it is advised to move code such that imports
only go in a single direction, i.e. they don't point "back" to the
importing file.

However, files that import themselves are allowed, and the rule won't trigger for these use cases.
This allows for encapsulation of functions/variables into a namespace instead of using a
static class (triggers [noStaticOnlyClass](https://biomejs.dev/linter/rules/no-static-only-class)).

:::note
This rule is computationally expensive. If you are particularly
pressed for lint time, or don't think you have an issue with dependency
cycles, you may not want this rule enabled.
:::

## Examples

### Invalid

```js title='foobar.js'
import { baz } from "./baz.js";

export function foo() {
    baz();
}

export function bar() {
    console.log("foobar");
}
```

<pre class="language-text"><code class="language-text"><a href="file:///foobar.js">/foobar.js</a>:1:21 <a href="https://biomejs.dev/linter/rules/no-import-cycles">lint/nursery/noImportCycles</a> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━<br /><br />  <strong><span style="color: Orange;">⚠</span></strong> <span style="color: Orange;">This import is part of a cycle.</span><br />  <br />  <strong><span style="color: Tomato;">&gt;</span></strong> <strong>1 │ </strong>import &#123; baz &#125; from &quot;./baz.js&quot;;<br />   <strong>   │ </strong>                    <strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><br />    <strong>2 │ </strong><br />    <strong>3 │ </strong>export function foo() &#123;<br />  <br />  <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">This import resolves to </span><span style="color: lightgreen;"><span style="color: lightgreen;">/baz.js</span></span><span style="color: lightgreen;"><br /></span>    <span style="color: lightgreen;">    ... which imports </span><span style="color: lightgreen;"><span style="color: lightgreen;">/foobar.js</span></span><span style="color: lightgreen;"><br /></span>    <span style="color: lightgreen;">    ... which is the file we're importing from.</span><br />  <br />  <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit </span><span style="color: lightgreen;"><a href="https://biomejs.dev/linter/#nursery">https://biomejs.dev/linter/#nursery</a></span><span style="color: lightgreen;"> for more information.</span><br />  <br /></code></pre>

```js title='baz.js'
import { bar } from "./foobar.js";

export function baz() {
    bar();
}
```

<pre class="language-text"><code class="language-text"><a href="file:///baz.js">/baz.js</a>:1:21 <a href="https://biomejs.dev/linter/rules/no-import-cycles">lint/nursery/noImportCycles</a> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━<br /><br />  <strong><span style="color: Orange;">⚠</span></strong> <span style="color: Orange;">This import is part of a cycle.</span><br />  <br />  <strong><span style="color: Tomato;">&gt;</span></strong> <strong>1 │ </strong>import &#123; bar &#125; from &quot;./foobar.js&quot;;<br />   <strong>   │ </strong>                    <strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><br />    <strong>2 │ </strong><br />    <strong>3 │ </strong>export function baz() &#123;<br />  <br />  <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">This import resolves to </span><span style="color: lightgreen;"><span style="color: lightgreen;">/foobar.js</span></span><span style="color: lightgreen;"><br /></span>    <span style="color: lightgreen;">    ... which imports </span><span style="color: lightgreen;"><span style="color: lightgreen;">/baz.js</span></span><span style="color: lightgreen;"><br /></span>    <span style="color: lightgreen;">    ... which is the file we're importing from.</span><br />  <br />  <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit </span><span style="color: lightgreen;"><a href="https://biomejs.dev/linter/#nursery">https://biomejs.dev/linter/#nursery</a></span><span style="color: lightgreen;"> for more information.</span><br />  <br /></code></pre>

### Valid

```js title='foo.js'
import { baz } from "./baz.js";

export function foo() {
    baz();
}
```

```js title='bar.js'
export function bar() {
    console.log("foobar");
}
```

```js title='baz.js'
import { bar } from "./bar.js";

export function baz() {
    bar();
}
```

```js title='foobaz.js'
export function foo() {
    console.log("foobaz");
}

export * as baz from './foobaz.js';

import { baz } from './foobaz.js';
```

```ts title='types.ts'
import type { bar } from "./qux.ts";

export type Foo = {
  bar: typeof bar;
};
```

```ts title='qux.ts'
import type { Foo } from "./types.ts";

export function bar(foo: Foo) {
    console.log(foo);
}
```

## Options

The rule provides the options described below.

### `ignoreTypes`

Ignores type-only imports when finding an import cycle. A type-only import (`import type`)
will be removed by the compiler, so it cuts an import cycle at runtime. Note that named type
imports (`import { type Foo }`) aren't considered as type-only because it's not removed by
the compiler if the `verbatimModuleSyntax` option is enabled. Enabled by default.

```json title='biome.json'
{
	"linter": {
		"rules": {
			"nursery": {
				"noImportCycles": {
					"options": {
						"ignoreTypes": false
					}
				}
			}
		}
	}
}

```

#### Invalid

```ts title='types.ts'
import type { bar } from "./qux.ts";

export type Foo = {
  bar: typeof bar;
};
```

```ts title='qux.ts'
import type { Foo } from "./types.ts";

export function bar(foo: Foo) {
    console.log(foo);
}
```

<pre class="language-text"><code class="language-text"><a href="file:///qux.ts">/qux.ts</a>:1:26 <a href="https://biomejs.dev/linter/rules/no-import-cycles">lint/nursery/noImportCycles</a> ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━<br /><br />  <strong><span style="color: Orange;">⚠</span></strong> <span style="color: Orange;">This import is part of a cycle.</span><br />  <br />  <strong><span style="color: Tomato;">&gt;</span></strong> <strong>1 │ </strong>import type &#123; Foo &#125; from &quot;./types.ts&quot;;<br />   <strong>   │ </strong>                         <strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><strong><span style="color: Tomato;">^</span></strong><br />    <strong>2 │ </strong><br />    <strong>3 │ </strong>export function bar(foo: Foo) &#123;<br />  <br />  <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">This import resolves to </span><span style="color: lightgreen;"><span style="color: lightgreen;">/types.ts</span></span><span style="color: lightgreen;"><br /></span>    <span style="color: lightgreen;">    ... which imports </span><span style="color: lightgreen;"><span style="color: lightgreen;">/qux.ts</span></span><span style="color: lightgreen;"><br /></span>    <span style="color: lightgreen;">    ... which is the file we're importing from.</span><br />  <br />  <strong><span style="color: lightgreen;">ℹ</span></strong> <span style="color: lightgreen;">This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit </span><span style="color: lightgreen;"><a href="https://biomejs.dev/linter/#nursery">https://biomejs.dev/linter/#nursery</a></span><span style="color: lightgreen;"> for more information.</span><br />  <br /></code></pre>

## Related links

- [Disable a rule](/linter/#disable-a-rule)
- [Configure the code fix](/linter#configure-the-code-fix)
- [Rule options](/linter/#rule-options)
- [Source Code](https://github.com/biomejs/biome/blob/main/crates/biome_js_analyze/src/lint/nursery/no_import_cycles.rs)
- [Test Cases](https://github.com/biomejs/biome/blob/main/crates/biome_js_analyze/tests/specs/nursery/noImportCycles)

</TabItem>
</Tabs>