Skip to content

Conversation

@nounder
Copy link
Contributor

@nounder nounder commented Feb 9, 2026

When using bun --hot, each module re-evaluation creates a new program causing
memory leaks.

Here we ensure only one active runtime exists at any time by cleaning up
on each hot reload.

When using `bun --hot`, each module re-evaluation creates a new program causing
memory leaks.

Here we ensure only one active runtime exists at any time, and cleanup
on each hot reload.
@nounder nounder requested a review from tim-smart as a code owner February 9, 2026 15:57
@github-project-automation github-project-automation bot moved this to Discussion Ongoing in PR Backlog Feb 9, 2026
@changeset-bot
Copy link

changeset-bot bot commented Feb 9, 2026

🦋 Changeset detected

Latest commit: c3b9780

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@effect/platform-bun Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@nounder
Copy link
Contributor Author

nounder commented Feb 9, 2026

I'm not sure why we need keepAlive timer here. I've used this version of runMain minus timer and it's been working well for last couple of weeks. Does anyone remember why was it added in the first place? Maybe it's only needed in node?

if (hmrState.keepAlive) {
clearInterval(hmrState.keepAlive)
}
hmrState.fiber.unsafeInterruptAsFork(hmrState.fiber.id())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will probably need to wait for the previous fiber to exit before starting another one, in the case there are long running finalizers that could hold ports open.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When bun is --hot, Bun automatically updates server handles on subsequent runs so there's no port holding. My initial implementation waited for previous program to finalize but that caused intermissions in-between, similar to what happens when --watch is used.

Since --hot is explicit and opt-in, I think current behavior makes sense. I think even React hot reloading via react-fast-refresh is executing new tree and running cleanup after vdom compare.

@tim-smart
Copy link
Contributor

I'm not sure why we need keepAlive timer here

For the case where nothing will keep the event loop busy.

In node this would exit the program immediately, not sure about bun

runMain(Effect.async<void>(() => {}))

@nounder
Copy link
Contributor Author

nounder commented Feb 10, 2026

Just did a test on Bun and it does indeed exits without keep alive timer. Make sense since it aims for full node compat. In my codebase where I tested it without that timer I must have had some dangling timers.

Also added changeset and a comment about interruption behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Discussion Ongoing

Development

Successfully merging this pull request may close these issues.

2 participants