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 🙏

© 2025 – Pkg Stats / Ryan Hefner

biscuitsjar

v1.0.21

Published

A minimal and high-performance Node.js framework with advanced routing, validation, middleware, and error handling.

Downloads

30

Readme

Biscuit Framework with Custom Hook System

Introduction

Biscuit is a lightweight and flexible HTTP server framework for Node.js, built to provide a robust Hook system for managing request flow, authentication, error handling, and middleware execution. It includes a custom router and advanced hook management, making it highly customizable and extensible.


Features

🍪: Custom Hook System

  • Define pre-request, post-response, and error-handling hooks.
  • Attach hooks to specific routes or apply them globally.
  • Priority-based execution for hooks.
  • Conditional Execution: Hooks can run only if specific conditions are met.
  • Cancellation Support using AbortController.
  • Execution Limits & Lifetimes to control hook invocation.

🍪:Built-in Router

  • Supports GET, POST, PUT, DELETE, PATCH methods.
  • Dynamic route parameter handling (/api/user/:id).
  • Middleware-like execution via hooks.

🍪:Advanced Response Handling

  • Automatic JSON serialization.
  • Streaming support for large responses.
  • Custom status code hooks to handle different HTTP statuses.

🍪:Error Handling & Logging

  • Hooks can capture and handle errors gracefully.
  • Global error hooks ensure stability.
  • Custom event emitters for debugging.

Installation

npm install biscuitsjar

Usage

  • Initializing the Framework
const Biscuit = require('./Biscuit');
const app = new Biscuit();

  • Defining Routes
app.route('GET', '/api/hello', async (req, res) => {
  res.send({ message: 'Hello, World!' });
});

app.route('POST', '/api/data', async (req, res) => {
  res.send({ message: 'Data received' }, 201);
});

Hook System Usage

Biscuit's hook system allows attaching custom behavior to different parts of the request lifecycle.

Request Hooks (atReq)

Executed when a request is received.

app.hook.atReq('/api/data', async (req, res) => {
  console.log('Processing request:', req.url);
}, { priority: 50 });

Response Hooks (atRes)

Executed before sending the response.

app.hook.atRes('/api/data', async (req, res) => {
  console.log('Finalizing response for:', req.url);
});

Authentication Hooks (atAuth)

Executed before route processing to enforce authentication.

app.hook.atAuth('/secure', async (req, res) => {
  if (!req.headers.authorization) {
    throw new Error('Unauthorized');
  }
});

Route-Specific Hooks (atRoute)

Executed after the route handler.

app.hook.atRoute('/api/users', async (req, res) => {
  console.log('Route logic executed');
});

Error Handling Hooks (atErr)

Executed when an error occurs.

app.hook.atErr('/api/data', async (req, res) => {
  console.error('Handling error for:', req.url);
});

Status-Based Hooks (atStatus)

Executed when a specific HTTP status is set.

app.hook.atStatus(404, async (req, res) => {
  console.warn('Handling 404 error.');
});

Pre and Post Hooks

Define pre-processing and post-processing hooks for more granular control.

app.hook.preHook('atReq', '/api/data', async (req, res) => {
  console.log('Pre-processing request...');
});

app.hook.postHook('atReq', '/api/data', async (req, res) => {
  console.log('Post-processing request...');
});

Removing Hooks

Hooks can be removed dynamically.

app.hook.removeHook('atReq', '/api/data', someFunction);

Event Handling

Biscuit provides an event system for handling errors and debugging.

app.hook.on('error', (err) => {
  console.error('Hook Error:', err);
});

Starting the Server

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

Detailed Explanation of Biscuit Components

Hook System

The Hook system in Biscuit allows developers to attach middleware-like functions at different request lifecycle stages.

Hook Structure

Each hook has:

  • Function (fn): The function to execute.

  • Lifetime (lifetime): How long the hook remains active.

  • Execution Limit (maxExecutions): Maximum times it can be executed.

  • Condition (condition): A function that must return true for execution.

  • Priority (priority): Determines execution order.


Router System

Biscuit's Router is designed to handle: 🍪: Static Routes (/api/users) 🍪: Dynamic Routes (/api/user/:id) 🍪:Method-Specific Routes (GET, POST, etc.) 🍪:Query Parameters & URL Parsing

Example:
app.route('GET', '/api/user/:id', async (req, res) => {
  res.send({ userId: req.params.id });
});

Response System

Biscuit provides enhanced response handling: 🍪 Automatic JSON Serialization 🍪:Streaming Support for large data 🍪:Custom Status Codes & Status-Based Hooks

Example:
res.send({ message: "Success" }, 200);

Advanced Features

Streaming Response Handling

For large datasets, use streaming instead of sending entire data at once.

const fs = require('fs');
app.route('GET', '/download', (req, res) => {
  const fileStream = fs.createReadStream('largefile.txt');
  res.send(fileStream);
});

Global Middleware via Hooks

Example of a global request logger:

app.hook.atReq(async (req, res) => {
  console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
});

Graceful Shutdown Handling

To ensure proper cleanup when the server shuts down:

process.on('SIGTERM', () => {
  console.log("Shutting down server...");
  app.server.close(() => {
    console.log("Server closed.");
  });
});

Final Thoughts

Biscuit is designed to be lightweight, flexible, and highly customizable. The powerful Hook system allows developers to modify request flow, add authentication, handle errors, and customize routing seamlessly.

Why Choose Biscuit?
  • Minimal & Efficient – No unnecessary bloat.
  • Extensible – Hooks provide deep customization.
  • Custom Router & Middleware Support – Control over request handling.
  • Error Handling – Robust debugging capabilities.

License

MIT License. See the LICENSE file for more details

Conclusion

Biscuit is designed for speed, flexibility, and security. Whether you're building a simple API or a complex system, its modular approach and built-in optimizations make development seamless.

This README is now in a fully formatted Markdown structure. Let me know if you need any modifications or additions!