#6064·rollup

Incorrect order of declarations after bundling (ReferenceError: Cannot access 'X' before initialization)

Author: q2pCreated Aug 9, 2025Updated Mar 20, 2026
Labelst¹ 🐞 bugt⁸ ⋅ triage

Rollup Version

4.46.2

Operating System (or Browser)

Ubuntu

Node Version (if applicable)

18.19.1

Link To Reproduction

https://rollupjs.org/repl/?version=4.46.2&shareable=JTdCJTIyZXhhbXBsZSUyMiUzQW51bGwlMkMlMjJtb2R1bGVzJTIyJTNBJTVCJTdCJTIyY29kZSUyMiUzQSUyMmltcG9ydCUyMCU3QiUyMHN0YXJ0JTIwJTdEJTIwZnJvbSUyMCU1QyUyMi4lMkZkZWNsYXJlJTVDJTIyJTVDbiU1Q25zdGFydCgpJTVDbiUyMiUyQyUyMmlzRW50cnklMjIlM0F0cnVlJTJDJTIybmFtZSUyMiUzQSUyMm1haW4uanMlMjIlN0QlMkMlN0IlMjJjb2RlJTIyJTNBJTIyaW1wb3J0JTIwJTdCJTIwbnVtJTIwJTdEJTIwZnJvbSUyMCU1QyUyMi4lMkZ1c2UlNUMlMjIlNUNuJTVDbmV4cG9ydCUyMGNsYXNzJTIwTnVtJTIwJTdCJTVDbiUyMCUyMGNvbnN0cnVjdG9yKHZhbHVlKSUyMCU3QiU3RCU1Q24lN0QlNUNuJTVDbmV4cG9ydCUyMGZ1bmN0aW9uJTIwc3RhcnQoKSUyMCU3QiU1Q24lMjAlMjBjb25zb2xlLmxvZyhudW0pJTVDbiU3RCU1Q24lMjIlMkMlMjJpc0VudHJ5JTIyJTNBZmFsc2UlMkMlMjJuYW1lJTIyJTNBJTIyZGVjbGFyZS5qcyUyMiU3RCUyQyU3QiUyMmNvZGUlMjIlM0ElMjJpbXBvcnQlMjAlN0IlMjBOdW0lMjAlN0QlMjBmcm9tJTIwJTVDJTIyLiUyRmRlY2xhcmUlNUMlMjIlNUNuJTVDbmV4cG9ydCUyMGNvbnN0JTIwbnVtJTIwJTNEJTIwbmV3JTIwTnVtKDApJTVDbiUyMiUyQyUyMmlzRW50cnklMjIlM0FmYWxzZSUyQyUyMm5hbWUlMjIlM0ElMjJ1c2UuanMlMjIlN0QlNUQlMkMlMjJvcHRpb25zJTIyJTNBJTdCJTIyb3V0cHV0JTIyJTNBJTdCJTIyZm9ybWF0JTIyJTNBJTIyZXMlMjIlN0QlMkMlMjJ0cmVlc2hha2UlMjIlM0F0cnVlJTdEJTdE

Expected Behaviour

Rollup 4.46.2 struggles to properly order declarations. I think it's a bundler's job to correctly resolve the order of dependencies, that's why I decided to open this issue. Here's the simplest example I could come up with:

Contents of entry.js:

javascript
import { start } from "./declare"

start()

Contents of declare.js:

javascript
import { num } from "./use"

export class Num {
  constructor(value) {}
}

export function start() {
  console.log(num)
}

Contents of use.js:

javascript
import { Num } from "./declare"

export const num = new Num(0)

The correct order could be:

javascript
class Num {
  constructor(value) {}
}

const num = new Num(0);

function start() {
  console.log(num);
}

start();

Actual Behaviour

Rollup's output:

$ pnpx rollup -c

entry.js → stdout...
const num = new Num(0);

class Num {
  constructor(value) {}
}

function start() {
  console.log(num);
}

start();
(!) Circular dependency
declare.js -> use.js -> declare.js

To which browser throws an exception: Uncaught (in promise) ReferenceError: Cannot access 'Num' before initialization.

Surprisingly, I had used Rollup in a 40K LoC monorepo with lots of circular-dependencies and has never had any issues in 1 year of using Rollup. So it's the first time I had caught such a case of incorrectly ordered dependencies. Maybe it's a regression in newer versions? Or maybe I just kept getting lucky all this time.

If it's not a regression then how difficult would it be to implement a fix for cases like that?