Skip to content

@elysiajs/node starts serving before async plugins resolve #58

@rubenferreira97

Description

@rubenferreira97

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions