Skip to content

Conversation

@chadxz
Copy link
Contributor

@chadxz chadxz commented Nov 27, 2025

Summary

Usage

import node from '@hono/vite-build/node'

export default defineConfig({
  plugins: [
    node({
      entry: './src/index.ts',
      shutdownTimeoutMs: 10000,  // 10s timeout before force exit
    }),
  ],
})

Options:

  • undefined (default): No graceful shutdown (existing behavior)
  • shutdownTimeoutMs: 10000: Graceful shutdown with 10s timeout
  • shutdownTimeoutMs: 0: Graceful shutdown, wait indefinitely

Test plan

  • Added unit tests for all three behaviors
  • Manually tested with sample app - confirmed clean exit on SIGINT

@changeset-bot
Copy link

changeset-bot bot commented Nov 27, 2025

🦋 Changeset detected

Latest commit: 4e9343f

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

This PR includes changesets to release 1 package
Name Type
@hono/vite-build Minor

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

Why?
====

When running a Node.js server built with `@hono/vite-build/node` in Docker or
Kubernetes, pressing Ctrl+C (SIGINT) or receiving SIGTERM doesn't gracefully
close the server. This means connections aren't drained properly, and the
process often needs to be force-killed. This addresses GitHub issue honojs#219.

How?
====

Added a new `shutdownTimeoutMs` option to the Node adapter:

- `undefined` (default): No graceful shutdown (preserves existing behavior)
- `shutdownTimeoutMs: 10000`: Enable graceful shutdown with 10s timeout
- `shutdownTimeoutMs: 0`: Enable graceful shutdown, wait indefinitely

When enabled, the generated code captures the server instance and registers
handlers for SIGINT and SIGTERM that call `server.close()` and exit cleanly.
If a timeout is specified, a fallback `setTimeout(...).unref()` forces exit
after the timeout expires.

Testing
=======

Added unit tests verifying:
- Default behavior generates no shutdown handling code
- Setting `shutdownTimeoutMs` generates signal handlers and timeout
- Setting `shutdownTimeoutMs: 0` generates handlers without timeout

Manually tested by building a sample app with the feature enabled, starting
the server, and sending SIGINT. Confirmed:
- With graceful shutdown: exits with code 0
- Without graceful shutdown: exits with signal SIGINT (null exit code)
@chadxz chadxz force-pushed the node-graceful-shutdown branch from 4d824bb to 4e9343f Compare November 27, 2025 05:21
@chadxz
Copy link
Contributor Author

chadxz commented Nov 27, 2025

@yusukebe lmk if you'd rather it default to on. I defaulted it to off because it seemed the safest path forward.

Copy link
Member

@yusukebe yusukebe left a comment

Choose a reason for hiding this comment

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

LGTM!

@yusukebe
Copy link
Member

Hi @chadxz

Thank you for the quick work. Making off by default is okay. Looks good. Merging!

@yusukebe yusukebe merged commit d9ecb01 into honojs:main Nov 27, 2025
5 checks passed
@github-actions github-actions bot mentioned this pull request Nov 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants