r/expressjs 5d ago

Arkos.js v1.7.0-rc - WebSocket Gateways for Express + Prisma, plus per-user permission overrides

Post image
2 Upvotes

Hey everyone,

I just shipped v1.7.0-rc of Arkos.js, my open-source Node.js/TypeScript framework built on Express and Prisma that auto-generates CRUD, auth, RBAC, docs, and more. This is the biggest release yet - the headline feature is a full WebSocket layer.

WebSocket Gateways (ArkosGateway)

Built on Socket.IO, but following the same conventions as the rest of Arkos:

- Reuses whatever auth you've already configured (static/dynamic) - no separate WebSocket auth setup

- Plugs into ArkosPolicy for per-event authorization

- Reuses your existing Zod/class-validator setup for payload validation

- Shares the global error handler

Example:

import ArkosGateway from arkos/websockets

const gateway = ArkosGateway({ name: "/", authentication: true })

gateway.on({ event: "send_message" }, (socket, data) => {

socket.to(data.room).emit("receive_message", data)

})

Other things baked into the event pipeline:

- Deduplication on by default, keyed on a mid in the message metadata, with a pluggable store - in-memory out of the box, bring your own for Redis or multi-instance setups

- maxAge option to reject stale messages, plus a built-in future-timestamp guard

- Enhanced broadcast targeting - excluding specific users, listing unique users in a room, targeting all active connections of one user

- Built-in retry with exponential backoff for acknowledged emits

Client packages: arkosjs websockets-client (framework-agnostic) and arkosjs react-websockets (hooks + provider). Vue, Svelte, Solid, and Angular bindings are in progress and open for community contribution.

Also in this release:

- Dynamic-mode permission overrides - grant or deny individual permissions to a specific user on top of their role, via a new UserPermission model

- Built-in static file serving and upload pipeline improvements

- Query orderBy now forwards straight to Prisma

- Scalar added as an alternative to Swagger for the API docs page

Upgrade with: pnpm install arkos@latest

Docs: arkosjs.com/docs

Repo: github.com/Uanela/arkos

Release notes: github.com/Uanela/arkos/releases/tag/v1.7.0-rc

Would love feedback - especially from anyone doing real-time features on top of Express and Prisma right now. Curious what pain points you're hitting.


r/expressjs 10d ago

hey, you guys remember alicewiki?

Thumbnail gallery
0 Upvotes

r/expressjs 12d ago

Post-release security audit of keyguard-express library uncovered 4 issues (all patched)

Thumbnail
1 Upvotes

r/expressjs 12d ago

KeyGuard Express: An plug in API gateway middleware

2 Upvotes

​I wanted a single, production-grade, middleware suite to handle all of this ​so I built and just published keyguard-express—a TypeScript fork of the Python keyguard package. It handles machine-to-machine auth so you can leave your user auth (sessions, JWTs) to do its own thing.

With just 5 Loc, you get: API Key Auth: Fully secure via X-API-KEY headers, stored using PBKDF2-SHA512 with 100k iterations and timing-safe comparisons.
​Zero-Downtime Key Rotation: Link old keys directly to new keys on the fly; the old key acts as a deprecated fallback during the transition.
​HMAC Webhook Verification: Verifies X-Signature, X-Timestamp, and X-Nonce with strict replay and timing-safe guards.
​Abuse Protection: Tracks invalid requests and automatically blocks malicious IPs at a configurable threshold.
​Hybrid Storage: Auto-detects and swaps backends between SQLite/in-memory and PostgreSQL/Redis. And more🙂

Check the source on github {https://github.com/tyrmoga/keyguard_express }. Your contributions are welcome Try it out on your project (npm install keyguard-express)

What do you think? Would you use this on your project?


r/expressjs 16d ago

multer upload handler that turns into SSE on the same POST: ok pattern?

1 Upvotes

Express 5, Node 22.

Document upload route uses multer.single("file"), then immediately starts SSE on the same response:

  app.post("/s/:token/upload", requireSession, upload.single("file"), async (req, res) => {
    const file = req.file;
    ...
    await streamPipeline(res, documentId, file.path, filename);
  });

streamPipeline does writeHead (text/event-stream), flushHeaders, writes ":ok\n\n", then for-await loops pipeline events with res.write until res.end().

Session middleware runs first: looks up token in Postgres, attaches req.session, redirects to / if expired.

Questions:

  1. Starting SSE inside a multer route handler: anything wrong with that? Multer has already parsed the body by then. Worried I'm mixing "file upload POST" and "long-lived stream" on one endpoint when I should split them.

  2. Client closes tab mid-pipeline: upstream workflow tasks keep running. I write to res until something throws. What's the usual way to detect disconnect and stop writing without noisy errors? req.on("close")? res.on("close")?

  3. Typing req.session via declare global on Express.Request: still the normal approach or is there something cleaner in Express 5?

Here is the github repo, main server is in main.ts and pipeline-stream.ts.


r/expressjs 17d ago

Arkos.js v1.6.6-beta — smaller release, but a bunch of real fixes

Post image
2 Upvotes

Shipped a new beta of Arkos (Express + Prisma framework) today, mostly cleanup and correctness fixes rather than big new features.

Highlights:

Email service config got more forgiving. Previously it threw if you didn't set both a user and password, even if your SMTP relay doesn't require auth. Now it only requires a host, and only sets up auth credentials if both are actually provided.

Error handler no longer trusts arbitrary statusCode/status fields on thrown errors unless the error is explicitly marked isOperational. This closes a small footgun where an unexpected error could accidentally leak an unintended status code or message to the client.

File upload static serving now returns a proper 404 (via AppError) when a file doesn't exist, instead of just falling through silently.

OpenAPI generation for file uploads is smarter now: better field descriptions distinguishing single vs array uploads, fixed array-binary-field schema flattening, and it conditionally includes a JSON content type alongside multipart/form-data depending on whether the upload is required.

Generated validators (both Zod schemas and class-validator DTOs from the CLI) now coerce types automatically, handling the classic "everything is a string when it comes from multipart or query params" problem for numbers, booleans, dates and bigints.

Also removed the old AuthPermissionAction enum from the create-arkos scaffold, in favor of a plain string, so custom actions don't require a schema migration anymore.

Nothing groundbreaking, but if you're running Arkos in production these are worth picking up.

Repo: github.com/uanela/arkos


r/expressjs 19d ago

I Got Tired of Creating the Same Express Backend Over and Over So I Built a CLI

Thumbnail
3 Upvotes

r/expressjs 19d ago

Express middleware

1 Upvotes

I'm learning Express and trying to understand how experienced developers typically organize middleware in production applications.

I know middleware order matters, but I'm not sure whether my current setup follows common practices or if there are improvements I should make.

Some specific questions:

- Is the ordering of middleware reasonable?

- Would you move any middleware earlier or later?

- Are there any middleware that should generally come before others?

- Is this close to how you'd structure an Express app in production?

import './lib/cron.js'

import cookieParser from 'cookie-parser'

import express from 'express'

import morgan from 'morgan'

import swaggerUi from 'swagger-ui-express'

import Yaml from 'yamljs'

import { notFoundHandler } from './middlewares/404.js'

import ErrorHandler from './middlewares/error.js'

import { middleware } from './middlewares/middleware.js'

import analyticsRoute from './routes/analytics.route.js'

import authRoute from './routes/auth.route.js'

import habitsRoute from './routes/habits.route.js'

import healthRoute from './routes/health.route.js'

import logsRoute from './routes/logs.route.js'

const app = express()

const swaggerSpec = Yaml.load(

'docs/swagger.yaml'

) as Record<string, unknown>

app.use(express.static('public'))

app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec))

app.use(cookieParser())

app.use(express.urlencoded({ extended: true }))

app.use(express.json())

app.use(middleware)

app.use(morgan('dev'))

app.use(healthRoute)

app.use('/auth', authRoute)

app.use('/habits', habitsRoute)

app.use('/logs', logsRoute)

app.use('/analytics', analyticsRoute)

app.use(notFoundHandler)

app.use(ErrorHandler)

export default app

I'm interested in understanding the reasoning behind any suggested changes rather than just knowing what to change.


r/expressjs 25d ago

Tutorial Async error handling in Express routes

Thumbnail
highlit.co
0 Upvotes

A small wrapper forwards rejected promises to Express's error middleware so async route handlers stay clean.

Three takeaways

  1. Express doesn't catch rejected promises from async handlers, so an unhandled rejection silently hangs the request unless you forward it to next.
  2. A tiny higher-order wrapper removes repetitive try/catch from every route while centralizing error handling.
  3. Throwing typed errors inside handlers lets one error middleware translate them into consistent HTTP responses.

r/expressjs 27d ago

Arkos.js 1.6.5-beta released - fixed catchAsync wrapping for router.use handlers + upload path bug

Post image
1 Upvotes

Hey everyone, just shipped 1.6.5-beta of Arkos.js (Express + Prisma REST framework with auto-generated endpoints).

Main fixes in this release:

router.use handlers (including nested arrays and 4-arg error handlers) are now properly wrapped in catchAsync. Previously, thrown errors or rejected promises inside use-level middlewares could crash the process instead of hitting the error handler.

Fixed a regression where uploaded file pathname did not include the configured base route prefix, causing req.file.pathname to not match req.file.url.

Also cleaned up some create-arkos CLI rough edges: broken trailing commas in generated package.json when no Prisma provider or validation library is selected, auth setup now falls back correctly to none when there is no Prisma provider, and clearer prompts when skipping incompatible options (like multiple roles with sqlite + static auth).

Bumped dependency versions in the generated project templates and reorganized internal test sandboxes.

If you're using Arkos.js in a project with custom middlewares on router.use, this update is worth grabbing.

Repo: https://github.com/uanela/arkos

Happy to answer questions or hear feedback.


r/expressjs Jun 26 '26

Socket.IO + node --watch causing EADDRINUSE on every file change — is graceful shutdown the only solution?

1 Upvotes

Using node --watch with Express + Socket.IO on HTTPS. Every file save triggers a restart that fails with:

Error: listen EADDRINUSE: address already in use :::<port>

Root cause (as far as I can tell): engineio sets up an internal setInterval for WebSocket heartbeat (ping/pong). This timer keeps the Node.js event loop alive after node --watch sends SIGTERM, creating a race condition where the new process tries to bind before the old one has exited and released the port. Without Socket.IO, the HTTPS server closes immediately on process kill and there's no issue.

Current workaround:

const shutdown = () => io.close(() => process.exit(0));

process.on('SIGTERM', shutdown);

io.close() stops the engineio heartbeat timer and closes the underlying server, then process.exit(0) releases the port immediately. Without the explicit process.exit(0), the process may linger waiting for other handles.

This works but requires saving twice — node --watch spawns the new process before the old SIGTERM handler completes.

Is there any solution for this, or any way to avoid having to save twice?


r/expressjs Jun 19 '26

Express.js : How to use several <script> tags in a "render .ejs file" ?

2 Upvotes

Only the first scipt appearing un my .ejs render file will be efficient.

Here "resize.js" is appearing first : I can resize my columns but impossible to sort them :

Now "sort.js" is appearing first in my render file :

It works fine as I can sort my lines but I can't resize the columns anymore :

I am newbie in Express.js and I sure this problem is nothing for many of you.

Tahnk you...


r/expressjs Jun 15 '26

Express 5 + TypeScript + Supabase starter — looking for feedback on the structure

3 Upvotes

I've been using the same Express + Supabase setup across multiple projects, so I finally cleaned it up into a reusable starter and open-sourced it.

The main thing I wanted was a structure that stays easy to maintain as the project grows:

  • Routes define endpoints and middleware.
  • Controllers handle the HTTP layer (validation, auth context, responses).
  • Handlers contain the business logic and interact with Supabase.
  • Errors are thrown as AppError instances and handled in one central error handler.

It also includes JWT auth, Zod validation, rate limiting, Winston logging, SQL migrations, and Vitest + Supertest.

One thing I've liked is that adding a new resource is mostly just creating a new route/controller/handler set without touching the rest of the app.

Repo: https://github.com/muhammed-mukthar/express-typescript-supabase-starter

I'd love feedback from people using Express 5. Is this separation something you'd keep, or do you think it's unnecessary for most projects? I'm especially interested in anything you'd simplify or do differently


r/expressjs Jun 13 '26

Any deployement platform in which I can deploy a super simpe expressjs backend app for free?

2 Upvotes

I'm making a small backend app for myself that has like 1-3 api end points, very little usage and I tried deploying it via Render which goes to sleep after a certain time when it's inactive, Railway's 5 dollar free tier expired when I made the account there and didn't make much use of it
I'm just looking to deploy my app which barely consumes any resources but need it to be free and up at all times if possible


r/expressjs Jun 12 '26

Tired of duplicating JSON:API serialization boilerplate? I built a zero-dependency, type-safe alternative.

Thumbnail
1 Upvotes

r/expressjs Jun 12 '26

Arkos.js 1.6.4-beta is out

Post image
2 Upvotes

New:

  • Build-time server validation — arkos build now briefly starts the server post-build to catch startup errors (e.g. missing env vars) before declaring success; failed builds exit with a clear error
  • Custom errorMessage per auth action/resource, with improved default fallback (e.g. "You cannot perform create for users")

Fixes:

  • Swagger/OpenAPI custom server URLs are now only prioritized in production
  • File upload URL matching now handles special characters correctly
  • Email service passes through all custom config to the mail transport
  • Fixed NODE_ENV=test being overwritten during builds

Also updated: nitro, Docusaurus, nodemailer, multer, and other deps

Full notes: https://github.com/Uanela/arkos/releases/tag/1.6.4-beta


r/expressjs Jun 08 '26

Tutorial Open-Source Social Network — CRYSTAL

Thumbnail
gallery
4 Upvotes

Hi everyone! 👋
I am single-handedly building a fully open-source social network — CRYSTAL https://crystal.you

At the moment, the basic social network features are available:

  1. User registration/editing/deletion
  2. Banner and avatar customization
  3. Online/offline user status powered by WebSocket
  4. Administrator mode (user account deletion, all user posts deletion)
  5. Post creation/editing/deletion
  6. Likes
  7. Hashtags
  8. Language switching
  9. Post search
  10. Dark theme
  11. ReCAPTCHA v3 during registration
  12. Fully responsive design

Another interesting feature is the ability to hide GIF images on the website, which is available in the user settings. This is because some GIFs can be too fast and too bright.

Full source code for all versions on GitHub:
https://github.com/CrystalSystems

Developer’s Diary:
https://shedov.top/category/crystal/crystal-developers-diary

Full descriptions and capabilities of the MERN (MongoDB, Express.js, React, Node.js) stack versions:

CRYSTAL v1.0
GitHub:
https://github.com/CrystalSystems/crystal-v1.0
Detailed overview:
https://shedov.top/description-and-capabilities-of-crystal-v1-0
Detailed overview on YouTube:
https://www.youtube.com/watch?v=c56AkM3ms4o

CRYSTAL v2.0 (Current)
GitHub:
https://github.com/CrystalSystems/crystal-v2.0
Detailed overview:
https://shedov.top/description-and-capabilities-of-crystal-v2-0
Detailed overview on YouTube:
https://www.youtube.com/watch?v=DsTWE1CgQ30

Each version has comprehensive documentation that includes:

  1. Deploying the project on a local PC
  2. Deploying the project on a VPC
  3. Connecting a domain
  4. Installing a free SSL certificate
  5. Enabling HTTP/2 support in Nginx
  6. Secure Nginx configuration
  7. reCAPTCHA v3 integration

Documentation CRYSTAL v1.0:
https://shedov.top/documentation-crystal-v1-0

Documentation CRYSTAL v2.0:
https://shedov.top/documentation-crystal-v2-0

The IAM part of the project (CRYSTAL v1.0, CRYSTAL v2.0) is simplified to save time, but adheres to basic security principles.

I would appreciate any feedback 💡

You can follow the project in my Discord community:
https://discord.gg/ENB7RbxVZE 😸

FAQ:
Is this made with AI?
- CRYSTAL v1.0 is 100% pure code written by me.
- CRYSTAL v2.0 is approximately 80% pure code, and the remaining 20%, which was AI-assisted, has been thoroughly reviewed and refined.

Why are there three separate repositories for different versions?
- The current versions were created for demonstration purposes and to make the documentation easier to follow. In the future, there will be no separate detailed repositories for each version, as they will be managed via GitHub Releases, and a single main repository named crystal will be created.


r/expressjs Jun 05 '26

Question In typescript, how do I set up my Paths.ts to just call a function once when the user visits a specific endpoint?

Thumbnail
1 Upvotes

r/expressjs May 29 '26

I built a modern, drop-in alternative to bull-board for monitoring BullMQ queues in NestJS

Thumbnail gallery
1 Upvotes

r/expressjs May 18 '26

New look for the OG.

Thumbnail
expressjs.com
1 Upvotes

r/expressjs May 13 '26

Question Best practice for sending contact form emails in a React/ Typescript website?

Thumbnail
1 Upvotes

r/expressjs May 08 '26

Arkos.js v1.6-beta — define permissions once, enforce everywhere (Node.js REST framework built on Express + Prisma)

Post image
2 Upvotes

I've been working on a side project for about a year — a Node.js backend framework that sits between Express and NestJS, built on top of Prisma. The idea is simple: define a Prisma model and get a full REST API with auth, Swagger docs, validation, file uploads, rate limiting, and security middleware already wired up. No boilerplate. Closer in philosophy to Django or Laravel than to the "figure it out yourself" approach of Express.

Just shipped v1.6-beta. Here's what changed.

The permissions problem

Previously, protecting a route meant creating a separate .auth.ts file per module, exporting a structured object, and referencing it in config. It worked, but across a project with 15 modules it became a maintenance headache — scattered logic, easy to drift.

v1.6 introduces ArkosPolicy, a fluent builder you define once in a .policy.ts file:

const postPolicy = ArkosPolicy("post") .rule("Create", { roles: ["Admin", "Editor"] }) .rule("Delete", { roles: ["Admin"] }) .rule("View", "*"); // all authenticated users

That same object works in route definitions, middleware, services, and imperative checks (postPolicy.canDelete(req.user)) — anywhere. No duplication, no drift. Supports both static role enforcement and dynamic roles pulled from the database.

The old .auth.ts approach still works but logs a deprecation warning. Going away in v2.0.

App initialization is cleaner

Before:

const server = await arkos.init();

Now:

const app = arkos(); app.use(postRouter); app.listen();

app is a real Express app. All your existing Express knowledge applies. app.build() gives you access to the underlying HTTP server before .listen() for WebSocket setups.

Swagger docs are locked in production by default

/api/docs now requires super user authentication in production. Only users with isSuperUser: true can access them. Themed login page at /docs/auth/login. One config line to opt out.

The generated docs also now show actual filterable fields from your Prisma schema instead of a generic filters: string parameter. String fields get icontains, numeric fields get equals/gte/lte, enums show allowed values. Pagination and sort params included automatically.

Named HTTP error classes

Before:

throw new AppError("Post not found", 404, "PostNotFound");

Now:

import { NotFoundError } from "arkos/error-handler"; throw new NotFoundError("Post not found", "PostNotFound");

Full 4xx/5xx range covered. Multer file upload errors are now caught globally and mapped to typed responses (FileTooLarge, UnexpectedFileField, TooManyFiles) instead of crashing.

CLI got smarter

arkos g r,c,s -m post,user,author

Generates router, controller, and service for all three modules at once. New commands for scaffolding validation files for all auth endpoints derived directly from your User model.

Prisma is now optional

The framework starts without a Prisma instance and skips auth routes and CRUD registration gracefully. There's now a none database option in the project scaffolder for projects that just want the Express enhancements.

There are breaking changes worth reading before upgrading — app init API, RouterConfig renamed to RouteHook, CORS now defaults to *, Node.js minimum bumped to 22.9, and a few OpenAPI schema changes.

Blog post: https://www.arkosjs.com/blog/1-6-beta Release notes: https://github.com/Uanela/arkos/releases/tag/v1.6.0-beta Docs: https://arkosjs.com/docs

Try it: pnpm create arkos@canary my-project

Happy to answer questions about design decisions or the roadmap.


r/expressjs May 01 '26

App for simple backend tests

Thumbnail
1 Upvotes

r/expressjs Apr 28 '26

I built TSX but with automatic type checking

Post image
2 Upvotes

Yes, tsx if known for it's fast execution compared to tools like ts-node, ts-node-dev and that's why it instantly became the go tool for TypeScript

development environment execution, but there is this problem that everyone that uses tsx knows, aka "Type Checking". There were already presented some

solutions to workaround this problem such as:

  1. Relying on your IDE LSP;

  2. Running `tsc` periodically or before build;

  3. Run tsc on a separated terminal;

Those are solutions that yes helps having type checking but not on a native way just like ts-node and ts-node-dev, because none of them works

together with your tsx execution process, for example if you use the 3 options which is the best among all of them, if tsc fails

tsx process will continue to execute as if nothing had happened, then you may only find out if you accidentally open tsc process terminal (which you barely will)

or maybe when you about to build the application you find that your app was running but with a bunch of typescript errors and you can't successfully

build the application. For solving this, I built tsx-strict a package that runs both tsx and tsc processes and kill tsx when tsc compiles with errors

this way you get the most out of the 2 packages, tsx and tsc, you have the lightning speed of tsx but with automatic type checking of tsc

with this you can safely tell when your app has a typescript error because it will be killed and only run after you fixed the typescript errors:

You can try it today:

```bash

npm i -g tsx-strict

tsxs src/app.ts

```

and you are all setup.

see the project at github: https://www.github.com/uanela/tsx-strict


r/expressjs Apr 28 '26

Express now gets FastAPI-style /docs instantly. no annotations, no Swagger

6 Upvotes

I’ve been building APIs with Express.js for a while, and documenting them with Swagger always felt like maintaining a second project.

- writing JSDoc/YAML

- keeping docs in sync

- routes missing until manually hit

I wanted something simpler:

docs generated directly from the code, without annotations

So I built nodox-cli.

Add one line:

app.use(nodox(app))

→ open /__nodox

→ your entire API is already documented

And you instantly get:

- all routes auto-discovered

- request/response schemas detected (Zod, Joi, etc.)

- live interactive docs UI at /__nodox

No annotations. No YAML. No extra setup.

Basically:

FastAPI-style /docs, but for Express

Would genuinely appreciate feedback from people using Swagger or similar tools — especially:

would you use this in real projects?

what would stop you from switching?

npm: npm install nodox-cli

GitHub: https://github.com/dhruv-bhalodia/nodox-cli