Severity: error
Category: modules
Stage: Stage 1
Description
SJS performs a static analysis of the module dependency graph during compilation. If two or more modules form an import cycle (A imports B and B imports A, directly or transitively), the compiler raises this error.
Circular imports are banned because:
- They cause unpredictable initialisation order — some module's exports may be
undefinedat the point they are consumed. - They indicate that responsibilities are not properly separated between modules.
The error is reported on the import statement that closes the cycle.
Example
// ✗ error — a.sjs
import { bar } from "./b.sjs" // SJS-E017 — closes the cycle
export function foo(): string { return bar() }// ✗ error — b.sjs
import { foo } from "./a.sjs"
export function bar(): string { return foo() }Fix
Break the cycle by extracting shared logic into a third module that neither of the original modules imports back:
// ✓ correct — shared.sjs (no imports from a or b)
export function shared(): string { return "hello" }// ✓ correct — a.sjs
import { shared } from "./shared.sjs"
export function foo(): string { return shared() }// ✓ correct — b.sjs
import { shared } from "./shared.sjs"
export function bar(): string { return shared() }Related codes
SJS-E012—namespaceis banned; use ES module imports insteadSJS-E018— top-levelawaitused outside an ES module context