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

nexus-backend

v1.1.1

Published

Backend utility library for Express.js

Readme

Nexus Backend

A lightweight backend utility library for Express.js providing structured error classes, standardised API response helpers, and a plug-and-play error handling middleware.


Table of Contents


Installation


npm install express mongoose cors helmet morgan cookie-parser

Express, mongoose, cors, helmet, morgan, and cookie-parser are peer dependencies — make sure they are installed in your project:

npm install nexus-backend

Quick Start

// src/config/mongoConfig.ts
import { requiredEnv, type MongoConfig } from "nexus-backend";

const dbConfig: MongoConfig = {
  subDomain: requiredEnv(process.env.DB_HOST, "DB_HOST"),
  userName: requiredEnv(process.env.DB_USERNAME, "DB_USERNAME"),
  password: requiredEnv(process.env.DB_PASSWORD, "DB_PASSWORD"),
  cluster: requiredEnv(process.env.DB_CLUSTER, "DB_CLUSTER"),
  dbName: requiredEnv(process.env.DB_NAME, "DB_NAME"),
};
export default dbConfig;
// src/server.ts
import express, { type Application, Request, Response } from "express";
import http from "http";
import {
  successResponse,
  errorMiddleware,
  NotFoundError,
  ValidationError,
} from "nexus-backend";
import cors from "cors";
import helmet from "helmet";
import morgan from "morgan";
import cookieParser from "cookie-parser";
import { Server } from "socket.io";

const app: Application = express();

if (process.env.NODE_ENV !== "production") {
  app.use(morgan("dev"));
}
app.set("trust proxy", 1);
app.use(helmet());
app.use(
  cors({
    origin: process.env.FRONTEND_URL,
    credentials: true,
  }),
);

app.use(express.json({ limit: "500mb" })); // Adjust the limit as needed
app.use(express.urlencoded({ extended: true, limit: "500mb" })); // For parsing application/x-www-form-urlencoded
app.use(cookieParser());

// Example route
app.get("/users/:id", async (req: Request, res: Response) => {
  const user = await getUserById(req.params.id);

  if (!user) {
    throw new NotFoundError("User not found");
  }

  res.json(successResponse(user, "User fetched successfully"));
});

// Register error middleware last
app.use(errorMiddleware);
const server = http.createServer(app);
export const io = new Server(server, {
  cors: {
    origin: process.env.FRONTEND_URL,
    credentials: true,
  },
});

export default server;
// src/index.ts
import "dotenv/config";
import { connectMongoDb } from "nexus-backend";
import dns from "dns";
import dbConfig from "./config/mongoConfig";
import server from "./server";
const PORT = process.env.PORT || 5000;
async () => {
  dns.setServers(["1.1.1.1", "1.0.0.1"]);
  const dbConnected = await connectMongoDb(dbConfig);
  if (!dbConnected) {
    console.error("Database connection failed. Exiting...");
    process.exit(1);
  }
  server.listen(PORT, () => {
    console.log(`Server running on ${PORT}`);
  });
};

API Reference

Response Helpers

successResponse(data, message?)

Returns a structured success payload. Pass the result directly to res.json().

successResponse<T>(data: T, message?: string): SuccessResponse<T>

Example

res
  .status(200)
  .json(successResponse({ id: 1, name: "Alice" }, "User fetched successfully"));
{
  "success": true,
  "message": "User fetched successfully",
  "data": { "id": 1, "name": "Alice" }
}

errorResponse(message, errors?, stack?)

Returns a structured error payload. You will rarely call this directly — errorMiddleware calls it internally. Useful if you need to construct an error response manually.

errorResponse(message: string, errors?: any, stack?: string): ErrorResponse

Example

res
  .status(400)
  .json(
    errorResponse("Validation failed", { field: "email", issue: "Required" }),
  );
{
  "success": false,
  "message": "Validation failed",
  "errors": { "field": "email", "issue": "Required" }
}

Error Classes

All error classes extend the base ApiError class, which itself extends the native Error. Throw any of these inside a route and let errorMiddleware handle the rest.

ApiError

The base error class. Use this when none of the specific subclasses fit your use case.

new ApiError(message: string, statusCode?: number, errors?: any, isOperational?: boolean)

| Parameter | Type | Default | Description | | --------------- | --------- | ----------- | ------------------------------------------------ | | message | string | — | Human-readable error message | | statusCode | number | 500 | HTTP status code | | errors | any | undefined | Additional error details or field errors | | isOperational | boolean | true | Marks the error as an expected operational error |


BadRequestError

Status: 400 Bad Request

Use when the client sends a malformed or invalid request.

throw new BadRequestError("Invalid request body");

UnauthorizedError

Status: 401 Unauthorized

Use when authentication is missing or invalid.

throw new UnauthorizedError("Invalid token");

ForbiddenError

Status: 403 Forbidden

Use when an authenticated user lacks permission to access a resource.

throw new ForbiddenError("You do not have access to this resource");

NotFoundError

Status: 404 Not Found

Use when a requested resource does not exist.

throw new NotFoundError("Post not found");

ValidationError

Status: 422 Unprocessable Entity

Use when request data fails validation. Pass field-level errors via the errors argument.

throw new ValidationError("Validation failed", [
  { field: "email", message: "Must be a valid email address" },
  { field: "password", message: "Must be at least 8 characters" },
]);

Error Middleware

errorMiddleware

An Express-compatible error handling middleware. It catches any error passed to next(err), determines the appropriate HTTP status code and message, and sends a structured ErrorResponse.

Register it after all routes and other middleware.

import { errorMiddleware } from "nexusjs";

app.use(errorMiddleware);

Behaviour

  • If the error is an instance of ApiError (or any subclass), the middleware uses the error's own statusCode and message.
  • For all other unhandled errors, it falls back to 500 Internal Server Error.
  • When NODE_ENV is set to "development", the response includes a stack field with the full stack trace to aid debugging. The stack field is omitted in production.

Development response example

{
  "success": false,
  "message": "User not found",
  "errors": null,
  "stack": "NotFoundError: User not found\n    at ..."
}

Response Shape

All responses follow a consistent structure.

Success

interface SuccessResponse<T> {
  success: true;
  message?: string;
  data: T;
}

Error

interface ErrorResponse {
  success: false;
  message: string;
  errors?: any;
  stack?: string; // only present in development
}

TypeScript

nexusjs is written in TypeScript and ships with type declarations out of the box. No @types package is needed.

SuccessResponse and ErrorResponse are exported and can be used to type your own response wrappers or API clients:

import type { SuccessResponse, ErrorResponse } from "nexusjs";

type ApiResult<T> = SuccessResponse<T> | ErrorResponse;

License

MIT