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

@flightdev/http

v0.1.0

Published

Ultra-fast HTTP server for Flight Framework - Built on Web Standards

Readme

@flightdev/http

HTTP server for Flight Framework. Built on Web Standard APIs with radix-tree routing for maximum performance. Runs on Node.js, Bun, and Deno.

Table of Contents


Features

  • Radix-tree routing for fast path matching
  • Native Request/Response APIs (Web Standard)
  • Multi-runtime support: Node.js, Bun, Deno
  • Middleware with async/await
  • Type-safe route parameters
  • Built-in helpers for JSON, HTML, redirects
  • Zero external runtime dependencies
  • Full TypeScript support

Installation

npm install @flightdev/http

Quick Start

import { createServer } from '@flightdev/http';
import { serve } from '@flightdev/http/node';

const app = createServer();

app.get('/', (c) => c.json({ message: 'Hello Flight!' }));

app.get('/users/:id', (c) => {
    return c.json({ userId: c.params.id });
});

app.post('/users', async (c) => {
    const body = await c.req.json();
    return c.json({ created: true, user: body }, 201);
});

serve(app, { port: 3000 });
console.log('Server running at http://localhost:3000');

Routing

Register routes using HTTP method helpers:

app.get('/path', handler);      // GET
app.post('/path', handler);     // POST
app.put('/path', handler);      // PUT
app.patch('/path', handler);    // PATCH
app.delete('/path', handler);   // DELETE
app.options('/path', handler);  // OPTIONS
app.head('/path', handler);     // HEAD

// All methods
app.all('/path', handler);

// Multiple methods
app.on(['GET', 'POST'], '/path', handler);

Route Patterns

// Static path
app.get('/about', handler);

// Single parameter
app.get('/users/:id', handler);

// Multiple parameters
app.get('/posts/:year/:month/:slug', handler);

// Optional parameter
app.get('/files/:path?', handler);

// Wildcard (catch-all)
app.get('/assets/*', handler);

// Named wildcard
app.get('/docs/:path*', handler);

Route Parameters

Access route parameters from the context:

// Route: /users/:id/posts/:postId
app.get('/users/:id/posts/:postId', (c) => {
    const { id, postId } = c.params;
    return c.json({ userId: id, postId });
});

// Wildcard parameters
// Route: /files/*
// Request: /files/images/photo.jpg
app.get('/files/*', (c) => {
    const path = c.params['*'];  // "images/photo.jpg"
    return c.text(`File: ${path}`);
});

Type-Safe Parameters

import type { Context } from '@flightdev/http';

interface UserParams {
    id: string;
    postId: string;
}

app.get('/users/:id/posts/:postId', (c: Context<UserParams>) => {
    c.params.id;      // string (typed)
    c.params.postId;  // string (typed)
});

Middleware

Middleware functions run before route handlers:

// Global middleware (runs on all routes)
app.use(async (c, next) => {
    const start = performance.now();
    const response = await next();
    const duration = performance.now() - start;
    console.log(`${c.req.method} ${c.req.url} - ${duration.toFixed(2)}ms`);
    return response;
});

// Path-specific middleware
app.use('/api/*', async (c, next) => {
    // Only runs on /api/* routes
    return next();
});

Authentication Middleware

const authMiddleware = async (c, next) => {
    const token = c.header('Authorization')?.replace('Bearer ', '');
    
    if (!token) {
        return c.json({ error: 'Unauthorized' }, 401);
    }
    
    const user = await verifyToken(token);
    if (!user) {
        return c.json({ error: 'Invalid token' }, 401);
    }
    
    // Store user in context for later use
    c.set('user', user);
    return next();
};

// Apply to specific routes
app.use('/api/*', authMiddleware);

// Access in route handler
app.get('/api/profile', (c) => {
    const user = c.get('user');
    return c.json(user);
});

Middleware Chain

Multiple middleware functions run in order:

app.get('/protected', 
    authMiddleware,
    rateLimitMiddleware,
    validationMiddleware,
    (c) => {
        return c.json({ data: 'secret' });
    }
);

Context API

The context object provides access to request data and response helpers:

app.get('/demo', (c) => {
    // Request object (Web Standard)
    c.req;                    // Request
    c.req.method;             // "GET"
    c.req.url;                // Full URL
    
    // Route parameters
    c.params;                 // { id: "123" }
    c.params.id;              // "123"
    
    // Query parameters
    c.query('page');          // "1" or undefined
    c.query('page', '1');     // "1" (with default)
    c.queries('tags');        // ["a", "b"] (array)
    
    // Headers
    c.header('Content-Type'); // "application/json"
    c.header('X-Custom');     // Custom header value
    
    // Cookies
    c.cookie('session');      // Cookie value
    
    // Context storage
    c.set('key', 'value');    // Store value
    c.get('key');             // Retrieve value
    
    return c.json({ ok: true });
});

Request Handling

JSON Body

app.post('/api/users', async (c) => {
    const body = await c.req.json();
    // body is parsed JSON
    return c.json({ received: body });
});

Form Data

app.post('/upload', async (c) => {
    const form = await c.req.formData();
    const name = form.get('name');
    const file = form.get('file');  // File object
    
    return c.json({ name, fileName: file?.name });
});

Raw Text

app.post('/webhook', async (c) => {
    const text = await c.req.text();
    return c.text(`Received: ${text}`);
});

Raw Binary

app.post('/binary', async (c) => {
    const buffer = await c.req.arrayBuffer();
    return c.json({ bytes: buffer.byteLength });
});

Response Helpers

// JSON response
c.json({ data: 'value' });
c.json({ created: true }, 201);
c.json({ error: 'Not found' }, 404);

// Text response
c.text('Hello, World!');
c.text('Created', 201);

// HTML response
c.html('<h1>Hello</h1>');
c.html('<!DOCTYPE html>...', 200);

// Redirect
c.redirect('/new-location');
c.redirect('/login', 302);      // Temporary (default)
c.redirect('/moved', 301);      // Permanent

// No Content
c.body(null, 204);

// Custom response
return new Response(body, {
    status: 200,
    headers: { 'X-Custom': 'value' },
});

// Set response headers
c.header('X-Request-Id', requestId);
c.header('Cache-Control', 'max-age=3600');

// Set cookies
c.cookie('session', token, {
    httpOnly: true,
    secure: true,
    sameSite: 'Strict',
    maxAge: 60 * 60 * 24,  // 1 day
});

Error Handling

Global Error Handler

app.onError((error, c) => {
    console.error('Error:', error);
    
    if (error instanceof ValidationError) {
        return c.json({ error: error.message }, 400);
    }
    
    return c.json({ error: 'Internal Server Error' }, 500);
});

404 Not Found

app.notFound((c) => {
    return c.json({ 
        error: 'Not Found',
        path: new URL(c.req.url).pathname,
    }, 404);
});

Throwing Errors

import { HTTPException } from '@flightdev/http';

app.get('/protected', (c) => {
    if (!c.get('user')) {
        throw new HTTPException(401, 'Unauthorized');
    }
    return c.json({ secret: 'data' });
});

Sub-Routers

Organize routes into modules:

// routes/users.ts
import { createServer } from '@flightdev/http';

export const users = createServer();

users.get('/', (c) => c.json({ users: [] }));
users.get('/:id', (c) => c.json({ id: c.params.id }));
users.post('/', (c) => c.json({ created: true }));

// main.ts
import { createServer } from '@flightdev/http';
import { users } from './routes/users';

const app = createServer();

// Mount sub-router
app.route('/api/users', users);

// Routes:
// GET  /api/users
// GET  /api/users/:id
// POST /api/users

Runtime Adapters

Node.js

import { createServer } from '@flightdev/http';
import { serve } from '@flightdev/http/node';

const app = createServer();

serve(app, { 
    port: 3000,
    hostname: '0.0.0.0',
});

Bun

import { createServer } from '@flightdev/http';
import { serve } from '@flightdev/http/bun';

const app = createServer();

serve(app, { port: 3000 });

// Or use Bun's native API
Bun.serve({
    port: 3000,
    fetch: app.fetch,
});

Deno

import { createServer } from '@flightdev/http';
import { serve } from '@flightdev/http/deno';

const app = createServer();

serve(app, { port: 3000 });

// Or use Deno's native API
Deno.serve({ port: 3000 }, app.fetch);

Cloudflare Workers

import { createServer } from '@flightdev/http';

const app = createServer();

// ... define routes

export default {
    fetch: app.fetch,
};

Static Files

Serve static files from a directory:

import { serveStatic } from '@flightdev/http/static';

// Serve from 'public' directory
app.use('/static/*', serveStatic({ root: './public' }));

// With options
app.use('/assets/*', serveStatic({
    root: './assets',
    maxAge: 60 * 60 * 24,  // 1 day cache
    index: 'index.html',
}));

CORS

Enable Cross-Origin Resource Sharing:

import { cors } from '@flightdev/http/cors';

// Allow all origins
app.use(cors());

// Specific origins
app.use(cors({
    origin: 'https://example.com',
    methods: ['GET', 'POST', 'PUT', 'DELETE'],
    headers: ['Content-Type', 'Authorization'],
    credentials: true,
    maxAge: 86400,
}));

// Dynamic origin
app.use(cors({
    origin: (origin) => {
        return origin.endsWith('.example.com');
    },
}));

API Reference

createServer(options?)

Create a new Flight HTTP server.

| Option | Type | Default | Description | |--------|------|---------|-------------| | strict | boolean | true | Strict routing (trailing slash matters) | | getPath | function | - | Custom path extraction |

Context Methods

| Method | Description | |--------|-------------| | c.req | Web Standard Request object | | c.params | Route parameters | | c.query(name, default?) | Get query parameter | | c.queries(name) | Get all values for query param | | c.header(name) | Get request header | | c.cookie(name) | Get cookie value | | c.set(key, value) | Store value in context | | c.get(key) | Retrieve value from context | | c.json(data, status?) | JSON response | | c.text(text, status?) | Text response | | c.html(html, status?) | HTML response | | c.redirect(url, status?) | Redirect response | | c.body(body, status?) | Raw body response |

App Methods

| Method | Description | |--------|-------------| | app.get/post/put/delete/patch(path, ...handlers) | Register route | | app.all(path, ...handlers) | All HTTP methods | | app.on(methods[], path, ...handlers) | Specific methods | | app.use(...middleware) | Add middleware | | app.use(path, ...middleware) | Path-specific middleware | | app.route(path, subRouter) | Mount sub-router | | app.notFound(handler) | Custom 404 handler | | app.onError(handler) | Custom error handler | | app.fetch(request) | Handle request (Web Standard) |


License

MIT