Overview

Start an Express server with proper production configuration. Use this as your main server entry point.

Features

  • Graceful shutdown on SIGTERM/SIGINT
  • CORS and Helmet pre-configured
  • Health check endpoint included
  • Environment-based port configuration

Installation

npx hanma add express-server

Dependencies

express, cors, helmet

Code

import http from "http";
import express from "express";
import cors from "cors";
import helmet from "helmet";

const app = express();
const server = http.createServer(app);

// Track active connections for graceful shutdown
const sockets = new Set<import("net").Socket>();

server.on("connection", (socket) => {
  sockets.add(socket);
  socket.on("close", () => sockets.delete(socket));
});

// Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
app.use(helmet());

// Health check endpoint
app.get("/health", (_req, res) => {
  res.status(200).json({ status: "ok", timestamp: new Date().toISOString() });
});

// TODO: Add your routes here
// app.use("/api", yourRouter);

// 404 handler
app.use((_req, res) => {
  res.status(404).json({ success: false, message: "Resource not found" });
});

// Error handler
app.use((err: Error, _req: express.Request, res: express.Response, _next: express.NextFunction) => {
  console.error("[ERROR]", err.stack || err.message);
  res.status(500).json({
    success: false,
    message: process.env.NODE_ENV === "development" ? err.message : "Internal Server Error",
  });
});

const PORT = process.env.PORT || 3000;

export const startServer = async () => {
  if (server.listening) {
    console.log("Server already running");
    return;
  }

  try {
    server.listen(PORT, () => {
      console.log(`Server running on http://localhost:${PORT}`);
      console.log(`Health check: http://localhost:${PORT}/health`);
    });
  } catch (err) {
    console.error("Failed to start server:", err);
    process.exit(1);
  }
};

export const shutdown = async (signal: string) => {
  console.log(`\n${signal} received. Shutting down gracefully...`);

  server.close(() => {
    console.log("HTTP server closed");
    process.exit(0);
  });

  // Force shutdown after 10s
  setTimeout(() => {
    console.warn(
      `Grace period expired. Forcing close of ${sockets.size} remaining connection(s).`
    );
    sockets.forEach((socket) => socket.destroy());
    process.exit(1);
  }, 10000).unref();
};


/* usage

import { startServer, shutdown } from "@libs/server";
 

startServer();

process.on("SIGTERM", () => shutdown("SIGTERM"));
process.on("SIGINT", () => shutdown("SIGINT"));

process.on("unhandledRejection", (reason, p) => {
  console.error("Unhandled Rejection at:", p, "reason:", reason);
});

process.on("uncaughtException", (err) => {
  console.error("Uncaught Exception:", err);
  process.exit(1);
});

*/

Usage

import { createServer } from './libs/server';

const app = createServer();
app.listen(process.env.PORT || 3000);

Dependencies

Frequently Asked Questions

How do I install Express Server?
Run the following command: npx hanma add express-server
What dependencies are required?
This snippet requires: express, cors, helmet. Make sure to install them before using the snippet.
How do I use this snippet?
Copy the code and paste it into your project. The snippet will be saved to libs/server.ts.
Can I customize this snippet?
Yes! All snippets are copy-paste code that you own. Feel free to modify them to fit your needs.
Does this work with other frameworks?
This snippet is designed for the specific framework. Check the other framework pages for equivalent implementations.