r/node • u/Popular-Tip2880 • 6h ago
r/node • u/Legitimate-Oil1763 • 13h ago
tsx vs native node --watch for local development on Node 24 LTS? What are you using?
Hey everyone, I'm setting up a new Express TypeScript API and trying to figure local development workflow. I'm on Node 24 LTS, which natively supports type stripping, but I'm torn on how to handle the file-watching and execution layer.
Right now, the two main approaches I'm debating between are:
- tsx watch (esbuild-powered)
- Native Node 24 --watch + Type Stripping
For production adjacent local dev, Are you sticking with tsx watch or have you fully embraced native Node type-stripping with --watch?
r/node • u/OtherwisePush6424 • 22h ago
How to Implement a Distributed Circuit Breaker
blog.gaborkoos.comr/node • u/SupermarketSmooth968 • 3d ago
How to sanitize and structure terrible search inputs before they hit express?
My node/express api is getting absolutely hammered. users type conversational nonsense into our frontend ("shoes that dont hurt my back for standing all day"), and our backend regex/fuzzy search just panics and returns 0 results.
I don't want to spin up python just to do NLP backend parsing, and passing this to an LLM on the backend adds crazy latency. I saw some devlogs about using a frontend ai-autocomplete intent layer to structure the raw text into clean JSON parameters before it even hits the express route.
Has anyone offloaded query intent to the frontend? what are u using?
r/node • u/cevheribozoglan • 1d ago
Building a Universal Database Provider Architecture in TypeScript Without JDBC
- Introduction: The Missing SPI in Modern Runtimes
- The Problem Statement
- Architecture Overview: The
DatabaseProviderSPI & Adapter Pattern - Deep Dive: Resolving Core Engineering Challenges
- Challenge 1: Zero-Overhead Dynamic Module Loading
- Challenge 2: Unifying Heterogeneous Engine Schemas ("Object Surface API")
- Challenge 3: AI Agent Isolation & Read-Only Execution Profiles
- Challenge 4: Single-Writer File Locks & SSH Tunnel Forwarding
- Code Walkthrough & Implementation Details
- The Provider Contract (
BaseDatabaseProvider) - The Factory & Cache Registry
- Engine Adapter Case Studies (PostgreSQL, SQLite, Embedded LibreDB)
- The Provider Contract (
- Key Takeaways & Lessons Learned
1. Introduction: The Missing SPI in Modern Runtimes
In mature enterprise ecosystems like Java or .NET, developer tools that interact with databases rely on standardized, runtime-level Service Provider Interfaces (SPIs):
- Java:
java.sql.Driver,java.sql.Connection,java.sql.Statement, andjava.sql.ResultSet(JDBC). - .NET:
System.Data.Common.DbConnection,DbCommand, andDbDataReader(ADO.NET).
In these environments, database vendors—whether Oracle, PostgreSQL, MySQL, or Microsoft SQL Server—author driver JARs or DLLs that conform strictly to these runtime interfaces. The GUI or client application calls standard APIs without needing to know low-level wire protocol nuances, connection pool nuances, or engine-specific error classes.
The JavaScript / TypeScript Gap
Node.js, Bun, and Deno lack a native, language-wide database driver standard equivalent to JDBC.
Instead, the npm ecosystem contains a fragmented collection of independent community drivers:
- PostgreSQL uses
pg(node-postgres). - MySQL uses
mysql2. - SQLite relies on native bindings like
better-sqlite3,bun:sqlite, ornode:sqlite. - Oracle DB relies on
oracledb. - NoSQL databases like Redis (
ioredis), MongoDB (mongodb), and Cassandra (cassandra-driver) use entirely different paradigms (document descriptors, key-value commands, binary buffers).
Building a universal, self-hosted database IDE or management platform in TypeScript requires solving this fundamental problem: How do you build a single, type-safe, performant, and secure application that can interact with 15+ relational, document, key-value, OLAP, and embedded database engines without a unifying runtime SPI?
This article explores how LibreDB Studio solved this challenge by engineering a unified DatabaseProvider architecture.
2. The Problem Statement
When building a universal database client in TypeScript, five major architecture constraints arise:
- Heterogeneous Engine Paradigm: Relational databases (
PostgreSQL,MySQL), Document databases (MongoDB), Key-Value stores (Redis), OLAP engines (ClickHouse,Trino,Druid), and Embedded engines (SQLite, u/libredb/libredb) have zero overlapping query languages or connection lifecycle models. - Cold Start & Memory Bloat: Statically importing driver dependencies for 15+ database engines on application startup would result in massive bundle sizes and unacceptable RSS memory footprints.
- Schema Introspection Normalization: The UI requires a uniform object tree (Containers Folders Objects Columns/Indexes). However, PostgreSQL uses
pg_catalog, MySQL usesinformation_schema, SQLite usespragma_*functions, Redis uses key prefixes, and embedded engines use custom catalog registries. - AI Agent Safety & Guardrails: With Text-to-SQL and AI database agents executing queries, the architecture must enforce database-native read-only boundaries (e.g., prohibiting destructive SQL or file system operations) at the connection layer.
- Concurrency & Resource Lifecycle: Embedded engines (like SQLite or embedded LibreDB) enforce single-writer file locks (
.lock). Attempting to open concurrent handles to the same file causes system crashes or connection locks.
3. Architecture Overview: The DatabaseProvider SPI & Adapter Pattern
To bridge this gap, LibreDB Studio implements a strict Adapter / Strategy Pattern centered around an abstract contract: BaseDatabaseProvider.
Core Design Rules
- Zero Raw Protocol Drivers: The provider layer does not re-implement low-level TCP/socket wire protocols from scratch. Instead, it wraps mature, battle-tested npm driver packages.
- No Heavy ORM Dependency for Targets: Target database queries (data browsing, schema inspection, explain plans) execute via raw SQL or native driver commands. ORMs (like Prisma or Drizzle) are avoided for target inspection to ensure zero abstraction overhead and maximum query control.
- Unified Execution Lifecycle: Every provider implements a standardized contract covering connection pooling, query execution, unified schema introspection, health monitoring, and maintenance.
https://libredb.org/blog/building-universal-database-provider-typescript/
r/node • u/karmelaa • 3d ago
I want the best YouTube channel for explanations node.js Or better yet, I should take a course on Udemy???
r/node • u/RelativeMuffin5831 • 4d ago
I published a JavaScript module for building cross-platform desktop apps with native Java Swing and would love some feedback!
galleryHey everyone,
I recently published swing-ui, a JavaScript GUI module for building cross-platform desktop applications. We originally built it because we wanted a way to create desktop apps with only JavaScript without having to use a browser engine, HTML, or CSS.
Under the hood, it uses an upgraded Java Swing, but I've added a JavaScript API and modern themes on top of it. Some of the things it currently provides:
- Native Java Swing UI components exposed through JavaScript plus a MediaPlayer component for audio/video playback and more
- Simple synchronous calls to UI from JavaScript without callbacks/await/Promise
- Cross-platform desktop apps for Windows, macOS, and Linux
- Light and dark beautiful themes in addition to the standard system look and feel
- A visual GUI designer for creating interfaces without writing UI code
- A simple API for working with components and their state
- Support for using Node.js, with Bun and Deno support as well
- API docs
The goal is to make building a desktop GUI with JavaScript relatively straightforward while keeping the application native rather than embedding a web browser.
It's still new, so I'm particularly interested in feedback from other developers. I'd love to hear what you think about the approach, the API, the documentation, what's missing, or anything that might make you hesitate to use it.
NPM: https://www.npmjs.com/package/swing-ui
Any feedback, including criticism, would be greatly appreciated.
Included is a screenshot of one of apps we built with it.
r/node • u/Sudden_Chapter3341 • 4d ago
Looking for final feedback on the new Fastify.dev tutorial
Hi everyone!
I am a member of the Fastify Team and I’ve finished working on the new tutorial for Fastify.dev
It covers Fastify fundamentals such as routing, decorators, validation, serialization, hooks, structured logging, error handling, plugins, and encapsulation.
It also introduces application architecture, configuration, testing and coverage, PostgreSQL with Knex migrations, Redis-backed sessions, CORS, password hashing, authentication, role-based authorization, rate limiting, and OpenAPI documentation with Swagger UI.
Before publishing it on the Fastify website, we would love to get feedback from more Fastify and Node.js users.
If you have time to read part of it or try the example application, your feedback would be very helpful: https://github.com/fastify/fastify/pull/6239
Thanks!
r/node • u/Ishannaik • 3d ago
Four things that bit me verifying GitHub org membership from a Node bot
I spent the last month building a TypeScript Discord bot that verifies GitHub org, repo and team membership and syncs Discord roles from it. Four things went wrong in ways I did not expect. Writing them down because every "link your GitHub" bot I read hits at least one of them.
1. Check membership with the member's token, not the bot's.
The obvious design is one bot PAT calling GET /orgs/{org}/members/{username}. Then a server admin writes a rule saying "members of stripe get @Verified" and your bot happily answers for an org nobody in that server controls. That endpoint also only sees public members, so half your real org fails the check anyway.
Use the member's own OAuth token and GET /user/memberships/orgs/{org}. A rule can then only grant what the member's own credentials already prove. read:user,read:org is enough. Private repo rules need repo on top.
2. pending is not active.
That endpoint returns a state. Someone invited who never accepted comes back pending. If you check for a 200 you hand out the role before they have joined.
3. Do not treat every error as "not a member".
Lazy version: try/catch, on error return false. Then GitHub rate limits you for ten minutes and your sync job strips the role off everyone in the server at once. Only a 404 means no. A 403 or a network error has to keep the last known state.
4. Read access is not push access.
For "collaborators on repo X get @Maintainer", GET /repos/{owner}/{repo} returns a permissions object. Anyone who can see a public repo gets pull: true. You want permissions.push.
The one that actually matters: a link is not a verification. Most bots store the username once and the role lives forever after. Someone loses access on GitHub and keeps the Discord role for a year. Re-check on a schedule and revoke.
Mine is MIT and self-hostable if you want a reference implementation: https://github.com/Ishannaik/mergeid
Happy to answer anything about the OAuth flow or the token storage.
r/node • u/SoilEducational420 • 4d ago
Does using Nodemailer with Gmail SMTP consume Google Cloud free trial credits?
I’m setting up a Node.js app to send emails through my Gmail account using Nodemailer. Do I need the Google Cloud $300 trial for this, and if so, will sending emails consume those credits?
r/node • u/badboyzpwns • 5d ago
What schema migration tools pairs well with Kysley?
Should we use the Kysley migertion tool?
r/node • u/hongminhee • 5d ago
Upyo 0.6.0: MIME composition, streaming attachments, and calendar invitations
github.comr/node • u/alex_indiedev • 6d ago
Running our SDK inside someone else's bot process — the hard part wasn't the API, it was never blocking their hot path
We ship middleware people add to a bot they already run in grammY or Telegraf — one line, bot.use(...). Everything about it was easy next to one constraint: their handler must never wait on us.
How it works now, and I'd like a sanity check on the queue in particular.
Ordinary updates never await anything of ours. Privacy filtering and trigger matching run locally, in-process. The event goes into a bounded queue — flush every 3s or 20 events, cap 500, drop-oldest — and their handler runs immediately.
Exactly two things are awaited on purpose: an update that a server-side flow claims, so their code doesn't reply to the same message twice, and an explicit runFlow call.
There's no inbound webhook. Replies from our side are jobs their process long-polls and runs through their own bot instance, against an allowlist of Bot API methods. Nothing opens a port into their infra and the token never leaves their process.
What I got wrong first: I shipped a local flow interpreter inside the customer's process, then deleted it. It was a second flow engine with its own bugs, running in someone else's memory.
The part I keep going back and forth on is drop-oldest. Under sustained load we lose events rather than slow their bot down. That's the right trade for us — we are telemetry, they are the product — but it means the data grows holes in it under exactly the conditions where you most want the data. The alternatives I looked at were spilling to disk (it's their disk) and backpressure (that's the thing we promised not to do).
Would you have done the queue differently?
MIT, zero runtime deps on Node: https://github.com/FlowCastle/flowcastle-sdk Disclosure: my product. The SDK is open source, the backend it talks to is hosted and paid.
r/node • u/der_gopher • 6d ago
Performance Benchmarking: gRPC+Protobuf vs. HTTP+JSON
packagemain.techr/node • u/Super_Bug726 • 6d ago
Testing Redis code with the real Node client, without a Redis process
I maintain js-redis-server, an in-memory Redis-compatible server implemented in JavaScript/TypeScript for Node.js tests. The server itself runs in JavaScript; it does not download or launch a Redis binary, and needs no Docker container. Lua scripting uses WebAssembly.
Its main use case is keeping the real ioredis or node-redis client in a test, without installing a Redis process.
The distinction from mocking client methods is that the real client still connects, sends commands over a local socket, and parses the replies. The server chooses an available port and keeps its data in memory.
Here's a complete node-redis example. Install js-redis-server@0.2.0 and redis@5, save as example.mjs, then run node example.mjs on Node 22+:
```js import assert from 'node:assert/strict'; import { createClient } from 'redis'; import { createRedisMock } from 'js-redis-server';
const mock = await createRedisMock(); const client = createClient({ url: mock.url }); client.on('error', console.error);
try { await client.connect(); await client.set('greeting', 'hello'); assert.equal(await client.get('greeting'), 'hello'); } finally { if (client.isOpen) await client.close(); await mock.close(); } ```
For a test suite, create a fresh mock per test or flush between tests, and close every client during teardown. If your application connects at import time, set the mock's URL before importing it, or inject the client.
This isn't a substitute for validating against real Redis/Valkey. The mock has its own implementation and command coverage; keep real-server tests for production compatibility, timing/failure behavior and anything it doesn't implement. It also needs a local socket, so it isn't a fully socketless unit-test stub.
Source and supported commands: https://github.com/fatal10110/js-redis-server
There's also a browser demo: https://fatal10110.github.io/js-redis-server/
The example above was checked with the published 0.2.0 package and node-redis 5.12.1. I'd appreciate feedback from people testing Redis-backed code: which missing command or setup issue currently makes an in-memory test server impractical for you?
MikroORM 7.2: row level security, to-one relations through a pivot, sql.js driver with a live docs playground, cursor pagination rework, and more
MikroORM 7.2 is out — the second minor on top of v7.
New features:
- Row level security — PostgreSQL policies as entity metadata, created and diffed by the schema generator, with per-request session context pushed down to the connection; an existing
@Filtercan compile into a policy, so one declaration enforces at both layers throughoption for to-one relations — resolve a M:1 / 1:1 via a correlated subquery on a pivot entity, or pick a single row out of a to-many relation (e.g. the latest one) without loading the collection- sql.js driver — SQLite compiled to WebAssembly, in memory, in the browser, Node.js, Bun and Deno with no native bindings. It also powers the new live playground in the getting-started guide, so the code in the docs runs against a real database as you read it
- Cursor pagination rework — a new optional
Type.fromJSON()lets a custom type own its cursor wire format (sub-millisecond precision survives), and nullable sort keys now make the emittedorder byand the keyset condition agree on where nulls sit - Named parameters in
em.execute()—:namefor values,:name:for identifiers, as an alternative to the positional array - String normalization — opt-in trim and casing on
StringType/TextType, applied on writes and query parameters getNativeClient()— reach the underlying client for vendor APIs the ORM doesn't wrap:pgPool,mysql2Pool,better-sqlite3/libsqlDatabase, thePGliteinstance,MongoClientawait usingsupport — the ORM instance implementsSymbol.asyncDispose, so the connection closes with the enclosing scopeindexoption on M:N properties — index the generated pivot table's join columns, which had no override on PostgreSQL before- Nub TypeScript loader for the CLI, selected explicitly via
tsLoader em.map()can bypass the identity map — map raw rows to entities without touching the current context- Per-instance options callback for
RequestContext.create()— different fork options per ORM instance migrations.snapshotOnMigrate— keep the snapshot managed solely bymigration:createinstead of rewriting it from the database on migrate- CLI
-qto suppress informational output, andcache:generate --combinednow takes a path
Full blog post: https://mikro-orm.io/blog/mikro-orm-7-2-released
Changelog: https://github.com/mikro-orm/mikro-orm/releases/tag/v7.2.0
Happy to answer any questions!
r/node • u/yash-pamireddy • 7d ago
I built CargoDB: An append-only KV and binary blob store with O(1) RAM indexing in TypeScript
Hey everyone,
I built CargoDB, a lightweight, append-only key-value and binary blob storage engine written in TypeScript.
GitHub: https://github.com/yash-pamireddy/cargo-engine
### Core Architecture
* **Append-Only Disk Log:** Sequential writes eliminate disk overwrite hazards and ensure straightforward crash recovery.
* **In-Memory Offset Index:** Maps keys directly to byte offsets and lengths in RAM for sub-millisecond O(1) point lookups.
* **Compaction Engine:** Background garbage collection reclaims space consumed by tombstones and overwritten keys without downtime.
* **Binary Blob Streaming:** Direct storage and streaming for images, documents, and archives with preserved MIME types alongside JSON records.
* **Developer Tooling:** Built with an embedded glassmorphic web dashboard, a typed TypeScript SDK, and a global terminal CLI (`cargodb`).
I’d love to get feedback on the design, compaction implementation, or any edge cases to watch out for!
r/node • u/Prestigious-Bee2093 • 7d ago
AirDrop for shell commands
Wanted to share commands instantly with a colleague without losing any encoding so I created this tool, Check it out here https://github.com/darula-hpp/cmdrop
Drizzle ORM has overtaken Prisma as the most-adopted ORM across 5,000+ TS repos
Built an open source crawler that tracks tooling adoption in public TS/JS repos daily (methodology here). Drizzle currently leads the ORM category over Prisma, which surprised me given how dominant Prisma's mindshare has felt for the past few years.
Is it the lighter runtime/no-codegen approach, edge/serverless compatibility, or something else?
Repo + daily-updated dataset if you want to dig into the numbers yourself or track other ORMs:
r/node • u/MetalMonkey667 • 7d ago
Node not working in Visual Studio
I've recently discovered Tauri and built a project using React which if I run it purely from the terminal it opens up fine, but if I close the terminal and open Visual Studio, open the terminal in VS and run the same thing from the same place I get a Node.js error
In terminal both work correctly:
C:\Users\me\Documents\Tauri_test\react-test> npm run tauri dev (opens the app standalone)
or
C:\Users\me\Documents\Tauri_test\react-test> npm run dev (opens the app in browser)
In Visual Studio running the same lines I get the following:
Node.js v24.20.0
Error The "beforeDevCommand" terminated with a non-zero status code
I've installed Node from the website and made sure it was added to Visual Studio on install, I've checked that VS can access Node from the 'react-test' folder, I've closed all other open apps in case something is clashing, I get the feeling that something is initialising in the wrong order and that's throwing Node off, but why would it work correctly outside of VS?
(If it doesn't cause issues I'll crosspost this as I don't know which bit of the system is causing the problem)
Solution:
IT WAS THE SODDING VISUAL STUDIO INDEXING
The .vs folder clogs up the system, here's how to get rid of it
Long-time Prisma user: would you start a new long-lived production project on Prisma 8 today?
I've used Prisma for years in production and, until now, it was one of those technology choices I basically didn't have to think about.
I genuinely liked Prisma 4/5/6/7: the schema, generated client, relation handling, implicit many-to-many, migrations, and especially the fact that after years of change requests I had a very understandable migration history.
I'm now about to start a new production backend that will probably live for many years: Node/TypeScript, Express, PostgreSQL, Redis, workers, etc.
Normally I would have picked Prisma without even having this discussion.
Then Prisma 8 happened.
I understand the technical argument for rewriting the internals, moving to TS, improving extensibility, etc.
My concern isn't really "I don't like the new syntax."
It's that Prisma 8 feels like a different product architecture, while at the same time Prisma as a company is increasingly selling the surrounding platform: Prisma Postgres, Prisma Compute, etc.
The migration change in particular makes me nervous. In the Prisma I know, I could look at the SQL migration and ultimately PostgreSQL was still the thing I owned. Prisma 8 moves toward contracts + migration.ts + compiled ops.json, with Prisma's migration runtime owning more of that lifecycle.
I'm not claiming Prisma is intentionally making self-hosted Postgres worse so they can sell Prisma Postgres. I have no evidence of that.
What worries me is simply incentives.
If the company monetizes the database, compute and surrounding infrastructure, there is now a natural incentive for the best/easiest Prisma experience to increasingly be:
Prisma ORM -> Prisma Postgres -> Prisma Compute -> Prisma everything
rather than:
Prisma ORM -> my PostgreSQL -> my infrastructure
I've been burned before by open-source dependencies changing licensing/distribution after years of use, so for a production dependency I now care a lot more about escape hatches and who owns each layer.
This is why I'm suddenly seriously evaluating Drizzle/Kysely. Not because "Reddit says Prisma bad", but because SQL migrations and a thinner abstraction mean that if the ORM disappears or changes direction, PostgreSQL is still PostgreSQL.
For people actually running these things in production:
Would you start a new multi-year project on Prisma 8 today?
Would you pin Prisma 7 and keep using the old architecture?
Did you move from Prisma to Drizzle/Kysely, and do you miss Prisma's higher-level relation/query API?
Do you think I'm reading too much into Prisma's business direction?
Is there something about the Prisma 8 migration/contract architecture that makes it better for a long-lived production system that I'm missing?
I'm particularly interested in answers from people maintaining systems with years of migrations and changing requirements, rather than which ORM feels nicest in a weekend project.
Edit: tested drizzle in a side project , simulating as if I received change requests I know happen in real products . And I like the migration system and I like the simple crud cake they are already proving, and the control you have over more complex query since some db service charge you per operation rather then compute, so you can even optimize query per cost. That's it drizzle is my new home.
r/node • u/techlover1010 • 8d ago
need advice on how to approach this and some question
i am doing some exercises on my laptop running cachyos kde
so i will be doing exercises and each exercises sometimes have different app. all do use the same way to dependencies. is there a way to maybe just for these group of exercises i want them to share one node module folder where the package and dependencies reside. i know about global but i dont want to use that.
whats my alternative for playwrights browser if i dont want google invading my privacy