Skip to content
Arxo Arxo

Language-Specific Patterns

Circular dependencies can look different depending on the language: import style, barrel files, and runtime behavior all affect where cycles appear and how to fix them. Arxo detects cycles in TypeScript/JavaScript and Python. This page summarizes common patterns and fixes for each.

For an overview, see Circular Dependencies. For refactoring patterns that work in any language, see Refactoring Patterns.

  • Barrel filesindex.ts re-exports from many files, and those files import from index.ts, forming A → index → B → index → A.
  • Types and values — File A imports a type and a value from B, B imports from A; the runtime import creates the cycle even if the type is only used in type position.
  • Circular component trees — e.g. React components that import each other through a long chain back to the start.
  • Prefer direct imports to the concrete file instead of the barrel when that would break the cycle.
  • Extract shared types into a types.ts (or similar) that neither side imports from the other — see Refactoring Patterns: Move Types to Definitions File.
  • Split barrels so that the cycle is broken (e.g. one barrel for “public” API, no circular re-exports).

Cycles prevent reliable tree-shaking. If bundle size matters, fixing import cycles is a prerequisite.


  • Circular imports — Module A imports B, B imports A (or A → B → C → A). Python may load them at runtime but with fragile order and “partial module” issues.
  • Type hintsfrom __future__ import annotations and forward references can hide circular imports at runtime but the static graph still has a cycle.
  • Shared models — Two modules that define or use each other’s types or models.
  • Dependency injection or late imports (import inside a function) can break runtime cycles; Arxo still sees the static import graph, so prefer removing the static cycle (e.g. move shared code to a third module).
  • Extract shared code into a separate module both A and B import from — see Refactoring Patterns: Extract Shared Module.
  • Use a types-only module or TYPE_CHECKING imports so that the main execution path doesn’t form a cycle.

  • Group by folder or package — Use group_by: folder (or equivalent) in Arxo so that cycles are reported at the level you care about (e.g. packages or modules, not every single file).
  • Fix small cycles first — Two- or three-node cycles are usually easier to break and still improve metrics; see Fixing Cycles.
  • Use the same grouping in CI — So that “no new cycles” is enforced at the same granularity you use locally.