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

jsonbash

v1.2.0

Published

Blazing-fast, standardized JSON API response builder with built-in Rate Limiter, AES-256 Encryption, Pagination, Field Picker, Express middleware, http-status-codes, and TypeScript support.

Readme

JsonBash ⚡

A blazing-fast (46M+ ops/sec), feature-packed JSON API response framework for Node.js & Express. Features built-in Express Rate Limiter, AES-256-GCM Payload Encryption & Decryption, Selective Field Picker (pick), Data Sanitization (sanitize), Pagination, Validation Error formatting, http-status-codes integration, and native TypeScript support.


📋 Table of Contents


🚀 Why JsonBash?

  • Unified API Responses: Gives every API endpoint in your backend a consistent, predictable JSON schema.
  • Blazing Performance: Optimized for V8 engine execution (46+ million operations/sec with zero hidden-class de-optimizations).
  • 🚦 Express Rate Limiter Built-in: Configure global or route-level rate limiting (rateLimit: { windowMs, max }) returning structured HTTP 429 responses.
  • 🔒 AES-256-GCM Encryption: Zero-dependency payload encryption and decryption for high-security APIs.
  • 🎯 Field Picker (pick) & Sanitizer (sanitize): Filter allowed fields or mask sensitive data recursively before sending.
  • 📊 Pagination & Validation: Auto-calculates totalPages, hasNextPage, and formats Zod/Joi/Express-Validator errors cleanly.
  • http-status-codes Included: Re-exports all HTTP constants (StatusCodes.OK, ReasonPhrases.NOT_FOUND, etc.) out-of-the-box.
  • Express Ready: Attach response helpers (res.jsonbash.success(), res.jsonbash.paginate(), res.jsonbash.pick()) with one line of middleware.

📐 Standard API Response Schema

All responses generated by jsonbash follow this clean, intuitive structure:

{
  "success": true,
  "statusCode": 200,
  "statusText": "OK",
  "message": "User list retrieved successfully",
  "data": [
    { "id": 1, "name": "Harshil Kaneria" }
  ]
}

| Property | Type | Description | | :--- | :--- | :--- | | success | boolean | true for 2xx status codes; false for 4xx/5xx error codes. | | statusCode | number | The HTTP status code (e.g. 200, 201, 400, 404, 422, 429, 500). | | statusText | string | Standard HTTP reason phrase (e.g. "OK", "Not Found", "Too Many Requests"). | | message | string | Human-readable response summary or message. | | encrypted | boolean | (Optional) Set to true when data payload is encrypted via AES-256-GCM. | | iv | string | (Optional) Initialization vector hex string for decryption. | | authTag | string | (Optional) GCM authentication tag hex string for security integrity. | | data | any | (Optional) Main response payload (or ciphertext string if encrypted). | | pagination | object | (Optional) Pagination details (page, limit, totalItems, totalPages, hasNextPage, hasPrevPage). | | errors | array | (Optional) Array of validation errors ([{ field, message }]). | | retryAfterSeconds | number | (Optional) Included on HTTP 429 Rate Limit responses. | | ...extra | any | (Optional) Any custom extra properties (e.g., executionTimeMs, timestamp). |


📦 Installation

npm install jsonbash

💻 Usage Examples

1. Express Middleware & Global Configuration

Register jsonbash.middleware() at the top of your Express app to attach res.jsonbash methods to every route. You can configure Global Encryption and Global Rate Limiting in one single call:

const express = require('express');
const jsonbash = require('jsonbash');

const app = express();
app.use(express.json());

// Enable Global Encryption AND Global Rate Limiting across your whole Express app!
app.use(jsonbash.middleware({
  encryptKey: 'my-global-super-secret-key-32-chars', // Global AES-256 Encryption Key
  rateLimit: {
    windowMs: 15 * 60 * 1000, // 15 minutes window
    max: 100,                 // Max 100 requests per IP per window
    message: 'Global rate limit reached, please try again later'
  }
}));

// Route 1 - Automatically Rate Limited & Encrypted via Global Config
app.get('/api/users', (req, res) => {
  const users = [{ id: 1, name: 'Harshil Kaneria' }];
  return res.jsonbash.success(users, 'Users fetched successfully');
});

app.listen(3000, () => console.log('Server running on port 3000'));

2. Semantic Helper Methods

Semantic helper methods provide instant, pre-configured HTTP status response builders for Node.js & Express.

jsonbash.success(data, message, statusCode, extra) — HTTP 200 OK

const response = jsonbash.success({ id: 1, name: 'Harshil' }, 'User details retrieved');

JSON Response Output:

{
  "success": true,
  "statusCode": 200,
  "statusText": "OK",
  "message": "User details retrieved",
  "data": { "id": 1, "name": "Harshil" }
}

jsonbash.created(data, message, extra) — HTTP 201 Created

const response = jsonbash.created({ id: 99, email: '[email protected]' }, 'Account created successfully');

JSON Response Output:

{
  "success": true,
  "statusCode": 201,
  "statusText": "Created",
  "message": "Account created successfully",
  "data": { "id": 99, "email": "[email protected]" }
}

jsonbash.badRequest(message, data, extra) — HTTP 400 Bad Request

const response = jsonbash.badRequest('Invalid parameter format');

JSON Response Output:

{
  "success": false,
  "statusCode": 400,
  "statusText": "Bad Request",
  "message": "Invalid parameter format"
}

jsonbash.unauthorized(message, data, extra) — HTTP 401 Unauthorized

const response = jsonbash.unauthorized('Authentication bearer token missing or expired');

JSON Response Output:

{
  "success": false,
  "statusCode": 401,
  "statusText": "Unauthorized",
  "message": "Authentication bearer token missing or expired"
}

jsonbash.forbidden(message, data, extra) — HTTP 403 Forbidden

const response = jsonbash.forbidden('Insufficient permissions to access resource');

JSON Response Output:

{
  "success": false,
  "statusCode": 403,
  "statusText": "Forbidden",
  "message": "Insufficient permissions to access resource"
}

jsonbash.notFound(message, data, extra) — HTTP 404 Not Found

const response = jsonbash.notFound('Requested user profile not found');

JSON Response Output:

{
  "success": false,
  "statusCode": 404,
  "statusText": "Not Found",
  "message": "Requested user profile not found"
}

jsonbash.tooManyRequests(message, data, extra) — HTTP 429 Too Many Requests

const response = jsonbash.tooManyRequests('Rate limit exceeded, please slow down');

JSON Response Output:

{
  "success": false,
  "statusCode": 429,
  "statusText": "Too Many Requests",
  "message": "Rate limit exceeded, please slow down"
}

jsonbash.internalServerError(message, data, extra) — HTTP 500 Internal Server Error

const response = jsonbash.internalServerError('Database connection timeout');

JSON Response Output:

{
  "success": false,
  "statusCode": 500,
  "statusText": "Internal Server Error",
  "message": "Database connection timeout"
}

jsonbash.error(message, statusCode, data, extra) — Generic Custom Error

const response = jsonbash.error('Service temporarily under maintenance', 503);

JSON Response Output:

{
  "success": false,
  "statusCode": 503,
  "statusText": "Service Unavailable",
  "message": "Service temporarily under maintenance"
}

3. Express Rate Limiter: Global & Route-Level (jsonbash.rateLimiter)

Protect your Express endpoints against DDoS and brute-force attacks with zero external dependencies.

Option A: Global Rate Limiting (Across Entire App)

Set rate limiting globally inside jsonbash.middleware():

app.use(jsonbash.middleware({
  rateLimit: {
    windowMs: 15 * 60 * 1000, // 15 minutes window
    max: 100,                 // Limit each client IP to 100 requests per window
    message: 'Global rate limit reached, please try again later'
  }
}));

Option B: Route-Level / Individual Endpoint Rate Limiting

Apply strict custom rate limits to sensitive routes (e.g. Login, Password Reset, OTP verification):

// Protect login route with max 5 requests per 1 minute per IP
app.post('/api/login', jsonbash.rateLimiter({
  windowMs: 60 * 1000, // 1 minute
  max: 5,              // Max 5 attempts
  message: 'Too many login attempts, please try again in a minute'
}), (req, res) => {
  return res.jsonbash.success({ token: 'jwt_token' }, 'Login successful');
});

JSON Output when Rate Limit is exceeded (HTTP 429 Too Many Requests):

{
  "success": false,
  "statusCode": 429,
  "statusText": "Too Many Requests",
  "message": "Too many login attempts, please try again in a minute",
  "retryAfterSeconds": 58,
  "limit": 5
}

Sets standard HTTP rate-limit headers automatically: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, and Retry-After.


4. Data Filtering: Selective Picking (pick) & Sanitization (sanitize)

Filter payloads cleanly before sending over the network:

Selective Field Picker (pick)

Select only specific allowed fields from objects or data arrays:

const rawUser = {
  id: 101,
  username: 'harshil_k',
  email: '[email protected]',
  passwordHash: '$2b$10$...',
  internalFlags: { admin: true }
};

// Includes ONLY 'id', 'username', and 'email' in data output!
res.jsonbash.success(rawUser, 'User profile', 200, {
  pick: ['id', 'username', 'email']
});

JSON Output:

{
  "success": true,
  "statusCode": 200,
  "statusText": "OK",
  "message": "User profile",
  "data": {
    "id": 101,
    "username": "harshil_k",
    "email": "[email protected]"
  }
}

Data Sanitization (sanitize)

Strip sensitive keys recursively from objects or data arrays:

// Automatically strips 'password' & 'twoFactorSecret' from output!
res.jsonbash.success(userProfile, 'User profile fetched', 200, {
  sanitize: ['password', 'twoFactorSecret']
});

Standalone Utility Functions

const pickedData = jsonbash.pick(dataArray, ['id', 'name', 'price']);
const sanitizedData = jsonbash.sanitize(rawData, ['password', 'ssn']);

5. AES-256-GCM Payload Encryption & Decryption (Global & Route-Level)

Zero-dependency payload encryption and decryption using Node's native C++ crypto module.

Option A: Global Encryption (Across Entire App)

Set encryptKey in jsonbash.middleware() to automatically encrypt response data payloads across all Express routes:

app.use(jsonbash.middleware({
  encryptKey: 'my-global-super-secret-key-32-chars'
}));

Option B: Route-Level / Individual Endpoint Encryption

Override the global key or encrypt a specific route with a custom key:

app.get('/api/top-secret', (req, res) => {
  const secretData = { bankAccount: 'CHASE-998127398', balance: 75000.00 };

  // Encrypts using a key specific to this route!
  return res.jsonbash.success(secretData, 'Top secret payload', 200, {
    encrypt: 'route-specific-secret-key-777'
  });
});

Option C: Per-Endpoint Skip (encrypt: false)

Skip global encryption for specific public endpoints to return plain unencrypted JSON:

app.get('/api/public-info', (req, res) => {
  return res.jsonbash.success(publicData, 'Public operational data', 200, {
    encrypt: false // 👈 Skips global encryption for this endpoint!
  });
});

Encrypted Response Output:

{
  "success": true,
  "statusCode": 200,
  "statusText": "OK",
  "message": "Sensitive data",
  "encrypted": true,
  "iv": "e9d589f364bce7ab7db112d8",
  "authTag": "8aa4fa8d4b3fa988a99037c76a04b047",
  "data": "c40089992aa5f24e5c247f8dbfcc9f1f218ed..."
}

Option D: Standalone Payload Decryption (jsonbash.decrypt)

Use jsonbash.decrypt(encryptedPayload, secretKey) anywhere in Node.js to decrypt ciphertext payloads back to original objects:

const jsonbash = require('jsonbash');

const decryptedData = jsonbash.decrypt(encryptedResponsePayload, 'route-specific-secret-key-777');

console.log(decryptedData);
// Output: { bankAccount: "CHASE-998127398", balance: 75000 }

6. Pagination Helper (jsonbash.paginate)

Auto-calculates totalPages, hasNextPage, and hasPrevPage automatically:

app.get('/api/products/paginated', (req, res) => {
  const page = parseInt(req.query.page || 1, 10);
  const limit = parseInt(req.query.limit || 5, 10);

  const products = [
    { id: 1, name: 'Headphones', price: 99.99 },
    { id: 2, name: 'Keyboard', price: 149.50 }
  ];

  return res.jsonbash.paginate(products, { page, limit, totalItems: 45 }, 'Products fetched');
});

JSON Output:

{
  "success": true,
  "statusCode": 200,
  "statusText": "OK",
  "message": "Products fetched",
  "data": [
    { "id": 1, "name": "Headphones", "price": 99.99 },
    { "id": 2, "name": "Keyboard", "price": 149.50 }
  ],
  "pagination": {
    "page": 1,
    "limit": 5,
    "totalItems": 45,
    "totalPages": 9,
    "hasNextPage": true,
    "hasPrevPage": false
  }
}

7. Validation Error Formatter (jsonbash.validationError)

Formats error objects from Zod, Joi, Express-Validator, or custom objects into a clean, uniform list under HTTP 422 Unprocessable Entity:

app.post('/api/register', (req, res) => {
  const zodResult = schema.safeParse(req.body);

  if (!zodResult.success) {
    return res.jsonbash.validationError(zodResult.error, 'Invalid input parameters');
  }
});

JSON Output (HTTP 422):

{
  "success": false,
  "statusCode": 422,
  "statusText": "Unprocessable Entity",
  "message": "Invalid input parameters",
  "errors": [
    { "field": "email", "message": "Invalid email address format" },
    { "field": "password", "message": "String must contain at least 8 character(s)" }
  ]
}

8. Global Express Error Handler (jsonbash.errorHandler)

Catch uncaught exceptions across Express routes:

app.get('/api/crash', (req, res, next) => {
  throw new Error('Database connection failed');
});

// Register Global Error Handler at the bottom of all routes
app.use(jsonbash.errorHandler({ stackTrace: process.env.NODE_ENV !== 'production' }));

JSON Output (HTTP 500):

{
  "success": false,
  "statusCode": 500,
  "statusText": "Internal Server Error",
  "message": "Database connection failed",
  "stack": "Error: Database connection failed at ..."
}

9. Custom Response Builder (jsonbash.build)

const jsonbash = require('jsonbash');

const response = jsonbash.build({
  success: true,
  statusCode: jsonbash.StatusCodes.ACCEPTED, // 202
  message: 'Background task scheduled',
  data: { taskId: 'task_88123' },
  executionTimeMs: 14.2,
  timestamp: new Date().toISOString()
});

10. Built-in http-status-codes Re-exports

const {
  StatusCodes,
  ReasonPhrases,
  getReasonPhrase,
  getStatusCode
} = require('jsonbash');

console.log(StatusCodes.OK);                    // 200
console.log(StatusCodes.TOO_MANY_REQUESTS);     // 429
console.log(ReasonPhrases.OK);                  // "OK"

11. Direct Express Sender (jsonbash.send)

app.get('/api/products', (req, res) => {
  const products = [{ id: 101, title: 'Laptop' }];
  return jsonbash.send(res, 200, 'Products loaded', products);
});

12. Standard Function Call

const jsonbash = require('jsonbash');

const data = { id: 1, username: 'harshil' };
const result = jsonbash(true, "Data Fetch Successfully", data, { version: "v1" });

📘 TypeScript Support

import jsonbash, { StatusCodes, JsonBashResponse, RateLimiterOptions } from 'jsonbash';

const response: JsonBashResponse<{ id: number }> = jsonbash.success(
  { id: 1 },
  'Typed success response',
  StatusCodes.OK
);

📄 License

MIT