@shgysk8zer0/http-server v1.1.1
@shgysk8zer0/http-server
A powerful but lightweight node server built using web standards
- Code of Conduct
- ContributingA 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.
Key Features
- Uses native
Request
andResponse
objects for handling HTTP - Built-in support for
AbortSignal
and timeouts - Dynamic imports using standard ESM
import()
- Modern URL handling with
URLPattern
for flexible routing - Standards-first - if it exists in the browser, we use it in Node
- Familiar API for frontend developers
Written 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.
CLI Arguments
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 |
Usage Examples
Basic Static Server
npx @shgysk8zer0/http-server
Custom Port and Hostname
npx @shgysk8zer0/http-server --port=3000 --hostname=0.0.0.0
Serve Static Files from Directory
npx @shgysk8zer0/http-server --static=./public
Using Config File
npx @shgysk8zer0/http-server --config=./http.config.js
Example http.config.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:
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'));
Example route/endpoint
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.
Request Preprocessors
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 data
Each preprocessor receives the request object and a context object containing:
ip
- Remote IP addressurl
- Complete request URLcookies
- Cookie managementcontroller
- Request's abort controllersignal
- Abort signal for the request
Response Postprocessors
Run on Response
s 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
usingresp.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.