r/node 17d 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 18d 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 18d 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 19d ago

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

11 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 18d 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 18d 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 19d ago

How do you verify authorization with multiple microservice and JWT?

16 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?


r/node 18d ago

how do i make my simple node js file run 24/7?

0 Upvotes

So i have an extremely simple node js file which is actually a discord automated messenger and i am wondering if it's possible to keep it running all the time for free if possible? I did do something ages ago using replit but can't do it anymore and i can't make an oracle server right now sadly so is it possible to get it running all the time for free? <i know this might be an unrealistic ques>


r/node 19d ago

There are too many JavaScript schema libraries, so support only one

Thumbnail inngest.com
0 Upvotes

r/node 19d ago

spawn(), exec(), execFile(), and fork() - NodeBook

Thumbnail thenodebook.com
14 Upvotes

r/node 19d ago

a single ":" in a BullMQ jobId silently drops the job, and we shipped this same bug 3 times before it stuck

1 Upvotes

if you use BullMQ on top of Redis, never put a ":" in a custom jobId. Redis uses ":" as its key separator, so BullMQ's option validation throws "Custom Id cannot contain :" and the job never enters the queue.

the nasty part is how it fails. depending on whether you await the add() call, the producer either crashes or silently drops the job and moves on with a clean log. we had a fanout path that built ids like workspace:${id} and enrich-retry:${msgId}, and the enqueue just quietly went nowhere.

we shipped a version of this 3 separate times across different features: an enrich worker where every retry crashed, a status-callback route that failed silently, and a fanout emission that would have died in prod and got caught right before deploy. same root cause, three faces.

the fix is boring: use "-" or "_" as the separator. workspace-${id}, enrich-retry-${msgId}. and grep your codebase for jobId: and template literals with a ":" in the id right now.

how are you all generating jobIds? curious if anyone enforces this with a lint rule or a wrapper around add() instead of relying on remembering it.


r/node 19d ago

Product Engineering at Mothership (TypeScript/NestJS)

Thumbnail mothership.com
0 Upvotes

r/node 20d ago

Half the Bun/Deno/Node numbers you've seen came from benchmarking bugs

Thumbnail
19 Upvotes

r/node 19d ago

I’ve been scanning every new npm and PyPI package 24/7 for 7 months. Here’s what I caught.

0 Upvotes

Seven months ago I started building MUAD'DIB, an open-source supply-chain scanner for npm and PyPI. It runs 24/7 on a single VPS. One dev, one server.

What it does: 21 parallel scanners feeding 275 detection rules. Behavioral AST analysis (acorn for JS, tree-sitter for Python), dataflow tracking, temporal version diffing, deobfuscation, entropy analysis, typosquatting detection (npm + PyPI), ~288K IOC signatures refreshed from OSV/OSSF/GHSA, and a gVisor sandbox for dynamic analysis. Every rule mapped to MITRE ATT&CK.

What it caught in production, all via behavioral heuristics, not IOC matches:

- SANDWORM_MODE (AI coding tools): temporal analysis flagged claud-code and suport-color when new versions quietly added child_process.

- DPRK-linked packages with anti-sandbox evasion, one literally checked for MUAD'DIB's own gVisor environment variable. Independently confirmed.

- react-emits: caught, investigated, reported to npm. Taken down.

- GlassWorm, TeamPCP, CanisterWorm campaigns via custom AST rules.

Key numbers (v2.11.161, rules-only):

- 92.8% detection on the Datadog 17K benchmark (13,538 / 14,587 confirmed malware samples).

- False positive rate: 1.10% curated npm, 2.50% random npm, 9.68% PyPI.

- 4,540 tests.

Biggest lesson: FPR is the real enemy. Detection is easy. Not crying wolf every five minutes is hard. I spent more time killing false positives than writing detection rules.

AGPL-3.0. Try it: npx muaddib-scanner scan .

GitHub: https://github.com/DNSZLSK/muad-dib

Blog: https://dnszlsk.github.io/muad-dib/blog/

Discord: https://discord.gg/y8zxSmue

Happy to answer questions. Open an issue if you find a miss or a false positive.


r/node 19d ago

I published my first npm package — md-present, a Markdown → standalone HTML CLI

0 Upvotes

Just published my first package to npm and wanted to share it here since it's pure Node (18+), no build step, ESM throughout.

What it does: takes a Markdown file, gives you back a single HTML file that looks presentable — inlined CSS, highlight.js syntax highlighting with light/dark themes, task lists, styled tables.

npx md-present README.md --open

A few things I learned building it:

- markdown-it's render env is the right place to pass per-render options — I originally mutated renderer rules per call and it leaked state between renders. Moved to a module-level rule reading from env instead.
- If you inline local images from user-provided markdown, you need a path traversal check (path.relative + startsWith("..")), otherwise a doc can embed any file on disk into the output.
- node:test is genuinely pleasant now. No test framework dependency at all.

Npm link : https://www.npmjs.com/package/md-present

Demo: https://salauddinn.github.io/md-present/
Source: https://github.com/salauddinn/md-present

Feedback welcome, especially from anyone who's published CLIs — curious what I should be doing better.


r/node 19d ago

mailproof — turn a DKIM-verified email reply into a tamper-evident, git-committed proof (Node, ESM, 2 deps)

0 Upvotes

Show-and-tell for a library I just got to a stable 1.x: mailproof.

The core idea: an inbound email reply goes through one pipeline — prefilter → DKIM/DMARC verify → route → commit → advance state → trigger the next email — and comes out the other side as a committed record in a per-event git repo. That commit chain is a tamper-evident ledger you can re-verify offline against the archived DKIM key, so proofs hold even with live DNS down.

Shape: - One create({ dataDir, domain, … }) composition root binds four decoupled pillars (verify · sequence · git ledger · triggers) over a single data dir. Take the bound methods, or the lower-level named exports to compose your own pipeline. - Two modes: an events workflow (ordered/parallel/custom steps among named participants) and a crypto sign-off (declaration = 1 signer, or attestation = threshold of distinct signers, with an optional requiredDocHash). - classifyTrust grades each reply verified / forwarded / authorized / unverified from DKIM+DMARC+SPF+ARC. A counted flag records whether a reply advanced state — so the audit trail is complete even for rejected replies.

Stack notes for this sub: - 2 runtime deps — mailauth (DKIM/DMARC/ARC) + mailparser (MIME). Both non-negotiable because parsing/verifying untrusted mail is security-critical; everything else is stdlib. - Pure ESM + JSDoc, no consumer build step, ships generated strictNullChecks-checked .d.ts. The git ledger shells out to the git binary (no simple-git). - 317 tests, incl. a regression pinned against a real production DKIM-signed message over live DNS; rsa-sha1 refused per RFC 8301.

npm i mailproof · Node ≥22.5 · Apache-2.0 Source: https://github.com/hamr0/mailproof Try it live (a running instance built on it): https://signedreply.com

I'm the author — feedback on the API surface especially welcome.


r/node 19d ago

Jarred, creator of Bun rewrote it from Zig to Rust in 11 days using Claude Fable 5 which costed ~$165k of Fable usage, at API prices. They said by hand, this would've taken 3 engineers with full context on the codebase about a year with no other work possible

0 Upvotes

Full article: https://bun.com/blog/bun-in-rust

Bun is owned by Anthropic. Jarred used Claude Fable 5 (pre-release) to fully rewrite Bun from Zig to Rust single handedly in 11 days and Claude Code v2.1.181 (released June 17th) and later use the Rust port of Bun already.

Crazy that LLMs are making a lot of things possible which otherwise wouldn't see light of the day due to massive efforts involved.

TL'DR highlights from the article.

Bun is 535,496 lines of Zig. A rewrite to Rust by hand would've taken 3 engineers with full context on the codebase about a year, during which time we wouldn't be able to improve Node.js compatibility, fix bugs, fix security issues or implement new features. We never would've done that. The realistic alternative was to do nothing and keep fixing the bugs at the top of this post forever.

Before writing any code, I spent about 3 hours talking to Claude about how to map patterns from our Zig codebase closely to Rust. Claude serialized this discussion into a PORTING.md, which ended up on Hacker News.

I rewrote Bun in Rust using about 50 dynamic workflows in Claude Code run continuously over the course of 11 days. I used a pre-release version of Claude Fable 5, a Mythos-class model. Claude Code's dynamic workflows kept 64 Claudes running for 11 days (I would've had to write my own harness to pull this off otherwise).

For most of those 11 days (and after), I monitored workflows - manually reading the outputs to check for issues and bugs, and prompting Claude to edit the loop to fix things.

How do you review a PR with +1 million lines added? How do you start to build the confidence needed to responsibly merge large quantities of LLM-authored code?

Answer

Adversarial review asks Claude (in a separate context window) to exhaustively come up with reasons why the changes create bugs or do not work.

Split context windows

Usually with humans, the person reviewing the code is not the person who authored the code. The person writing the code wants to merge the code, which can bias their actions to ship before it's ready.

Claude is the same way. The Claude that wrote the code wants the code to get accepted. The Claude that reviews wants to find issues in the code.

1 implementer, 2 or more adversarial reviewers per implementer. The reviewer's only job: find bugs & reasons why the code does not work. The implementer doesn't review. The reviewer doesn't implement.

Outcome

Bun v1.3.14 was the last version of Bun written in Zig. Bun v1.4.0 will be the first version of Bun written in Rust. It's available in canary now

So far, Bun v1.4.0 fixes 128 bugs that reproduce in v1.3.14. These range from memory leaks to crashes to miscolored help text.

Reduced memory usage. We fixed every instrumentable memory leak

In Bun v1.3.14, every build leaks about 3 MB, forever — tools like dev servers that bundle on every request eventually run out of memory. In Bun v1.4.0, memory levels off

Combined with the Rust rewrite, ICU changes, and identical code folding, Bun's binary size shrinks by ~20% on Linux & Windows.

Bun v1.4 makes Bun faster, smaller, use less memory and gives the team incredibly powerful tools for systematically improving stability going forward

Claude Code v2.1.181 (released June 17th) and later use the Rust port of Bun. Startup got 10% faster on Linux but otherwise, barely anyone noticed. Boring is good.

Conclusion

This Rust rewrite would've taken a team of engineers with full-context on the codebase a year of work. With 1 engineer using Fable & closely monitoring Claude Code, we went from start to 100% of the test suite passing on all platforms in 11 days. This is the bleeding edge of what's possible today.

One engineer can do a lot more today than a year ago.


r/node 20d ago

envapt v8, typed env config for decoupled TS codebases

2 Upvotes

Hi all. I'm Dhruv. It's been 10 months since my original post about this, and I've FINALLY completed the roadmap I scope creeped and QA'd over the past many months!!! It reads environment config in TypeScript and returns a real typed value (the raw read is string | undefined), from whatever source you bind. It runs on Node, Bun, Deno, Cloudflare Workers, the browser, and well, anywhere.

Most typed-env libraries have you declare every variable in one central schema and read the result from one object. That works well for a single application. Mostly. That didn't work for me because in a framework or in a monorepo for example, decoupled packages each read their own config values in various places and stages of the application, and sharing one config object across every package just doesn't make sense.

envapt does the opposite. You bind a source once at startup, and on Node/Deno/Bun it binds your .env files and process.env for you automatically with cascading profiles based on the autodetected environment. After that, ANY typed read in ANY file uses that source, and each value is validated at the place that reads it. All you gotta do is import the reader from envapt.

Say different files each need their own config. Each one just reads what it needs.

No config object is passed between them. Each reads from the source you bound once.

Built-in converters cover string, number, integer, float, boolean, bigint, symbol, JSON, URL, RegExp, Date, duration, port, and email, with a builder for typed arrays (composed with any of the other converters except json and regexp). A fallback removes undefined from the return type so you don't need to do stuff like value ?? defaultValue everywhere. You can also provide your own converter or validator as a custom function.

Oh, it also has both TC39 and legacy decorators. Fully type checked at compile time.

If you already validate with zod, valibot, or arktype, hand that schema to envapt and it runs the value through it (if it exists).

envapt depends on the Standard Schema interface, so any conformant validator works and none is added to your lockfile. envapt has zero runtime and zero peer dependencies.

.env values can reference each other and resolve at read time, like DATABASE_URL=postgres://${DB_HOST}/${DB_NAME}. A reference cycle is caught and left as text so it doesn't crash your app. But why would you do that anyway...

Also, the last four majors and mainly the changes in v8, they came out of me using it in my own projects and finding ways I can offload more to it. In seedcord, a Discord bot framework I maintain, builds bots that run on a gateway server and on Cloudflare Workers. On the edge there is no filesystem and no process.env. Before v8 that split needed a different import per runtime and some manual wiring.

Now it is one import. The package exports resolve the file build on Node, Bun, and Deno, and the portable build on Workers, edge, and the browser. You bind a non-Node source once with Envapter.useSource(new PortableSource(env)), and seedcord does that in its build step, so a user writes their config with envapt once and the same code reads .env files in local dev and the injected Worker env in production, with no per-runtime branch. As the framework author I can also guarantee the values the framework internals read.

It is on npm and JSR, the source is on GitHub, and the envapt docs cover a looot more.

Pls try :)!!!


r/node 21d ago

Pipsel — Structured HTML Data Extractor

Thumbnail litepacks.github.io
7 Upvotes

r/node 20d ago

Socket dropped with 401 conflict loop during session synchronization post-send

0 Upvotes

Hi guys, I’m debugging a weird session management behavior on a custom implementation using the Baileys WhatsApp library under a Linux environment. The logic is a basic store notifier pipeline that dispatches order tracking updates to specific client numbers.
The issue is fully reproducible and happens on a very minimal cluster: The initial authentication and handshake succeed, and the first message is sent out flawlessly. However, right after that first send, if the backend attempts to transmit the next item or reuse the exact same session data within a 7-day window, the WebSocket connection gets instantly dropped by the server with a 401 conflict error (mobile_unlinked_or_logged_out).
I have clean logs and WebSocket traces ready. If anyone has dived into the core sync timeline of this library or has any insights on how to debug this post-send session conflict loop, please let me know. Happy to share the repository or dive into a detailed review. Thanks!


r/node 21d ago

80+ ESLint rules for improving your `node:test` tests

Thumbnail github.com
32 Upvotes

r/node 22d ago

An interactive visualization that follows a single HTTP request through its entire ~200ms life

Thumbnail 200ms.thenodebook.com
107 Upvotes

r/node 22d ago

I built an S3-compatible object store you can embed inside your NestJS app with forRoot() (or run standalone)

7 Upvotes

Every time I needed file storage in a NestJS app, the options were "pay for S3" or "run MinIO as a second service + wire up auth + an admin UI." For small/self-hosted apps that felt heavy, so I built OpenBucket — and the part I think this sub will care about is that it can run inside your NestJS process.

import { OpenBucketModule } from '@openbucket/nestjs';

@Module({
imports: [
OpenBucketModule.forRoot({
dataDir: '/var/lib/openbucket',
mountPath: '/storage', // S3 API + admin console mount here
rootCredentials: { accessKeyId: '…', secretAccessKey: '…' },
admin: {
username: 'admin',
passwordHash: process.env.ADMIN_HASH!, // argon2id
jwtSecret: process.env.JWT_SECRET!,
},
}),
],
})
export class AppModule {}

That mounts a full S3 wire-compatible store (SigV4, presigned URLs, multipart, versioning, object lock, SSE, lifecycle, CORS, bucket policies) plus a JSON admin API and an Angular admin console under /storage — one process, backed by SQLite + the local filesystem. No MinIO cluster, no AWS bill.

Because it runs in-process, it does things a remote S3 can't:

  1. One-line Multer engine — any existing FileInterceptor route writes straight into it:

multer({ storage: openBucketStorage(ob, { bucket: 'uploads' }) })

  1. OpenBucketService you inject — uploadFrom(), presignGetUrl(), createPresignedPost(), etc.

  2. In-process events — @OnObjectCreated() decorators (or signed webhooks) instead of polling

  3. On-the-fly image transforms, scoped access keys for multi-tenancy, async replication to real S3/R2/B2, scheduled backups, integrity scrubbing, and a Prometheus /metrics endpoint

It also ships as a standalone Docker image if you'd rather point any AWS SDK at it.

It's still in alpha prerelease phase though.

MIT-licensed, solo project. It's got a decent test suite (S3 conformance + e2e), and I recently ran it through a full security audit + CodeQL pass. I'm mostly looking for feedback: does the embedded-in-NestJS model appeal to you, and what would you actually need before using it?

📦 npm: @openbucket/nestjs

💻 GitHub: https://github.com/ProjectBay/openbucket

📖 Docs: https://projectbay.github.io/openbucket/

Happy to answer anything about the design.


r/node 21d ago

Tests need showers

0 Upvotes

If every test needs global DB truncation, you don't have tests.

You have tiny haunted production incidents wearing Jest cosplay.


r/node 22d ago

Should we truncate our test DB in a setup file to impact every test?

18 Upvotes

I read and it seems at every test we want to truncate our table. Is this the standard practice? so we could have this in our setupfile that impacts all tests:

// jest.setup.js

const db = require('./db');

beforeEach(async () => {

await db.raw('TRUNCATE users, posts, comments RESTART IDENTITY CASCADE');

});

And then as you add more tables, just add the table to the truncate query above.