npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

wave.http

v1.3.1

Published

A lightweight and flexible Node.js HTTP framework

Readme

wave.http

A lightweight and flexible Node.js HTTP framework with built-in routing, static file serving, and EJS template support.

Features

  • 🚀 Simple and intuitive API
  • 🛣️ Express-like routing system
  • 📁 Static file serving with caching options
  • 🍪 Cookie management
  • 📝 EJS template rendering
  • 📤 File upload handling with progress tracking
  • 🔄 Request body parsing (JSON, URL-encoded, text)
  • ⚡ Zero external dependencies (except EJS)

Installation

npm install wave.http

Quick Start

const App = require("wave.http");

const app = new App();
const router = new App.Router();

router.on("GET", "/", (req, res) => {
    res.send("Hello World!");
});

app.addRouter(router);
app.listen(3000);

Documentation

App

The main entry point for your HTTP server.

Usage

const App = require("wave.http");
const app = new App();

Methods

  • addRouter(router)
    Attach a Router instance to the app.

    app.addRouter(router);
  • listen(port, callback?)
    Start the HTTP server.

    app.listen(3000, () => {
        console.log("App running on port 3000");
    });

Router

Handles route and static file registration.

Usage

const router = new App.Router([baseUrl]);
  • baseUrl (optional): Prefix for all routes and static paths in this router.

Methods

  • on(method, path, handler)
    Register a route handler.

    • method: HTTP method (GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD, or *)
    • path: Route path (supports parameters, e.g. /user/:id)
    • handler(req, res): Function to handle the request
    router.on("GET", "/users/:id", (req, res) => {
        res.json({ id: req.params.id });
    });
  • addStatic(url, local, options?)
    Serve static files from a directory.

    • url: URL prefix (e.g. /assets)
    • local: Local directory path (e.g. __dirname + "/public")
    • options (optional):
      • maxAge: Cache duration in seconds
      • useLastModified: Use Last-Modified/If-Modified-Since headers
      • dynamicImageFormats: Array of image formats for dynamic negotiation (e.g. ["webp", "png", "jpg"])
    router.addStatic("/assets", "./public", {
        maxAge: 3600,
        dynamicImageFormats: ["webp", "png", "jpg"]
    });

Request Object

Extends Node's IncomingMessage:

  • req.params: Route parameters (object)
  • req.searchParams: Query parameters (object)
  • req.cookies: Parsed cookies (object)
  • req.body.buffer([options]): Get raw body as Buffer (Promise)
  • req.body.text([options]): Get body as string (Promise)
  • req.body.json([options]): Get body as JSON (Promise)
  • req.body.urlencoded([options]): Get body as object (Promise)

Body options:

  • maxFileSize: Maximum allowed size in bytes
  • onUploadProgress: Callback for upload progress

Example:

router.on("POST", "/data", async (req, res) => {
    const data = await req.body.json();
    res.json({ received: data });
});

Response Object

Extends Node's ServerResponse:

  • res.send(str): Send a string response
  • res.status(code): Set status code (chainable)
  • res.json(obj): Send JSON response
  • res.sendStatus(code): Send status code and default message
  • res.redirect(path): Redirect to another path
  • res.render(path, data): Render EJS template
  • res.setCookie(name, value, attrs?): Set a cookie
  • res.clearCookie(name): Clear a cookie

Example:

res.status(201).json({ created: true });
res.setCookie("token", "abc", { httpOnly: true, maxAge: 3600000 });

Static File Serving

  • Supports cache control via maxAge or useLastModified
  • Supports dynamic image format negotiation via dynamicImageFormats and the Accept header or ?format=... query

Example:

router.addStatic("/img", "./images", {
    maxAge: 86400,
    dynamicImageFormats: ["webp", "png", "jpg"]
});

Utilities

Available as App.utils:

  • formatBytes(bytes, fixed?): Format bytes as human-readable string
  • formatTime(seconds): Format seconds as human-readable string
  • setCookie(name, value, attrs?): Generate a Set-Cookie header string
  • parseCookie(header): Parse a Cookie header string

Example:

const { formatBytes, formatTime } = App.utils;
console.log(formatBytes(2048)); // "2 KB"
console.log(formatTime(90)); // "1 minute"