A powerful but lightweight node server built using web standards
npm install @shgysk8zer0/http-server@shgysk8zer0/http-serverA powerful but lightweight node server built using web standards

!Node CI
!Lint Code Base





!node-current
!npm bundle size gzipped


!GitHub forks
!GitHub stars


- - -
- Code of Conduct
- Contributing
A lightweight, modern Node.js HTTP server built entirely around Web Standards. Created to bridge the gap between Node.js servers and native browser APIs, making server-side development feel more familiar to frontend developers.
Request and Response objects for handling HTTPAbortSignal and timeoutsimport()URLPattern for flexible routingWritten in pure ESM and providing a flexible configuration system, this server brings the power and familiarity of Web APIs to your Node.js backend. Whether serving static files, creating a dev server, or building a full API, you'll work with the same standards-based interfaces you already know from frontend development.
| Flag | Alias | Default | Description |
|------|--------|---------|-------------|
| --hostname | -h | localhost | The hostname to serve on |
| --port | -p | 8000 | The port number to listen on |
| --path | -a | / | The path relative to project root to use for the default URL |
| --static | -s | / | Root directory for static files |
| --open | -o | false | Open in default browser when server starts |
| --timeout | -t | undefined | Server timeout in milliseconds |
| --config | -c | undefined | Path to config file |
| --debugger | -d | false | Enables logging of errors via console.error |
bash
npx @shgysk8zer0/http-server
`$3
`bash
npx @shgysk8zer0/http-server --port=3000 --hostname=0.0.0.0
`$3
`bash
npx @shgysk8zer0/http-server --static=./public
`$3
`bash
npx @shgysk8zer0/http-server --config=./http.config.js
`Example
http.config.js:
`js
const controller = new AbortController();export default {
staticRoot: '/static/',
routes: {
'/favicon.svg': '@shgysk8zer0/http-server/api/favicon.js',
'/tasks': '@shgysk8zer0/http-server/api/tasks.js',
},
staticPaths: ['/'],
port: 8000,
signal: controller.signal,
open: true,
};
`Using as a Module
The server can be imported and configured programmatically:`js
import { serve } from '@shgysk8zer0/http-server';const controller = new AbortController();
const config = {
port: 3000,
hostname: 'localhost',
staticRoot: '/public/',
routes: {
'/api/data': './routes/data.js',
'/api/tasks/:taskId': './routes/tasks.js',
'/posts/:year(20\\d{2})/:month(0?\\d|[0-2])/:day(0?[1-9]|[12]\\d|3[01])/:post([a-z0-9\-]+[a-z0-9])': '/js/routes/posts.js',
},
open: true,
signal: controller.signal,
};
const { url, server, whenServerClosed } = await serve(config);
console.log(
Server running at ${url});const resp = await fetch(new URL('/posts/2025/01/30/hello-world', url));
const { title, description, content, author } = await resp.json();
// Handle cleanup when done
controller.abort();
whenServerClosed.then(() => console.log(server, 'closed'));
`$3
`js
export default async function(req) {
switch(req.method) {
case 'GET': {
const url = new URL(req.url);
const params = url.searchParams;
return Response.json(Object.fromEntries(params)); }
case 'POST': {
const data = await req.formData();
// Handle request with form data
}
}
}
`Request & Response Middleware
The server provides a powerful middleware system through
requestPreprocessors and responsePostprocessors, offering
deep control over the request/response lifecycle.$3
Request preprocessors run before route handling and can:
- Filter/block requests
- Modify the request object
- Enhance the request context with additional data
- Perform validation or authentication
- Add logging or monitoring
- Abort requests early
- Skip request handling with aborting request or cached response
- Mutate the
context object with eg geoip dataEach preprocessor receives the request object and a context object containing:
-
ip - Remote IP address
- url - Complete request URL
- cookies - Cookie management
- controller - Request's abort controller
- signal - Abort signal for the request$3
Run on
Responses returned by handlers (or cache) that can:- Add headers to responses, such as CORS
- Add responses to a cache
- Pipe response streams through transform streams such as
CompressionStream using resp.body.pipeThrough()`Both types of middleware can be provided as direct functions, importable modules, or factory functions that return
configurable handlers. The system's flexibility allows you to compose complex request/response pipelines while
maintaining clean separation of concerns.