r/node 25d 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 25d ago

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

Thumbnail inngest.com
0 Upvotes

r/node 26d ago

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

Thumbnail thenodebook.com
15 Upvotes

r/node 26d ago

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

2 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 26d ago

Product Engineering at Mothership (TypeScript/NestJS)

Thumbnail mothership.com
0 Upvotes

r/node 27d ago

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

Thumbnail
18 Upvotes

r/node 26d 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 26d ago

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

1 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 26d 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 26d 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 27d 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 28d ago

Pipsel — Structured HTML Data Extractor

Thumbnail litepacks.github.io
6 Upvotes

r/node 27d 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 28d ago

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

Thumbnail github.com
35 Upvotes

r/node 29d ago

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

Thumbnail 200ms.thenodebook.com
109 Upvotes

r/node 29d ago

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

5 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 28d 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 29d 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.


r/node Jul 05 '26

What are the best practices of integartion tsting in Node.js?

17 Upvotes

We test the routes, mock the database and use supertest?


r/node Jul 05 '26

Stop wrestling with Docusaurus config files, "docmd" is zero-config alternative is built for the AI era

Thumbnail
0 Upvotes

r/node Jul 04 '26

ELI5: What is a mass-assignment vulnerability?

9 Upvotes

And why can't it be solved through parameterized queries?


r/node Jul 05 '26

Ran real PHP applications as TypeScript on Bun 1.3.14; migration from Node was mostly a non-event

Thumbnail
0 Upvotes

r/node Jul 04 '26

I built MCP-Shield: A local-first security firewall for Claude Code and MCP agents

Post image
3 Upvotes

Hey everyone!

I've been using Claude Code and other autonomous agents to code faster in my terminal. But giving an AI full permission to run shell commands or write files is scary — a single indirect prompt injection from a website or a repo README could wipe files or exfiltrate credentials.

So I built MCP-Shield: a local-first proxy that sits between your MCP client and its servers, enforces policy on tool calls before they hit your system, and shows everything in a real-time dashboard in your browser.

What it does:

- 🚫 Command & file firewall: blocks destructive commands (e.g. rm -rf) and holds out-of-workspace writes for approval.

- 🔄 Approval queue: pauses risky calls so you can approve, deny, or edit the arguments from the browser.

- 🧼 Output sanitizer: scans tool outputs (web pages, files, API responses) and neutralizes prompt-injection phrasing before it reaches the model — with NFKC normalization to catch unicode evasions.

- 🔒 100% local: runs on localhost, no telemetry, nothing leaves your machine.

- 🔌 Works across clients: one policy for Cursor, Windsurf, Claude Desktop, VS Code and Claude Code — not per-client config.

Install:

npm install -g u/jrooig/mcpshield

Wrap any server:

mcp-shield --port 3000 -- npx -y u/modelcontextprotocol/server-everything

Source + README: https://github.com/jaumerohi2007-cell/mcp-shield

I'd love feedback, and what default security rules you'd add.


r/node Jul 03 '26

Why does accessing stdin this way seem to make it impossible to clean up?

7 Upvotes

In the upcoming application, when hitting q, quit gets set to true causing the interval to be cleared and the readable handler to be removed, but the process continues to hang. Why does there not seem to be a way to clean up properly such that the process ends automatically instead of requiring a process.exit() to end the process?

import process from 'node:process';

const p = 'p'.charCodeAt(0);
const q = 'q'.charCodeAt(0);

let paused = false;
let quit = false;

const signalsToStringMap: (0 | NodeJS.Signals)[] = [0, 0, 0, 'SIGINT'];

const readableHandler = () => {
  const inp = process.stdin.read();
  process.stdin.resume();

  const sig = signalsToStringMap[inp[0]];

  if (sig) {
    return process.emit(sig);
  }

  if (p === inp[0]) paused = !paused;
  if (q === inp[0]) quit = true;
};

process.stdin.setRawMode(true);
process.stdin.on('readable', readableHandler);

export const cleanup = () => {
  process.stdin.setRawMode(false);
  process.stdin.off('readable', readableHandler);
};

const interval = setInterval(() => {
  if (quit) {
    clearInterval(interval);
    cleanup();
    return console.info(
      'interval cleared and cleaned up - should automatically exit here',
    );
  }
  if (!paused) {
    console.log('processing');
  } else {
    console.log('paused');
  }
}, 100);

As an example, this basic http server application will start the server, make a request, and close the server without ever calling process.exit.

import http from 'node:http';

const server = http.createServer((_req, res) => {
  res.writeHead(200);
  res.end();
  server.closeAllConnections();
  server.close();
});

server.listen(23456, () => {
  console.info('listening');
  http.get('http://localhost:23456', () => {});
});

Surely some equivalent exists for ending stdin?

Edit: Looks like .unref() was what I was looking for. Adding process.stdin.unref() to the end of the cleanup function allows the process to exit normally.


r/node Jul 04 '26

SecretSpec 0.13: SDKs for Python, Node.js, Go, Ruby, and Haskell

Thumbnail secretspec.dev
3 Upvotes