Library to help you create a context that can be used to reference data, without prop drilling, in Node-based environments.
The inspiration comes from the concept of Context in React.
Prop drilling is the process of getting data from component A to component Z by passing it through multiple layers of intermediary React components. Instead of manually passing props down, Context provides a way to share values between components.
Passing data to child functions in Node-based environments is a challenge. You could use a static class that works as your storage, but in cases where the application might be accessed in parallel, this approach fails. There is a definite need for a context-like concept.
Instead of doing this:
callFunction1(originalData) {
callFunction2(someData, originalData);
}
callFunction2(someData, originalData) {
processOtherDataToo(someData);
callFunction3(originalData);
}
callFunction3(originalData) {
callFunction4(originalData);
}
callFunction4(originalData) {
useTheOriginalDataFinally(originalData);
}
You can do this:
callFunction1(originalData) {
Context.set(originalData);
callFunction2(someData);
}
callFunction2(someData) {
processOtherDataToo(someData);
callFunction3();
}
callFunction3() {
callFunction4();
}
callFunction4() {
const data = Context.get();
useTheOriginalDataFinally(data);
}
The library uses Async Local Storage internally, which provides an API to track the lifetime of asynchronous resources in a Node application.
Install with npm:
npm install @theinternetfolks/context
Install with pnpm:
pnpm add @theinternetfolks/context
Install with bun:
bun add @theinternetfolks/context
Install with yarn:
yarn add @theinternetfolks/context
- Lightweight implementation using native
AsyncLocalStorage
- TypeScript typings with interfaces support
- Works with all kinds of async functions (
Promises
,Timeouts
,TCPWrap
,UDP
, etc.)
const { Context } = require("@theinternetfolks/context");
const SomeFunction = () => {
const data = Context.get();
console.log(`Name: ${data.name}`);
};
(() => {
Context.init(); // initialize the context for this run
Context.set({ name: "The Internet Folks" });
SomeFunction();
})();
Output:
Name: The Internet Folks
const { Context } = require("@theinternetfolks/context");
const ChildFunction = () => {
const data = Context.get();
console.log(`Name from Context: ${data.name} in Child`);
};
const ParentFunction = () => {
const data = Context.get();
console.log(`Name from Context: ${data.name} in Parent`);
ChildFunction();
};
(() => {
Context.init(); // initialize the context for this run
Context.set({ name: "The Internet Folks" });
ParentFunction();
})();
const express = require("express");
const { Context } = require("@theinternetfolks/context");
const app = express();
app.use(express.json());
app.use((req, res, next) => {
Context.init(); // initialize the context for the request
Context.set({ host: req.get("host") });
next();
});
app.get("/", (req, res) => {
const data = Context.get();
return res.json({ host: data?.host });
});
app.listen(3000, () => {
console.log("Server running on port 3000");
});
import express from "express";
import { Context } from "@theinternetfolks/context";
interface IPayload {
host: string;
}
const app = express();
app.use(express.json());
app.use((req, res, next) => {
Context.init(); // initialize the context for the request
Context.set({ host: req.get("host") });
next();
});
app.get("/", (req, res) => {
const context = Context.get<IPayload>();
setTimeout(() => {
console.log(context?.host);
}, 2500);
return res.json({ host: context?.host });
});
app.listen(6174, () => {
console.log("Server running on port 6174");
});
-
static init(): void;
Initializes a new context. This must be called before setting data. -
static get<T>(key?: string | null): T;
Retrieves the stored data in the context. -
static set(data: Record<string, any>): boolean;
Stores data in the context. -
static remove(key?: string): void;
Deletes the data stored in the context. -
static run<T>(fn: () => T | Promise<T>, initialData?: Record<string, any>): T | Promise<T>;
Runs a function with an isolated context.
- Uses Bun Test Suite for unit testing.
- Load tested with k6 to ensure no data leakage across requests.
- Sameer Khan (@monkfromearth)
At The Internet Folks, we’re a team of ambitious builders driven by curiosity and a passion for crafting high-performance, scalable software. We tackle complex engineering challenges, push the boundaries of innovation, and create technology that makes a real impact.
If you love solving hard problems, designing clean architectures, and building systems that scale, we’d love to have you on board. Here, you’ll work with some of the sharpest minds, ship fast, and grow even faster.
🚀 Explore open roles and join us: Explore Now
Let’s build something extraordinary—together.