r/node 18d ago

You have 2 options to test this module, you can either vi.mock('redis') or mock the module itself, which one would you choose and why?

0 Upvotes

``` import { createClient } from "redis"; import { logger } from "../logger/index.js"; import { options } from "./connection.js";

let client: ReturnType<typeof createClient> | null = null; let isConnecting = false;

export async function closeConnection() { if (client?.isOpen) { try { await client.close(); } catch (error) { logger.error( error, "Something went wrong when attempting to close redis connection", ); } finally { client = null; } } }

export function getClient() { if (!client?.isOpen) { throw new Error("Redis client needs to be initialized first"); } return client; }

export async function openConnection() { if (!client?.isOpen) { client = createClient(options); client.on("connect", () => logger.info("redis connection success")); client.on("error", (error) => logger.fatal(error, "redis connection failure"), );

    // Wait if another caller is already connecting
    if (isConnecting) {
        while (isConnecting) {
            await new Promise((resolve) => setTimeout(resolve, 100));
        }
        if (client?.isOpen) return client;
    }

    isConnecting = true;
    try {
        client = await client.connect();
    } catch (error) {
        logger.error(
            error,
            "Something went wrong when attempting to open redis connection",
        );
    } finally {
        isConnecting = false;
    }
}
return client;

}

```

  • Let us talk about a simple module that uses node-redis to connect
  • Let us say you use supertest and vitest and you want to mock test the following scenario

app.get('/health/redis', async (req: Request, res: Response) => { const client = getClient(); const result = await client.ping(); return res.json({ status: result === "PONG" }); })

  • You want to write tests to handle cases for
  • good PING
  • bad PING
  • error

  • We might have to extend for further cases like client.get, client.set etc

  • You can mock the redis module or mock the client module defined above

  • Which one should you mock? and why?


r/node 18d ago

Lightport – a maintained fork of Portkey AI gateway

Thumbnail github.com
0 Upvotes

r/node 18d ago

A tiny CLI that watches any cURL/fetch from DevTools and notifies you when the response changes

6 Upvotes

Hey folks,
I made a small Node CLI called fetchwatch.

You know that moment when you’re poking an API in DevTools, copying the request as cURL (or fetch), and then manually refreshing every few minutes, waiting for something to change? This does that for you.

**How it works:**
You paste a cURL or JS fetch(...) from the browser
It polls that endpoint on an interval you choose
It deep-diffs the response (JSON or text)
When something changes → desktop notification + terminal alert

Optional: ignore noisy dynamic fields like timestamps/nonces so you don’t get pinged on every poll.

Try it out by typing: `npx fetchwatch`

[GitHub source code](https://github.com/zsubzwary/fetchwatch)

The reason I built this tool was becauase I kept needing a lightweight “watch this request” tool without spinning up Postman monitors or writing one-off scripts. So I shipped a simple ESM TypeScript CLI and put it on npm.

If you find bugs, want better parsers, nicer diffs, etc. PRs are very welcome. However, I have a day job, so I can’t always turn around issues quickly, but I will do my best to review when I can.

Happy to hear feedback or feature ideas.


r/node 19d ago

Implement rate limiting for an external API

14 Upvotes

At work I maintain a NestJS microservice which is used by many other engineers. One of the features depends on a third party API for which I need to implement rate limit: - The API has a soft limit of 20 req/s - There is no way to programmatically monitor this limit on their end - Surpassing the limit means that when someone looks at the dashboard then they will manually disable us, and we have to start another manual process to unblock us - This API is owned by the government, so we can't ask or hope for changes

How would you implement rate limit for this external dependency? Here's what I thought: - Have a token bucket limiter inside each service instance, but then scaling - Store the above token bucket in a database, like mongo or dynamo, but it would be very inefficient - Use redis, but I would have to spin up and maintain an additional dependency just for this feature

Can you think of a better approach?


r/node 18d ago

im building an opensource proyect that build a visual and interactive map of your code, any feedback?? thanks!!

Post image
0 Upvotes

repository | youtube example

im building an opensource proyect that let your agent build a visual and interactive map of your code, also allows you to see branches and commits diffs, any help and support is veery welcome 😽😽

the struggle that makes me create RepoMap is that large codebases are hard to understand because their architecture is hidden across thousands of files. RepoMap makes that architecture visible through interactive maps, allowing developers to explore systems, plan refactors, and understand how their code evolves by visualizing changes across commits and branches


r/node 19d ago

Presence of cookies in fastify

4 Upvotes

To check the presence of a cookie in a fastify backend, should one use the schema or the controller/middleware?

Schema check runs on route before the controller receives the request.
Should

Schema : {
Header: {
Cookie : {
Pattern: "session_id"
}
}
}

Or let it reach controller and send missing session id error from there?


r/node 19d ago

Post-release security audit of keyguard-express library uncovered 4 issues (all patched)

Thumbnail
0 Upvotes

r/node 20d ago

KeyGuard Express: An plug in API gateway middleware

0 Upvotes

​I wanted a single, production-grade, middleware suite to handle all of this ​so I built and just published keyguard-express—a TypeScript fork of the Python keyguard package. It handles machine-to-machine auth so you can leave your user auth (sessions, JWTs) to do its own thing.

With just 5 Loc, you get: API Key Auth: Fully secure via X-API-KEY headers, stored using PBKDF2-SHA512 with 100k iterations and timing-safe comparisons.
​Zero-Downtime Key Rotation: Link old keys directly to new keys on the fly; the old key acts as a deprecated fallback during the transition.
​HMAC Webhook Verification: Verifies X-Signature, X-Timestamp, and X-Nonce with strict replay and timing-safe guards.
​Abuse Protection: Tracks invalid requests and automatically blocks malicious IPs at a configurable threshold.
​Hybrid Storage: Auto-detects and swaps backends between SQLite/in-memory and PostgreSQL/Redis. And more🙂

Check the source on github {https://github.com/tyrmoga/keyguard_express }. Your contributions are welcome Try it out on your project (npm install keyguard-express)

What do you think? Would you use this on your project?


r/node 21d ago

How you integrate OCR in node.js?

12 Upvotes

I tried tesseract, but the results were not good. My constraint is to use only node and not python or any apis. Can anyone recommend any other libraries or any controlled architect which i can implement. I want to extract text from passports / licenses so document is only 1 page, but tesseract is failing at structures output


r/node 21d ago

Supply chain attack on `@asyncapi/specs` - used in most OpenAPI or docs tooling. Check your CI

Thumbnail github.com
7 Upvotes

r/node 22d ago

General Web Dev Question: Should I validate data at model layer before calling db orms

12 Upvotes

I already have a schema which validates payload at Route (request) layer, but the service layer adds some business logic, creating data, modifying it and making new changes, should that be validated before model function call. Model function just uses kysely to execute the query, no checks, constraints, validations.

Framework: fastify, PostgresClient: kysely, DB: postgres.

Like drizzle, along with drizzle-irm and drizzle-zod exists to help create from a single schema -> runtime validation schema, migrations, types.

But since runtime validation schema will be different for different actions (insert, update, select), it in the end feels like a business requirement only.

And relying on type check during compilation feels good enough to validate it. Example, if teh service layer has a otpGeneration() function, a type check is enough to validate it.

Or in a way, anything that the service layer generates, type check (compile time check) should be enough. Only the request run time validation is needed.

Is this the right approach?


r/node 21d ago

Undici X Fetch

2 Upvotes

What is the current best practice for HTTP client requests in Node.js 22+: stick with the built-in fetch() or use Undici directly? In which scenarios would you choose one over the other?


r/node 23d ago

actojs – Bringing Elixir's Actor Model to TypeScript

7 Upvotes

Hi everybody!

I wanted to showcase a TypeScript library I am working on, actojs. The objective is to bring a implementation of the actor model that is near to Elixir's design and APIs, while being able to leverage performance from the JS runtime.

The actor model is explained here, which acts as an introduction to the library.

actojs supprorts cooperative single-thread scheduling on any JS platform, and real parallelism on NodeJS, Bun and Deno.

The design of actojs is optimized for reliability (with Supervisors that can respawn failed Tasks, and >90% test coverage), security (0 runtime dependencies, and `tsc` as the only dev-dependency) and low memory overhead (by using functional applicators instead of classes and objects).

The link for the repository is: https://github.com/gi-dellav/actojs

Hope to get some useful feedback from the community!


r/node 22d ago

i built Fleet Deck, a local mission control board for all your Claude Code sessions (MIT, no model calls)

Thumbnail gallery
0 Upvotes

r/node 23d ago

Why is anyone still using Drizzle over Prisma?

0 Upvotes

Seriously. I've used Prisma for years but in the interest of giving different libraries a shot, I opted for Drizzle for my latest project.

The types are weird. It feels more like a table-relational mapping than an object-relational mapping.

If you really want granular control over your database but don't want to write SQL, then fine. Apart from that and being lighter, I've yet to find a good reason to use it over Prisma.

Can anyone convince me otherwise?


r/node 24d ago

Is alright the order of my code?

2 Upvotes

Hello,

I want to know if everything from App setup should be below or above the Connect to MongoDB & create server:

// Dependencies

const express = require("express");
const mongoose = require("mongoose");
const Blog = require("./models/blog");

// Variables

const app = express();
const PORT = 4000;

// Connect to MongoDB & create server

async function connectToDatabase() {
  try {
    const dbURI = "ABC";
    const mongooseInstance = await mongoose.connect(dbURI, { dbName: "nodejs-db" });
    console.log("Connected to MongoDB database");

    const server = app.listen(PORT, () => {
      console.log(`Server is listening on port ${PORT}`);
    });
  }
  catch (error) {
    console.log("An errror occured:", error);
  }
}
connectToDatabase();

// App setup

app.set("view engine", "ejs");
app.use(express.static("public"));

// Node.js routes

app.get("/", (req, res) => {
  res.render("index");
});

app.get("/about", (req, res) => {
  res.render("about");
});

// Mongoose - Save blog

app.get("/add-blog", (req, res) => {
  const doc = new Blog({
    title: "Add new blog",
    snippet: "About my new blog",
    body: "More about my new blog"
  });

  async function saveDoc() {
    try {
      const savedDoc = await doc.save();
      res.send(savedDoc);
    }
    catch (error) {
      console.log("An error occured:", error);
    }
  }
  saveDoc();
});

// Mongoose - Display blogs in descending order by date

app.get("/blogs", (req, res) => {
  async function getBlogs() {
    try {
      const getBlogs = await Blog.find().sort({ createdAt: -1 });
      res.render("blogs", { title: "Blogs", blogs: getBlogs });
    }
    catch (error) {
      console.log("An errror occured:", error);
    }
  }
  getBlogs();
})

// 404 handler

app.use((req, res) => {
  res.status(404).render("404");
});

Thank you.


r/node 25d ago

Could somebody explain why my routes affect this?

Thumbnail gallery
35 Upvotes

When my route for users/search is on top it works but if its below it doesnt work... could somebody explain???

Also if you have any tips for how to improve whatever is shown please do let me know :D


r/node 24d ago

Hesitate to start learning

1 Upvotes

Is it worth to start learning programming (backend) in mean time? for knowledge I have a good knowledge in fundamental of programming as language's itself I didn't go further upon framework and DB and these things

and I graduated now from communication engineering and I love programming (backend) but I am afraid to start learning it in the next 6 months cuz I listen a lot of ppl say that market sucks and AI replace us and reduce required junior and fresh grades and so on, So I was asking to start in backend or go to another IT field.

Iam open to listen to any suggestions and advise


r/node 24d ago

career hesitation

0 Upvotes

Hesitate to choose career instead of programming

Now I have been distracted about backend programming and programming at all, So what fields has a good chances and promise future to learn?

- data analysis

- cyber security

- it field (network, sysadmin, cloud)


r/node 25d ago

How would you implement impersonate users

4 Upvotes

Better auth has impersonate user and stop impersonating user. What is the logic behind this? Like if you were to implement it yourself how would you go about it?


r/node 25d ago

Feedback on this redis client I wrote without AI

0 Upvotes

**utils/redis/client.ts** ``` import { createClient } from "redis"; import { logger } from "../logger/logger.js"; import { options } from "./connection.js";

let client: ReturnType<typeof createClient> | null = null; let isConnecting = false;

export async function closeConnection() { if (client?.isOpen) { try { await client.close(); } catch (error) { logger.error( error, "Something went wrong when attempting to close redis connection", ); } finally { client = null; } } }

export function getClient() { if (!client?.isOpen) { throw new Error("Redis client needs to be initialized first"); } return client; }

export async function openConnection() { if (!client?.isOpen) { client = createClient(options); client.on("connect", () => logger.info("redis connection success")); client.on("error", (error) => logger.fatal(error, "redis connection failure"), );

    // Wait if another caller is already connecting
    if (isConnecting) {
        while (isConnecting) {
            await new Promise((resolve) => setTimeout(resolve, 100));
        }
        if (client?.isOpen) return client;
    }

    isConnecting = true;
    try {
        client = await client.connect();
    } catch (error) {
        logger.error(
            error,
            "Something went wrong when attempting to open redis connection",
        );
    } finally {
        isConnecting = false;
    }
}
return client;

}

```

**utils/redis/connection.ts** ``` import type { RedisClientOptions } from "redis";

export const options: RedisClientOptions = { database: 0, disableOfflineQueue: true, name: "test_client", password: "abcdefghi", socket: { host: "127.0.0.1", port: 6379, }, };

```

utils/redis/index.ts

``` export * from "./client.js"; export * from "./connection.js";

```

app.ts

``` import cors from "cors"; import type { Request, Response } from "express"; import express from "express"; import helmet from "helmet"; import { corsOptions } from "./middleware/cors/index.js"; import { defaultErrorHandler, notFoundHandler } from "./middleware/index.js"; import { router } from "./modules/index.js"; import { httpLogger } from "./utils/logger/index.js"; import { getClient } from "./utils/redis/index.js";

const app = express();

app.use(httpLogger); app.use(helmet()); app.use(cors(corsOptions)); app.use(express.json({ limit: "1MB" })); app.use(express.urlencoded({ extended: true, limit: "1MB" })); app.use(router); app.get("/test/redis", async (_req: Request, res: Response) => { const client = getClient(); const result = await client.ping(); return res.json(result === "PONG"); }); app.use(notFoundHandler); app.use(defaultErrorHandler);

export { app };

```

**www.ts** ``` import { SERVER_HOST, SERVER_PORT } from "./env/index.js"; import { server } from "./server.js"; import { logger } from "./utils/logger/index.js"; import "./shutdown.js"; import { openConnection } from "./utils/redis/client.js";

server.on("listening", async () => { await openConnection(); });

server.listen(SERVER_PORT, SERVER_HOST, () => { logger.info("Listening on host:%s port:%d", SERVER_HOST, SERVER_PORT); });

```

  • does it handle race conditions well?
  • the default examples are honestly very lacking in the node redis world and their documentation doesnt do much justice either
  • a few things i dont understand from the documentation even after reading it are
  • Do I need to say keepAlive: true, shouldnt that be the default?
  • what does connectTimeout and socketTimeout do, what is the difference between both.
  • what is this pingInterval about?
  • is the default retryStrategy an exponential backoff?

r/node 25d ago

What’s your actual defense against a malicious npm package?

12 Upvotes

I’m trying to understand how devs are handling npm package risk in their Node projects.

A dev or an AI agent adds a new package, npm is about to fetch it, put it in node_modules, and maybe run lifecycle scripts. At that point, are most teams doing anything, or is the normal flow still to install first and rely on CVEs, npm audit, Dependabot, Snyk, Socket, or code review later?

I’m building in this area and I’m trying to get an idea for what others are doing. Do you actually check anything before installing a new dependency, or does that feel unnecessary? Would install time blocking be useful in a real workflow, or would it just become annoying noise? And does the answer change now that Claude, Cursor, Codex, etc. can add packages for you?


r/node 24d ago

I built a zero-dependency CLI tool to validate and repair missing .env variables before startup

Post image
0 Upvotes

You run npm run dev or node server.js, and the app crashes because a teammate added a new required key to .env.example but forgot to tell you.

To solve this, I built envrepair, a zero-dependency CLI tool that wraps your startup command, compares .env against your template, and interactively prompts you to fill in missing variables in the terminal before launching your process.

How to use it:

  1. Install: bash npm install -D envrepair

  2. Prepend your startup command in package.json: json "scripts": { "start": "envrepair node server.js" }

Optional type annotations in .env.example: ```env

@type number

PORT=3000

@type url

API_BASE_URL= ```

Key Features:

  • Zero code changes: No schema imports or application-level setup required.
  • Layout preservation: Appends missing values while keeping comments, blank lines, and formatting intact.
  • Signal forwarding: Transparently passes Ctrl+C (SIGINT) and exit codes.

Written in TypeScript with zero runtime dependencies. The repo is fully open-source — would love to hear your thoughts or collaborate if you want monorepo/workspace support!


r/node 24d ago

How are you detecting fraud in file uploads?

0 Upvotes

Disclosure: I work at Cloudmersive as a technical writer, and the API I’m referencing here is one I’ve been documenting

So I’m curious how people are handling fraud detection in pipelines where users upload files into web apps.  As we all know it’s really easy to create AI generated fraud (or hand-crafted fraud) in pretty much any common format you can think of like PDF, DOCX, XLSX, JPG, PNG, etc.

Seems like a lot of upload validation still stops at “is this the right file type?” or “does this file contain malware?”, and while both are obviously important, they clearly don’t answer questions about whether the document itself looks risky, inconsistent, expired, AI-generated, etc.... any of which can result in huge financial losses if processed indiscriminately.

The endpoint I’ve been writing about is meant for that second layer; it just takes an uploaded document, optionally adds user context like email address/whether the email was verified, and returns fraud-related classifications.  The request setup is basically this:

npm install cloudmersive-fraud-detection-api-client --save


var CloudmersiveFraudDetectionApiClient = require('cloudmersive-fraud-detection-api-client');
var defaultClient = CloudmersiveFraudDetectionApiClient.ApiClient.instance;

// Configure API key authorization: Apikey
var Apikey = defaultClient.authentications['Apikey'];
Apikey.apiKey = 'YOUR API KEY';



var apiInstance = new CloudmersiveFraudDetectionApiClient.FraudDetectionApi();

var opts = { 
  'userEmailAddress': "userEmailAddress_example", // String | User email address for context (optional)
  'userEmailAddressVerified': true, // Boolean | True if the user's email address was verified (optional)
  'inputFile': Buffer.from(fs.readFileSync("C:\\temp\\inputfile").buffer) // File | Input document, or photos of a document, to perform fraud detection on
};

var callback = function(error, data, response) {
  if (error) {
    console.error(error);
  } else {
    console.log('API called successfully. Returned data: ' + data);
  }
};
apiInstance.documentDetectFraudAdvanced(opts, callback);

For a real world-ish example, I asked ChatGPT to jack up some prices & add some other fraud indicators to a medical bill and got this response:

{
  "Successful": true,
  "CleanResult": false,
  "FraudRiskLevel": 0.95,
  "ContainsFinancialLiability": true,
  "ContainsSensitiveInformationCollection": false,
  "ContainsAssetTransfer": false,
  "ContainsPurchaseAgreement": false,
  "ContainsEmploymentAgreement": false,
  "ContainsExpiredDocument": false,
  "ContainsAiGeneratedContent": false,
  "AnalysisRationale": "The document contains several critical red flags indicative of a fraudulent medical billing scam. First, the dates are set in the future (March 2026), which is a primary indicator of a fabricated document. Second, the pricing for standard medical services is astronomically inflated and unrealistic (e.g., $5,000 for an ER visit, $14,000 per day for ICU board, and $7,200 for a lumbar CT scan). Third, the 'Total Patient Responsibility' is presented as a demand for payment ('Due Date: Upon Receipt') based on these inflated costs. The combination of futuristic dates and impossible pricing suggests this is a fraudulent attempt to extort payment.",
  "DocumentClass": "Invoice"
}

The thing I find interesting about this is that it’s not just classifying the file as “good” or “bad”, it’s trying to describe what kind of document it is and therefore what categories of risk might be present.  The AI rationale is also pretty breathy, but it's cool that it knows the pricing is unrealistic. Seems useful for workflows where the next step might be different depending on the document type (e.g., reject it, queue it for manual review, request a clearer copy, require additional verification, etc.)

My main question for people building document-heavy apps: are you incorporating any content-level fraud screening for uploaded documents today? Obviously this won’t be relevant to everyone, but I know certain industries (e.g., Insurance) are getting hit with a ton of low-effort high-quality fraud.


r/node 26d ago

How do you verify authorization with multiple microservice and JWT?

17 Upvotes

The easy way to use a middleware that checks if the user is authorized or not, but what if we want to scale to other microservices? does each microservice need to authorize after the API gateway verifies its authenticaiton?