r/node • • 8h ago

Optimized CI, 2 mins cache to 40 seconds

Post image
2 Upvotes

r/node • • 1d ago

Blocking requests to private IPs from inside the DNS lookup in Node

9 Upvotes

I build an email API where users register webhook URLs and agents can call HTTP tools, so the server makes requests to URLs it doesn't control. Checking the hostname before the request only catches IP literals and names like localhost. A hostname can resolve to a public address when you check it and to 127.0.0.1 or 169.254.169.254 when the socket actually connects.

So outbound requests go through node:https with a custom lookup function. It calls dns.lookup with the options Node passes in, and if any returned address falls in a net.BlockList of private, loopback, link-local, CGNAT or IPv6 unique-local ranges, the connection fails. IPv4-mapped addresses like ::ffff:10.0.0.1 are unwrapped and checked against the IPv4 list too.

https.request doesn't follow redirects, so a 3xx pointing at an internal address is never followed by accident. The HTTP tool follows up to 4 redirects itself, checks each Location again, and drops every header except content-type, accept and user-agent when the redirect changes origin. I used node:https rather than a library so the guard has no extra dependency.

If you've done the same thing with undici, did you put the check in a custom connect function or somewhere else?


r/node • • 1d ago

Diary Dev - Staxis is coming!

Thumbnail
staxis.dev
0 Upvotes

Staxis is coming. The first preview of the website is live. Staxis is a modular toolkit for Node.js. Start with the free Core, assemble your stack with Layers Packs, or build your own layers.

We’re getting the first pages of the official documentation ready as we work toward the Kickstarter campaign and the 1.0 release. If you’d like to help us get there, you can already support or sponsor the project.

Take a look → https://staxis.dev


r/node • • 1d ago

I built a typed router on top of Hono + zod-openapi

0 Upvotes

Hi all, I love Hono and everything it has to offer. Its type safety, performance, and syntax is beautiful. However, I felt it had some areas that it was lacking as far as how it would fit inside enterprise-level software.

Due to this, our team created `hono-typed-router.` It is a thin layer on top of `hono` \+ `zod-openapi` that focuses on fixing one issue: **inheritance** and **context.**

With \`hono-typed-router\`, everything is based around inheritance and context. You always define child routes off a parent's type definition. The parent's middleware, bindings, etc. are always available in the child. Its syntax and usage also promote directory structures that simulate route structures (*think file-based routing*). It was also created to work as closely as possible to native Hono, so you can still leverage the full power of the web server.

**It’s also built around OpenAPI.** Every route is a `hono`, `zod-openapi` route, so you get a full spec for free, and the library works to keep that spec honest:

* Path params are inferred from the inherited path, so they’re typed, validated, and documented without re-declaring them at each level.
* Shared responses (401/403/422), security, and tags live in `routeDefaults` and merge into every route.
* Error handlers are type-checked against the route’s declared responses. Return a 409 you didn’t document, and it won’t compile.
* Scope checks are driven by each route’s `security` field, so the docs and the enforcement can’t disagree.

It also catches things Hono silently accepts: a `/:id` router shadowing a `/stats` sibling, duplicate routes, or a child mounted somewhere that skips its parent’s auth middleware. All of these throw at startup.

And it’s cheap: we measured about 2% type-checking overhead over plain zod-openapi, enforced by a type budget in CI.

We've had a great time using it over the past year or so and we'd love to share it with you all. Hopefully you find it useful.

Repository: [https://github.com/cristianhg2/hono-typed-router](https://github.com/cristianhg2/hono-typed-router)

Here is an example usage:

import { z } from 'zod';
import { testClient } from 'hono/testing';
import {
createRouter, defineChildContext, defineRootContext, handle,
jsonRequest, jsonResponse, matchErrors, mountRouter,
} from 'hono-typed-router';
import { createScopeMiddleware } from 'hono-typed-router/scopes';

const Project = z.object({ id: z.string(), name: z.string() });
const ErrorBody = z.object({ message: z.string() });

// 1. Root context: every route below gets a typed `c.var.session`
const api = defineRootContext('/api').middleware<{ session: Session }>(async (c, next) => {
c.set('session', await readSession(c.req.header('authorization')));
await next();
});

// 2. Children inherit the path AND the vars. `.bind()` loads the org or 404s.
const org = defineChildContext(api, '/orgs/:orgId').bind('org', 'orgId', (id, c) =>
findOrg(id, c.var.session.userId),
);
const projects = defineChildContext(org, '/projects');

// 3. Shared OpenAPI responses + scope enforcement, declared once for every route
const makeRouter = createRouter({
routeDefaults: {
responses: {
401: jsonResponse(ErrorBody, 'Unauthorized'),
404: jsonResponse(ErrorBody, 'Not found'),
},
},
routeMiddleware: createScopeMiddleware(api, { resolve: (c) => c.var.session.scopes }),
});

const projectsRouter = makeRouter(
projects,
({ app, defineRoute }) => app.openapi(defineRoute('post', {
security: [{ bearer: ['projects:write'] }], // documented AND enforced (403)
request: jsonRequest(z.object({ name: z.string().min(1) }), 'New project'),
responses: {
201: jsonResponse(Project, 'Created'),
409: jsonResponse(ErrorBody, 'Slug taken'), // remove this and the arm below won't compile
},
}), (c) =>
handle(
c,
async ({ param, json }) => {
param.orgId; // string: inferred from '/api/orgs/:orgId/projects', never declared
c.var.session; // inherited from the root
return c.json(await createProject(c.var.org.id, json.name), 201); // c.var.org from .bind()
},
matchErrors([SlugTaken], {
SlugTaken: (_e, c) => c.json({ message: 'Name already taken' }, 409),
}),
),
)
);

const orgRouter = makeRouter(org, () => {}, [projectsRouter]);
const app = mountRouter(api, [orgRouter]);

// 4. End-to-end typed client: path, params, body, and every response status
const client = testClient(app);
await client.api.orgs[':orgId'].projects.$post({
param: { orgId: 'acme' },
json: { name: 'Website' },
});


r/node • • 2d ago

I built Dakly: A free, zero-setup transactional email engine with multi-Gmail failover so you don't have to pay Resend or SendGrid for side projects

4 Upvotes

Hey everyone!

Like many developers, I got tired of paying $20+ each month for transactional email providers just to send OTPs and sign-up confirmations for early-stage projects. Raw Gmail SMTP is free, but hitting Google's 500 daily email limit or getting flagged by spam filters is a constant headache.

To fix this, I built Dakly ( https://dakly.cc.cd ).

How it works:

• Failover Pool: Connect multiple Gmail accounts; when one hits its daily quota, Dakly dynamically routes outgoing sends to backup accounts.

• Smart Warm-up & Pacing: Automatically paces email flow to prevent spam flags.

• Live Telemetry: Real-time open & click tracking with webhooks.

• Sender Aliases: Send from your custom domain alias ([email protected]).

• Official SDKs: Ready for Node.js (npm i @ dakly/sdk) and Python.

It's completely free to use. Would love to get your feedback and feature suggestions!


r/node • • 2d ago

A package for standardizing logging? Looking for thoughts

Thumbnail
reddit.com
0 Upvotes

r/node • • 3d ago

Stop passing req.user everywhere: I ported Spring Security's architecture to Express

1 Upvotes

If you have built an Express API, you know the frustration: you authenticate a token, attach data to req.user, and spend the rest of the day passing the req object down through services, repositories, and helper functions.

The usual alternative is migrating to NestJS just to get decent guards and decorators.

I built express-spring-security to bring that clean architecture to Express 5 and TypeScript without the framework bloat:

- Ambient Context: Access the authenticated user anywhere in your backend via Node's AsyncLocalStorage without passing the req object around.

- Single Security Chain: Define all your public, protected, and role-based routes in one central configuration.

- Method-Level Authorization: Lock down controller methods with declarative `@PreAuthorize` role and authority checks.

It is open source on GitHub and npm under `express-spring-security` (link is in the comments below).

Would love to hear your feedback and how you are currently handling auth in your Express apps!


r/node • • 4d ago

3 years ago I posted my first Node Package, now it's at +1M monthly downloads.

8 Upvotes

3 years ago I posted this: https://www.reddit.com/r/node/comments/16zrn21/my_first_node_package_efficient_language_detector/

My first Node Package: Efficient Language Detector

ELD is a fast and accurate natural language detector, written 100% in Javascript, no dependencies. I believe it is the fastest non compiled detector, at its level of accuracy.
https://github.com/nitotm/efficient-language-detector-js

I've been programming for years but this is the first time I publish a package, so I would appreciate any feedback you have on the project's structure, code quality, documentation, or any other aspect you feel could be improved.

I learned a bit, I improved it, and now it has surpassed 1 million downloads per month.
The package is called eld: https://www.npmjs.com/package/eld

I know most of the growth is because of AI agents, but I don't see that as a bad thing, they are smart ;). There is still room for improvements but I think it's a decent tool already.


r/node • • 4d ago

Building a multi-platform gaming project (E-commerce + Community + Video) — Need stack & database feedback

3 Upvotes

Hey everyone,

I’m planning to build a multi-platform gaming project that includes:

  1. E-commerce store for gaming products, accessories, and merchandise

  2. Real-time community with posts, likes, comments, shares, images and videos

  3. Dedicated video section with playlists, individual video pages, and a main video feed

  4. Multi-language, multi-currency, and multi-payment support

  5. Everything working in real-time

My current preferred stack:

- Frontend: Next.js 15 + React + TypeScript + Tailwind + GSAP + Three.js

- Backend: Node.js + Express + Socket.io

- Database: MongoDB Atlas

- Cache / Real-time: Redis

- Media storage: Cloudflare R2 + CDN

Questions:

  1. Which database is better for a multi-platform gaming project like this — MongoDB, PostgreSQL, Cassandra, or something else?

  2. Is MongoDB a good primary choice for this mix of e-commerce + community + video features?

  3. Would you recommend adding PostgreSQL for orders and payments?

  4. Any better alternatives for real-time features or video handling?

  5. Overall architecture suggestions?

Would love honest feedback from people who have built similar multi-platform projects. Thanks!


r/node • • 4d ago

npm install

16 Upvotes

Hello, Im a node.js beginner and confused about the npm install mechanism.

Why are we supposed to npm install everything a new for each project we start? Say that I install the Express framework module in any project I start, wouldn't that mean that I end up with hundreds of copies of Express on my computer? Wouldn't that be a huge waste of disk resources? It's like a C++ programmer installed a new copy of the standard library or boost for each project he starts.

I know there is a -g flag that installs "globally". Where is this "global" library located, can I browse it? Is it advisable to use the -g flag everytime I need to use a module to avoid heavy waste of disk space?


r/node • • 5d ago

I built site2paper, a Node CLI that prints a whole website into a storybook (Playwright + pdf-lib + sharp)

4 Upvotes

Ctrl+P on a real website gives you print stylesheet which are badly formatted pages, a few blank ones, the first carousel slide only, and nothing that was rendered by JS. I wanted to review a site on paper with a red pen, so I wrote a CLI that screenshots what the visitor sees and packs it into a small PDF [booklet].

[npx site2paper https://example]

Tried on [https://example 48-page catalogue site] 171 sheets / 75 MB with Ctrl+P, 25 sheets / 6.4 MB with site2paper.

For first release,

I am relying on sitemap.xml and sitemap indexes first for discovery, else a breadth-first same-origin crawl, capped at 50 pages for now. Then playwright-core drives your installed Chrome or Edge (headless Chromium is downloaded only if neither exists). Each page is scrolled in steps so lazy and IntersectionObserver content loads, then one full-page PNG is captured.

Once we have raw content we prep the page by using CSS + injecting a small script only into headless pages. Swiper/Slick/Embla/Splide/Owl carousels are reflowed into a grid. Cookie banners are hidden by selector, never clicked. Sticky and fixed nodes are removed. A viewport-sized sticky frame inside a tall section (three.js, GSAP, Lenis) prints as blank runway everywhere else. [site2paper] scrolls it to 4 stops, screenshots each, and prints them as a filmstrip with a 0/33/67/100% ruler.

For Layout we fix sharp slices each shot, a per-row variance map finds blank rows, pages flow down 1 to 4 columns and are cut only on blank rows. pdf-lib writes the PDF, JPEG slices keep it small.

I am still trying to work on auth-walled sites, infinite scroll, and anything that needs a click to reveal content.

Repo: https://github.com/piyushagru/site2paper . If you run it on a site that comes out wrong, please open an issue with the URL to help me improve this tool!

TYSM for reading, and for trying it out!


r/node • • 6d ago

Best price/performance hosting setup for a TypeScript/Node.js SaaS? Dev vs Production, VPS vs PaaS

17 Upvotes

Hey everyone!

I'm a full-stack/backend developer currently working on a personal SaaS project, and I'm trying to figure out the best hosting strategy in terms of cost, performance, scalability, and developer experience.

My stack is mainly:

- Backend: TypeScript / Node.js, with multiple backend applications/services

- Frontend: React / Next.js (1–2 frontend applications)

- Database: PostgreSQL

- Infrastructure: Docker, with GitHub Actions for CI/CD

- Potential future additions: Redis, object storage, WebSockets, and possibly some Rust/Go services

I'm looking at two different stages:

  1. Development / Early testing

I'd like to keep costs as low as possible while being able to deploy my applications, test features, run APIs and databases, and share the project with a few users.

I don't necessarily need high availability or massive resources at this stage.

2. Production / Public release

Once the project is ready for a public release, I'd like something reliable, performant, and reasonably scalable.

Ideally, I could start small and scale individual services or resources as traffic increases, without having to completely rebuild my infrastructure.

I'm open to splitting the infrastructure between different providers if that makes sense (e.g. frontend on one platform, backend on another, managed PostgreSQL elsewhere).

What I'm wondering:

  1. Which hosting providers offer the best price/performance ratio for this kind of stack? I've been looking into Hetzner, OVHcloud, Railway, Render, DigitalOcean, etc.

  2. Would you recommend starting with a VPS running Docker Compose (possibly with Coolify/Dokploy), or using a managed PaaS?

  3. Is it worth separating frontend, backend, and database hosting from the beginning, or should I keep things together initially?

  4. How would you approach scaling later on? Would you stick with VPS instances, move to managed containers, or consider Kubernetes?

  5. What does your actual setup cost per month, and what kind of workload does it handle?

I'm comfortable with development and willing to learn infrastructure/DevOps, but I'd rather avoid unnecessary complexity or spending money on resources I don't need yet.

I'm based in Europe, so EU hosting options would be particularly interesting.

I'd especially appreciate real-world experiences, actual monthly costs, and examples of setups that have worked well for you.

Thanks!


r/node • • 6d ago

How I trace which Node lines one HTTP request ran, using V8 coverage and diagnostics_channel

9 Upvotes

I wanted to see exactly which server lines one request ran without adding logs or changing the app. Here's how it ended up working, in case it's useful to anyone.

  1. V8 already counts this.Profiler.takePreciseCoverage gives per function byte ranges with counts. Taking it resets the counters so one read before a request and one after = exactly that request's code.

  2. Bracketing each request. A small agent loaded with --require subscribes to diagnostics_channel (http.server.request.start / http.server.response.finish) and takes coverage at both points. No monkey-patching of express or fastify.

  3. Overlapping requests are the hard part.Two requests in flight at once share the same counters so you cant split them. I mark those traces "overlapped" instead of pretending.

  4. Bytes → your lines. Ranges map to lines, then through source maps back to your .ts files. Gotcha: a line holding only } takes the count of the outer range so an untaken `else if` showed as "ran" until I fixed it.

The result for one request looks like:

    POST /api/invoices/INV-2041/pay → 200 [node, 8 ms]
      server/services/ledger.ts
        getSummary 14-28 ×1  not run: 16-27

Overhead is about 4-6 ms per request on Express/Fastify/Nest examples.

It's open source (MIT) as part of a tool called Lightpath, which also joins the browser side of a click: https://github.com/Unknown-333/Lightpath

Curious if anyone's done this differently, especially around concurrent requests.


r/node • • 6d ago

Introducing Skif - a repository/monorepo linter written in Rust

0 Upvotes

Hi Peeps,

I want to share with you a tool I am working on. Its still early, but I already use it and it works well.

So story goes like this - I was working on restructuring a very large monorepo with disparate package managers and versions into a single PNPM workspace. When I was finished I decided I am going to enforce certain conventions so it could not drift again without failing CI. I set this up, and found myself using several different tools -Sherif, Syncpack and Knip to ensure that the repository doesn't drift again. This setup, while working, is rather clanky and also suffered from some issues - mainly performance, but also a few bugs.

I therefore decided I will build my own tool. I forked Sherif as a baseline, and built on top of it while substantially rewriting and extending its capabilities. The result is skif: a Rust linter and enforcement tool for JS/TS dependencies and monorepos.

skif replaces sherif and syncpack, and most of what knip does (the aim is to offer a full replacement for Knip in the future) in a single, ultra fast, binary.

npx skif-cli              # lint the workspace or package you are in
npx skif-cli --fix        # apply safe fixes
npx skif-cli migrate      # turn sherif, syncpack and knip config into a skif.toml

Where it came from

skif started as a fork of sherif, and the workspace and manifest rules are ported from it. The version and catalog policies follow syncpack's model. The dead-code analysis follows knip's issue types.

It has since gone past the fork. It ports every sherif rule, adds new ones and fixes, and runs faster on every target measured. On the syncpack side it enforces version, range, banned-dependency and catalog policy.

What it deliberately does not do is sync versions. skif is a linter: it tells you a policy is broken and fails CI. Moving versions in step is left to specialized tools or the package manager's themselves. If you need this, use syncpack for example.

What it checks

42 rules:

  • Manifests and workspace: empty dependency maps, types in dependencies, root private and packageManager, unsorted dependencies, workspace globs that match nothing, members without a package.json.

  • Version policy: mismatched versions, semver range policy, banned dependencies, catalogs (missing entries, unused entries, references that do not resolve), workspace: protocol, peer dependency compatibility.

  • Dead code: unused files, exports, types, enum members and dependencies; unlisted dependencies and binaries; unresolved imports; circular imports. Leveraging the OXC ecosystem for this.

It also adds some new rules, such as incompatible-peer-dependencies and workspace-protocol.

Skif lifts the idea of framework plugins - which allow it to understand different types of entrypoints (e.g. Next.JS, Vite, Storybook etc.). But unlike Knip, which loads these files, Skif doesn't actually load code - it only statically analyses it. This removes a potential surface for code execution, and is altogether much faster, although it does bring in the potential to some imprecision.

Supported package managers

Skif supports all major package managers - npm, pnpm, Yarn classic, Yarn Berry as well as Bun. It does not support Deno, although if there is a need it might in the future. It also supports Rush and Lerna workspaces.

Benchmarks

Speed

Medians of 15 runs on a 4-vCPU Linux VM, pinned public repositories, dependencies installed:

Repositoryskifknip
create-t3-turbo32 ms2.0 s
vue-core62 ms1.7 s
tanstack-query375 ms4.5 s
npm-cli99 ms968 ms
babel884 ms7.2 s

Manifest checks alone (--no-js) against sherif and syncpack:

Targetskifsherifsyncpack
create-t3-turbo4.6 ms36 ms41 ms
babel9.4 ms37 ms280 ms
2,000 generated packages102 ms130 ms655 ms

sherif is already fast Rust, so the margin there is small: 1.3x at 2,000 packages. The real win is knip, and not paying for three processes.

Links

P.S.

Note: This is an early project, it is on v0.2.0. I am very eager to have users, since it will improve the tool and help me fix bugs. But do expect some issues!

Thanks for reading, this was a human written post (the benchmarking data was done by an LLM). If you find the tool useful, star it!


r/node • • 7d ago

WebLoad: "https:" Imports With Caching And Access Control

0 Upvotes

I've created WebLoad, an npm package for Node JS and Bun that uses module hooks (in Node) and plug-in (in Bun) APIs.

Features:

  • file-based module caching; includes basic cache management utility

  • import maps with scopes support

  • CSP "script-src"-inspired access control

  • shell scripts simplify hook/plug-in installation and local file/web/expression (eval) entry points or test-mode runs

npm i -g @bkatzung/webload


r/node • • 7d ago

Put a Node/Express app on a public HTTPS URL from your own machine in one command

0 Upvotes

I made hoist for my own hackathon demos. In a folder with a package.json, hoist up . runs npm start (or npm run dev) as a systemd service, gives it a port through process.env.PORT, and publishes it on a public HTTPS URL through Cloudflare Tunnel, with a QR code in the terminal.

Already running something? hoist adopt myapp --port 3000 publishes it without touching it. Point it at a git repo instead and it runs npm ci + npm run build on every push, with rollback if a build breaks.

The tool itself is Python with no dependencies; your app is untouched. Linux + systemd, domain on Cloudflare (or --local for a LAN URL).

Built with AI assistance (Claude), tested by me.

https://github.com/nikhilcherry/hoist


r/node • • 7d ago

leeway: stable per-folder dev port ranges (no more EADDRINUSE across checkouts)

2 Upvotes

Two checkouts of the same repo, both on 5173. leeway gives each folder its own contiguous port range, stable across runs and never overlapping, and passes the ports as env vars.

  • leeway.json lists your ports once

  • devPorts(config) in code, falling back to the defaults outside leeway

  • vite plugin sets server.port with strictPort and exposes every port to browser code

  • {{PORT_API}} placeholders in commands

  • leeway list / kill for orphaned servers

Linux/macOS/Windows. https://github.com/OhadC/leeway

Or ask your agent: "how can we benefit from using https://www.npmjs.com/package/leeway in this codebase"


r/node • • 8d ago

I built a tool that upgrades Express/TS/Node projects and opens a PR with before/after CI proof. Looking for maintainers to try it (free)

1 Upvotes

I built GreenPR: a tool that upgrades the framework in a Node/TS project and submits a PR with proof that nothing broke.
Here's how it works. AI coding tool performs the update in an isolated sandbox, then every command from the repo's CI is run before and after the update, and the results go into the PR description as a table. A separate model reads the diff and can reject it. Finally, I review it myself, and only then do I publish it. Nothing merges automatically.
It supports: Express 4 through 5, Next 14 through 16, ESLint up to 10, TypeScript up to 7 (or 6 if tools block it), NestJS up to 12, Node up to 24.
How it played out in practice? 6 PRs to other people's repos: 1 merged, 3 awaiting CI approval from maintainers, 2 closed (I closed one myself because the repo doesn't accept AI-generated code; the other maintainer said they'd do it in their own PR). Out of 13 test repos, every migration passed on the first try, and in most cases didn't touch a single line of source code (just tsconfig and package.json). Once, an independent reviewer rejected a change because the tool missed a single TypeScript setting. That's the point. It's supposed to reject it.
What doesn't work? ESLint 10 in React projects: eslint-plugin-react, jsx-a11y, and eslint-plugin-import don't support it yet, so the tool stops at version 9 and explains why. TypeScript 7 upgrades stop at 6 until typescript-eslint catches up.
I only open a PR on my own where there is already an open issue asking for that upgrade. Where there is no such issue, I ask first: a comment with a proposal, and a PR only after the maintainer says "yes."
Website is https://greenpr.pages.dev. Paste your repo URL, and you'll get a scan of what can be fixed. It's free. I'm looking for maintainers who want to give it a try and tell me what's wrong.

Edit (Nov 13): corrected the paragraph about when I open PRs and updated the numbers: 2 merged, 2 open, 2 closed.


r/node • • 9d ago

Five years of Node.js backend work. Would you stick with Node or learn Java or Go?

71 Upvotes

A backend engineer has spent about five years building systems with Node.js, Express, Fastify, and Kafka. Their salary growth hasn’t kept up with their experience.

Is Node.js still a strong career choice, or would learning Java, Go, or another stack open up better opportunities?

For anyone testing out another backend stack, try working through the same rate limiter design in both languages. PracHub has system design interview questions for that.

For experienced backend engineers and recruiters, what would you learn or change in their position?

If you’re already applying across stacks, LandOffer’s autofill can fill in the work history you keep typing into application forms.

Would love to hear your honest advice!


r/node • • 9d ago

I built distroless Node.js images that keep getting OS patches for older Node versions

8 Upvotes

nodejs-distroless is a set of distroless Node.js Docker images. It follows the official Node.js release schedule: every Current, Active LTS and Maintenance LTS line is published, and a line is dropped when it reaches end of life. Every version of those lines (about 90 right now) is rebuilt whenever the Ubuntu base changes, so an older version you've pinned keeps getting OS fixes. Google's distroless and Chainguard's free images only patch the newest Node release. Tags move to new digests when the images are rebuilt (so you need to pin digests for reproducible builds).

I wrote the whole thing from scratch, originally across three repos: a Chisel base image, a script that fetches new Node versions, and the Node images themselves. I've been running it in production on a medium-size project. It already published new Node versions on its own, but keeping dependencies up to date was mostly manual. Recently I used AI to help consolidate the repos and clean up the GitHub Actions, which got it to the point where it runs itself.

The images are cut from Ubuntu LTS with Canonical's Chisel and contain the bare minimum Node needs to run. There's no shell, and they run as non-root. For troubleshooting, every tag has a -debug variant (22-debug, lts-debug and so on) that adds a BusyBox shell. They're built for amd64 and arm64 and published to Docker Hub and GHCR.

New Node releases usually go out within the hour, and Ubuntu and dependency updates merge automatically once the checks pass. There's little for me to do until a dependency needs a major version upgrade.

Repo and usage docs: https://github.com/nvitaterna/nodejs-distroless

I'd like to hear from anyone running distroless Node in production, especially if your app needs something the image leaves out.


r/node • • 9d ago

Problem with concurrent linter fixes

Thumbnail jfmengels.net
5 Upvotes

r/node • • 9d ago

I built a Node.js package for macOS speech recognition, system voices and the on-device LLM

0 Upvotes

I am the author of apple-llm. I built it to call Apple’s built-in language model from Node, and the latest release adds text-to-speech and speech-to-text through macOS.

The Node package exposes speak(), synthesize(), transcribe(), and microphone listening alongside AppleLLM. For example, transcribe a recording, summarize the transcript using tier: device, and synthesize the result to an M4A file. The npm package also runs a local OpenAI/Ollama-compatible server with audio endpoints.

Implementation: a Swift helper compiles on first use with the Xcode Command Line Tools, is cached, and communicates with the Node client as a child process. The package supports ESM and CommonJS and has no required runtime npm dependencies.

On my M4 Air running macOS 27.2, rendering 30 minutes of narration took about 18 seconds, and transcribing a 30-minute recording took about 28 seconds. Those results are from one machine; recognition quality needs testing on real recordings.

It needs macOS 26+ on Apple Silicon. Speech does not need Apple Intelligence; the on-device LLM does. Languages may download on first use. The optional cloud tier sends prompts off the machine. MP3/Opus output and WebM input are unsupported, and the recognition language must be selected.

Source and examples: https://github.com/jagdishpal02000/apple-llm

Demo: https://jagdishpal02000.github.io/apple-llm/#speech

I would appreciate reports from anyone trying it on macOS 26 or integrating its speech endpoints into a Node app.


r/node • • 10d ago

Should I ensure my NodeJS code "root directory/working directory" is the initial executable script?

4 Upvotes

Lets say this is my NodeJS project...

    - my-online-store
       - index.js
       - about.js
       - node_modules
       - items
          - get.js
          - add.js

And lets say my-online-store directory is in /home/john for example.

If my working directory in the terminal is /home/john/my-online-store and I run node index.js for example. The working directory for the index.js, about.js, all of the node_modules/npm packages and any scripts in sub directories such as get.js and add.js will be /home/john/my-online-store and all will work.

If I run index.js from a different working directory such as the root directory using node /home/john/my-online-store/index.js the NodeJS code will crash since the working directory is / and when looking for other files using import or using fs will look at the wrong directory.

Should I be concerned of this. Should I write my NodeJS code to ensure it will get the right directories no matter what the working directory was when running index.js?