What version of Elysia is running?
[email protected]
What version of Node Adapter are you using?
@elysiajs/[email protected]
What platform is your computer?
Microsoft Windows NT 10.0.26200.0 x64
What steps can reproduce the bug?
When using Elysia with the Node adapter, the server can begin handling requests before promised modules added via .use(...) have finished resolving.
In practice, this means routes or static assets registered by async plugins are not available immediately after listen(). For example, @elysiajs/static can return NOT_FOUND unless the plugin is manually awaited before being passed to .use(...).
This looks specific to the Node adapter lifecycle. The Bun adapter updates the running server after promised modules resolve, but the Node adapter serves immediately and does not refresh its handler once async plugins finish loading.
import { Elysia } from 'elysia'
import { node } from '@elysiajs/node'
new Elysia({ adapter: node() })
.use(
new Promise((resolve) => {
setTimeout(() => {
resolve(new Elysia().get('/async-plugin', 'ok'))
}, 25)
})
)
.listen(3000)
Then request:
GET http://127.0.0.1:3000/async-plugin
A more realistic example is:
app.use(staticPlugin(...))
where the static plugin resolves asynchronously and the route can initially return NOT_FOUND on Node unless it is manually awaited.
What is the expected behavior?
Async plugins should work without requiring manual await before .use(...).
Once promised modules resolve, routes and assets registered by those plugins should be available automatically. In other words, this should work as expected:
app.use(staticPlugin(...))
and should not require:
app.use(await staticPlugin(...))
What do you see instead?
The server starts accepting requests before async plugins have finished registering their routes.
As a result, routes or static assets added by those plugins can be missing right after startup. For example:
- /async-plugin returns NOT_FOUND
- static files served by @elysiajs/static return NOT_FOUND
The route becomes available only if the plugin is awaited manually before calling .use(...), or if the adapter refreshes its handler after promised modules resolve.
Additional information
I was able to reproduce this with a minimal regression test for both CommonJS and ESM entrypoints in the Node adapter repo.
The issue appears to be adapter-specific rather than a general Elysia async plugin issue. Bun does not appear to have the same behavior because it updates the running server after promised modules resolve.
The likely root cause is that @elysiajs/node begins serving with the initial handler and does not refresh the active fetch and websocket handling after app.promisedModules resolves.
Have you try removing the node_modules and bun.lockb and try again yet?
Yes
What version of Elysia is running?
[email protected]
What version of Node Adapter are you using?
@elysiajs/[email protected]
What platform is your computer?
Microsoft Windows NT 10.0.26200.0 x64
What steps can reproduce the bug?
When using Elysia with the Node adapter, the server can begin handling requests before promised modules added via .use(...) have finished resolving.
In practice, this means routes or static assets registered by async plugins are not available immediately after listen(). For example, @elysiajs/static can return NOT_FOUND unless the plugin is manually awaited before being passed to .use(...).
This looks specific to the Node adapter lifecycle. The Bun adapter updates the running server after promised modules resolve, but the Node adapter serves immediately and does not refresh its handler once async plugins finish loading.
Then request:
GET http://127.0.0.1:3000/async-pluginA more realistic example is:
where the static plugin resolves asynchronously and the route can initially return NOT_FOUND on Node unless it is manually awaited.
What is the expected behavior?
Async plugins should work without requiring manual await before .use(...).
Once promised modules resolve, routes and assets registered by those plugins should be available automatically. In other words, this should work as expected:
and should not require:
What do you see instead?
The server starts accepting requests before async plugins have finished registering their routes.
As a result, routes or static assets added by those plugins can be missing right after startup. For example:
The route becomes available only if the plugin is awaited manually before calling .use(...), or if the adapter refreshes its handler after promised modules resolve.
Additional information
I was able to reproduce this with a minimal regression test for both CommonJS and ESM entrypoints in the Node adapter repo.
The issue appears to be adapter-specific rather than a general Elysia async plugin issue. Bun does not appear to have the same behavior because it updates the running server after promised modules resolve.
The likely root cause is that @elysiajs/node begins serving with the initial handler and does not refresh the active fetch and websocket handling after
app.promisedModulesresolves.Have you try removing the
node_modulesandbun.lockband try again yet?Yes