<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yass1n</title>
    <description>The latest articles on DEV Community by Yass1n (@yass1n).</description>
    <link>https://dev.to/yass1n</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4118236%2Fae1fae14-3d9d-4e16-96ed-1d99fca24ec8.png</url>
      <title>DEV Community: Yass1n</title>
      <link>https://dev.to/yass1n</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yass1n"/>
    <language>en</language>
    <item>
      <title>Bro.JS v3.1.0 – Massive Security &amp; Stability Fixes</title>
      <dc:creator>Yass1n</dc:creator>
      <pubDate>Tue, 29 Sep 2026 15:53:58 +0000</pubDate>
      <link>https://dev.to/yass1n/brojs-v310-massive-security-stability-fixes-53k0</link>
      <guid>https://dev.to/yass1n/brojs-v310-massive-security-stability-fixes-53k0</guid>
      <description>&lt;p&gt;Hey folks! 🎉&lt;/p&gt;

&lt;p&gt;If you’ve been using &lt;strong&gt;Bro.JS&lt;/strong&gt; for anything beyond a quick prototype, you’ll want to grab v3.1.0 right away. The last few weeks were spent on a deep‑dive security and stability audit, and 14 critical issues have been patched.&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s fixed?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IP spoofing&lt;/strong&gt; – The framework now only trusts the real client IP from your load balancer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate‑limiter DoS&lt;/strong&gt; – Keys are tied to verified IPs or API keys, stopping key‑bloat attacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross‑tenant IDOR&lt;/strong&gt; – User tokens win over any &lt;code&gt;X‑Tenant‑Id&lt;/code&gt; header unless you explicitly enable &lt;code&gt;TRUST_TENANT_HEADER&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plugin sandbox escape&lt;/strong&gt; – Proxy traps fully isolate plugin contexts again.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev dashboard XSS&lt;/strong&gt; – All HTML output is now safely escaped.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Runtime improvements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Edge upload limits are enforced with a &lt;code&gt;ReadableStream&lt;/code&gt; interceptor.&lt;/li&gt;
&lt;li&gt;File logger is now async (&lt;code&gt;fs.promises.appendFile&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Redis distributed locks use UUIDs and atomic Lua scripts.&lt;/li&gt;
&lt;li&gt;Background tasks get an &lt;code&gt;AbortController&lt;/code&gt; signal to avoid overlap.&lt;/li&gt;
&lt;li&gt;Pino logger redaction and circular‑reference crashes have been fixed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Developer experience tweaks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;SDK generator now correctly maps hyphenated routes for React Query hooks.&lt;/li&gt;
&lt;li&gt;Native &lt;code&gt;FormData&lt;/code&gt; uploads work out‑of‑the‑box.&lt;/li&gt;
&lt;li&gt;Windows path resolution for &lt;code&gt;bro start&lt;/code&gt; is fixed via &lt;code&gt;file://&lt;/code&gt; URLs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.env&lt;/code&gt; API key arrays (&lt;code&gt;API_KEY=key1,key2&lt;/code&gt;) are parsed automatically.&lt;/li&gt;
&lt;li&gt;CommonJS &lt;code&gt;ERR_REQUIRE_ESM&lt;/code&gt; issues are resolved.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Give it a spin and let me know what you think. If it saves you time, a ⭐ on the repo would be awesome! Happy coding!&lt;/p&gt;

</description>
      <category>security</category>
      <category>node</category>
      <category>brojs</category>
    </item>
    <item>
      <title>bro.js v3.0.0 – What’s new</title>
      <dc:creator>Yass1n</dc:creator>
      <pubDate>Sun, 20 Sep 2026 22:44:20 +0000</pubDate>
      <link>https://dev.to/yass1n/brojs-v300-whats-new-53op</link>
      <guid>https://dev.to/yass1n/brojs-v300-whats-new-53op</guid>
      <description>&lt;p&gt;Tired of flaky state leaking between tests or worrying about insecure defaults? &lt;/p&gt;

&lt;p&gt;bro.js just hit &lt;strong&gt;v3.0.0&lt;/strong&gt; and brings a bunch of practical upgrades that let you focus on code, not on runtime quirks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Edge &amp;amp; Web Standard Runtime
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Separate entry points for Node (&lt;code&gt;bro-framework&lt;/code&gt;), Next.js (&lt;code&gt;bro-framework/next&lt;/code&gt;), and Edge/worker (&lt;code&gt;bro-framework/edge&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;No more &lt;code&gt;node:crypto&lt;/code&gt; or &lt;code&gt;node:fs&lt;/code&gt; in Edge – it now uses the native Web Crypto API and &lt;code&gt;Response.json()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Guarded &lt;code&gt;process.env&lt;/code&gt; lookups make the runtime portable for Cloudflare Workers and Next.js Edge.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Immutable Instance‑Scoped Engine
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;All global singletons are gone. State lives inside the &lt;code&gt;createBro(config)&lt;/code&gt; or &lt;code&gt;createServer()&lt;/code&gt; instance, giving you true isolation per request or tenant.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Strict TypeScript Contracts
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Core context is generic‑typed via &lt;code&gt;AppContext&lt;/code&gt;. No more &lt;code&gt;any&lt;/code&gt; – you can type &lt;code&gt;ctx.db&lt;/code&gt;, &lt;code&gt;ctx.env&lt;/code&gt;, and &lt;code&gt;ctx.user&lt;/code&gt; precisely.&lt;/li&gt;
&lt;li&gt;Updated declaration files (&lt;code&gt;src/index.d.ts&lt;/code&gt;, &lt;code&gt;src/next.d.ts&lt;/code&gt;) now compile with zero errors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Contract Studio (&lt;code&gt;bro studio&lt;/code&gt;)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Generates strongly‑typed React Query hooks and MSW handlers straight from Zod schemas.&lt;/li&gt;
&lt;li&gt;OpenAPI output now includes request/auth/multipart metadata and RFC 9457 problem details.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  In‑Process Testing (&lt;code&gt;bro.test()&lt;/code&gt;)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A self‑contained HTTP testing harness that shuts down cleanly.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;testRoute()&lt;/code&gt; lets you call a handler directly without starting a server.&lt;/li&gt;
&lt;li&gt;Built‑in hooks for DB transaction rollbacks and fake timers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Production Observability &amp;amp; Security
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;OpenTelemetry spans, metrics, and W3C trace propagation.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;createPinoAdapter&lt;/code&gt; redacts PII (&lt;code&gt;Authorization&lt;/code&gt;, &lt;code&gt;Cookie&lt;/code&gt;) by default.&lt;/li&gt;
&lt;li&gt;Scaffolding no longer embeds literal secrets. In production, a missing or short JWT secret crashes the app early.&lt;/li&gt;
&lt;li&gt;CORS is now strict – you must provide an explicit allowlist.&lt;/li&gt;
&lt;li&gt;API keys are hashed; OIDC and JWKS caching via &lt;code&gt;jose&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Lifecycle Adapters &amp;amp; CLI
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;TaskManager&lt;/code&gt; now handles workers, dead‑letter queues, exponential backoff, and Redis lease locks.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PostgresAdapter&lt;/code&gt; is production‑ready, and S3/Local upload adapters are secure.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bro init&lt;/code&gt; scaffolds &lt;code&gt;bro.config.js&lt;/code&gt;, a Dockerfile, Vitest config, and an example env file.&lt;/li&gt;
&lt;li&gt;CLI commands (&lt;code&gt;bro doctor&lt;/code&gt;, &lt;code&gt;bro sdk&lt;/code&gt;, &lt;code&gt;bro studio&lt;/code&gt;) all target the default &lt;code&gt;routes/&lt;/code&gt; folder.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this is aimed at making bro.js a solid, secure, and edge‑ready framework for production workloads. Give it a spin and let us know how it fits your stack! &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>typescript</category>
      <category>web</category>
    </item>
    <item>
      <title>Introducing DevPipe: One-Click Release Publishing for Open-Source</title>
      <dc:creator>Yass1n</dc:creator>
      <pubDate>Thu, 17 Sep 2026 21:35:45 +0000</pubDate>
      <link>https://dev.to/yass1n/introducing-devpipe-one-click-release-publishing-for-open-source-1pi0</link>
      <guid>https://dev.to/yass1n/introducing-devpipe-one-click-release-publishing-for-open-source-1pi0</guid>
      <description>&lt;p&gt;Hey fellow devs! 🎉&lt;br&gt;&lt;br&gt;
Ever spent hours tweaking the same release notes for GitHub, Dev.to, Hashnode, and Reddit? I felt the same, so I built &lt;strong&gt;DevPipe&lt;/strong&gt; – a dashboard that lets you write your draft once and hit &lt;em&gt;publish everywhere&lt;/em&gt; in a single click.&lt;/p&gt;

&lt;p&gt;🚀 &lt;strong&gt;Live Demo&lt;/strong&gt;: &lt;a href="https://devpipe.yessindevs.me" rel="noopener noreferrer"&gt;devpipe.yessindevs.me&lt;/a&gt;&lt;br&gt;&lt;br&gt;
💻 &lt;strong&gt;Source&lt;/strong&gt;: &lt;a href="https://github.com/medyass1ne/devpipe" rel="noopener noreferrer"&gt;github.com/medyass1ne/devpipe&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How it works
&lt;/h3&gt;

&lt;p&gt;1️⃣ Write a standard Markdown draft.&lt;br&gt;&lt;br&gt;
2️⃣ DevPipe runs it through a Groq + gpt-oss-120b engine.&lt;br&gt;&lt;br&gt;
3️⃣ Choose “First Release” and it rewrites the narrative for each platform, auto‑generating titles and tags.&lt;/p&gt;

&lt;h3&gt;
  
  
  Publishing modes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Direct API&lt;/strong&gt; – Plug in your Dev.to token or GitHub OAuth and let DevPipe push automatically.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1‑Click Copy&lt;/strong&gt; – For platforms that are not connected, it copies the formatted Markdown and opens the submit page, so you just paste.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Give it a spin next time you launch a side project. It’s open‑source, so feel free to remix the hybrid publishing logic! 🙌&lt;/p&gt;

</description>
      <category>devops</category>
      <category>automation</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>🚀 bro.js v2.4.5 – Next.js Adapter &amp; AI‑First DX</title>
      <dc:creator>Yass1n</dc:creator>
      <pubDate>Thu, 17 Sep 2026 17:58:29 +0000</pubDate>
      <link>https://dev.to/yass1n/brojs-v245-nextjs-adapter-ai-first-dx-5fl2</link>
      <guid>https://dev.to/yass1n/brojs-v245-nextjs-adapter-ai-first-dx-5fl2</guid>
      <description>&lt;p&gt;Hey devs! 🎉&lt;/p&gt;

&lt;p&gt;I’m super excited to share &lt;strong&gt;bro.js v2.4.5&lt;/strong&gt; – the biggest leap we’ve made yet. Imagine dropping zero‑boilerplate Express magic straight into a Next.js serverless route. No more fighting Turbopack or juggling &lt;code&gt;busboy&lt;/code&gt; for file uploads. 🚀&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s fresh?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js App Router Adapter&lt;/strong&gt; – use &lt;code&gt;defineRoute&lt;/code&gt; and &lt;code&gt;createBro&lt;/code&gt; right inside &lt;code&gt;app/api&lt;/code&gt;. Multipart/form‑data is parsed for you, rate‑limiting works out of the box, and caching is a one‑liner (&lt;code&gt;cache: 60&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI‑First CLI&lt;/strong&gt; – &lt;code&gt;create-bro-app&lt;/code&gt; now asks if you want a plain Node backend or a full‑stack Next.js app, then writes an &lt;code&gt;agents.md&lt;/code&gt; file so AI tools like Copilot stay on script.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Core upgrades&lt;/strong&gt; – hot‑reloading tasks, JSON locale watching, and a unified error shape so you can trust the same &lt;code&gt;{ error, details }&lt;/code&gt; everywhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to get it?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i bro-framework@latest   &lt;span class="c"&gt;# upgrade existing projects&lt;/span&gt;
npx create-bro-app@latest    &lt;span class="c"&gt;# start a brand‑new zero‑boilerplate app&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Give it a spin and let me know what you build! ✨&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>nextjs</category>
      <category>node</category>
      <category>ai</category>
    </item>
    <item>
      <title>bro.js v2.4.0 - Redis clustering, API key rotation, and a rate limiter that actually survives outages</title>
      <dc:creator>Yass1n</dc:creator>
      <pubDate>Mon, 14 Sep 2026 22:06:41 +0000</pubDate>
      <link>https://dev.to/yass1n/brojs-v240-redis-clustering-api-key-rotation-and-a-rate-limiter-that-actually-survives-4pja</link>
      <guid>https://dev.to/yass1n/brojs-v240-redis-clustering-api-key-rotation-and-a-rate-limiter-that-actually-survives-4pja</guid>
      <description>&lt;p&gt;Pushed v2.4.0 of &lt;a href="https://github.com/medyassine/bro.js" rel="noopener noreferrer"&gt;bro.js&lt;/a&gt; (my zero-boilerplate Express alternative) and figured I'd write up what changed instead of just dumping a changelog.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Redis integration got a lot less annoying
&lt;/h2&gt;

&lt;p&gt;Used to be you had to wire up your own Redis client and babysit connection state. Now you just drop a &lt;code&gt;redisUrl&lt;/code&gt; in the config and most of it's handled for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;redisUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REDIS_URL&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From there:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Caching is basically one line.&lt;/strong&gt; &lt;code&gt;cache: 60&lt;/code&gt; on a route caches the response, and keys get hashed per user + locale + api key so you can't accidentally leak someone else's cached data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-healing cache.&lt;/strong&gt; If a cached JSON blob ever gets corrupted (happens more than you'd think), it catches the parse error, deletes the bad key, and rebuilds instead of throwing a 500 at your users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebSockets that scale automatically.&lt;/strong&gt; If it detects a Redis connection it wires up the Socket.io Redis adapter for you, so load-balancing sockets across multiple instances just works instead of silently breaking.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Rate limiter no longer panics when Redis dies
&lt;/h2&gt;

&lt;p&gt;This was the annoying one to get right. If your Redis instance drops or crashes mid-request, the old behavior was... not great. Now it falls back cleanly to a single pre-instantiated in-memory limiter, so your API keeps running and stays rate-limited instead of either falling over or spawning a new limiter per request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Actual API key auth, not just JWT workarounds
&lt;/h2&gt;

&lt;p&gt;JWTs are fine for user sessions, kind of a pain for CLI tools and service-to-service calls. So:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/admin/stats&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;api-key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OLD_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NEW_KEY&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;auth: 'api-key'&lt;/code&gt; self-documents in the auto-generated Swagger/Scalar docs as a proper &lt;code&gt;apiKeyAuth&lt;/code&gt; header scheme.&lt;/li&gt;
&lt;li&gt;Passing an array of keys means you can rotate credentials with zero downtime — old key stays valid until you're ready to drop it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;auth: ['admin']&lt;/code&gt; gives you basic RBAC out of the box.&lt;/li&gt;
&lt;li&gt;Helmet is on by default now.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Smaller stuff
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;shutdown()&lt;/code&gt; now properly kills both the primary Redis client and the pub/sub duplicates, so your process actually exits instead of hanging on ghost handles.&lt;/li&gt;
&lt;li&gt;Fixed the Multer typings, so &lt;code&gt;single&lt;/code&gt;/&lt;code&gt;array&lt;/code&gt;/&lt;code&gt;fields&lt;/code&gt; uploads get real TS autocomplete now instead of &lt;code&gt;any&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Still no decorators, no nested module system, just file-based routing. Wanted it to hold up under actual production traffic without turning into another framework you need a config generator for.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/medyassine/bro.js" rel="noopener noreferrer"&gt;https://github.com/medyassine/bro.js&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docs:&lt;/strong&gt; &lt;a href="https://brojs.yessindevs.me" rel="noopener noreferrer"&gt;https://brojs.yessindevs.me&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quickstart:&lt;/strong&gt; &lt;code&gt;npx create-bro-framework@latest my-api&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Would genuinely appreciate anyone trying to break the cache or the limiter — ran it through a decent amount of testing but there's always an edge case I didn't think of.&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>bro.js v2.3.0: Simpler Routes, Smart Language Support, and Auto API Docs</title>
      <dc:creator>Yass1n</dc:creator>
      <pubDate>Sat, 12 Sep 2026 12:56:49 +0000</pubDate>
      <link>https://dev.to/yass1n/brojs-v230-simpler-routes-smart-language-support-and-auto-api-docs-297o</link>
      <guid>https://dev.to/yass1n/brojs-v230-simpler-routes-smart-language-support-and-auto-api-docs-297o</guid>
      <description>&lt;p&gt;When building an API framework, the hardest part is keeping code simple while making sure it doesn't break in production. &lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;bro.js v2.3.0&lt;/strong&gt;, we focused on removing clutter from your route files and making everyday tasks—like handling multiple languages and documenting endpoints—as easy as possible.&lt;/p&gt;

&lt;p&gt;Here is a quick look at what changed.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Cleaner, Flatter Route Validation
&lt;/h2&gt;

&lt;p&gt;In earlier versions, you had to wrap your validation rules in a nested &lt;code&gt;schema&lt;/code&gt; object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Old way (No longer supported)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineRoute&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That was unnecessary nesting. In v2.3.0, you write your checks right at the top level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ✅ New way (Cleaner &amp;amp; faster to read)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineRoute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bro-framework&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineRoute&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Saved!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your code has the old &lt;code&gt;schema&lt;/code&gt; wrapper, &lt;code&gt;bro.js&lt;/code&gt; catches it on startup and tells you exactly how to update it.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Automatic Language Detection
&lt;/h2&gt;

&lt;p&gt;Browsers send a header called &lt;code&gt;Accept-Language&lt;/code&gt; that tells the server what languages the user understands, sorted by preference (for example: "I prefer German, but French is okay too").&lt;/p&gt;

&lt;p&gt;In v2.3.0, &lt;code&gt;bro.js&lt;/code&gt; handles all of this for you:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt; Create a &lt;code&gt;locale/&lt;/code&gt; folder in your project root.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt; Add your language files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// locale/fr.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;welcome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bienvenue, {name}!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Une erreur est survenue.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt; Use the built-in translator directly in your routes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineRoute&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;welcome&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="na"&gt;userLanguage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;bro.js&lt;/code&gt; checks the client's language list, skips any languages marked with zero preference, and picks the best match you have available.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Clearer API Documentation
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;bro.js&lt;/code&gt; automatically builds interactive documentation for your API.&lt;/p&gt;

&lt;p&gt;Now, you can also tell your docs what a successful &lt;code&gt;200 OK&lt;/code&gt; response looks like using the new &lt;code&gt;response&lt;/code&gt; option:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineRoute&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is completely optional. If you just want to return a quick object without defining a schema for it, the framework stays out of your way.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Under-the-Hood Improvements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Upload Protection: Changing a single upload setting (like maximum file size) keeps all your other safety limits intact.&lt;/li&gt;
&lt;li&gt;Clean Database Teardown: Added an &lt;code&gt;onShutdown&lt;/code&gt; option to &lt;code&gt;bro.config.js&lt;/code&gt; so you can close database pools when shutting down.&lt;/li&gt;
&lt;li&gt;Frontend SDK Polish: Fixed dynamic route naming bugs when using &lt;code&gt;$&lt;/code&gt; in parameters.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Install or upgrade to the latest version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;bro-framework@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Docs: &lt;a href="//brojs.yessindevs.me"&gt;brojs.yessindevs.me&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GitHub: &lt;a href="//github.com/medyassine/bro.js"&gt;github.com/medyassine/bro.js&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Got roasted by senior engineers for my framework's security, so I completely rebuilt the core engine</title>
      <dc:creator>Yass1n</dc:creator>
      <pubDate>Fri, 11 Sep 2026 17:35:54 +0000</pubDate>
      <link>https://dev.to/yass1n/got-roasted-by-senior-engineers-for-my-frameworks-security-so-i-completely-rebuilt-the-core-engine-166b</link>
      <guid>https://dev.to/yass1n/got-roasted-by-senior-engineers-for-my-frameworks-security-so-i-completely-rebuilt-the-core-engine-166b</guid>
      <description>&lt;p&gt;When I first launched &lt;strong&gt;bro.js&lt;/strong&gt;, a zero-boilerplate Node.js backend engine, the goal was simple: bring Next.js-style file-based routing to pure backend API development. &lt;/p&gt;

&lt;p&gt;The community response was insane. But as developers started using it to spin up APIs, a few senior engineers took a look under the hood and gave me some incredibly sharp feedback on scaling, security, and edge-case bugs. &lt;/p&gt;

&lt;p&gt;Instead of ignoring it, I took it back to the lab. Today, I'm releasing &lt;strong&gt;bro.js v2.2.0&lt;/strong&gt;, transitioning the framework from a fast prototyping tool into a production-hardened engine.&lt;/p&gt;

&lt;p&gt;Here is what we leveled up:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Bulletproof Zod Validation Parity
&lt;/h3&gt;

&lt;p&gt;Previously, the framework read nested Zod schemas to generate beautiful OpenAPI docs, but didn't strictly enforce them all at runtime. Now, we have 100% parity. If it's in your route's schema, it is ruthlessly validated before it ever hits your handler. &lt;/p&gt;

&lt;h3&gt;
  
  
  2. The "Fail-Closed" Security Model
&lt;/h3&gt;

&lt;p&gt;It's too easy to accidentally deploy a dev environment JWT secret to production. &lt;code&gt;bro.js&lt;/code&gt; now actively detects known fallback secrets on boot. If &lt;code&gt;NODE_ENV=production&lt;/code&gt; and you haven't supplied a strong cryptographic key, the server intentionally crashes on startup to protect your application. &lt;/p&gt;

&lt;h3&gt;
  
  
  3. Graceful Lifecycle &amp;amp; Task Management
&lt;/h3&gt;

&lt;p&gt;Scaling means clean deployments. I wired up a full SIGTERM/SIGINT shutdown handler. Now, when your container spins down, &lt;code&gt;bro.js&lt;/code&gt; cleanly drains HTTP requests, gracefully closes Socket.io connections, and halts scheduled background cron tasks.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. SDK Smart Quoting
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;bro sdk&lt;/code&gt; command parses your backend routes and generates a strictly typed frontend client instantly. We overhauled the generator to safely encode complex URL paths and use "Smart Quoting," giving you beautiful dot-notation (&lt;code&gt;api.users.get()&lt;/code&gt;) for standard routes without breaking on hyphenated dynamic segments.&lt;/p&gt;

&lt;p&gt;If you are tired of writing Express middleware and want an API that just works out of the box, give the new engine a spin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-bro-framework@latest my-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'd love for you to try breaking it again. Check out the &lt;a href="https://brojs.yessindevs.me/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt; or drop a star on &lt;a href="https://github.com/medyass1ne/bro.js/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>You have to stop using standalone express.js...</title>
      <dc:creator>Yass1n</dc:creator>
      <pubDate>Fri, 11 Sep 2026 13:51:30 +0000</pubDate>
      <link>https://dev.to/yass1n/you-have-to-stop-using-standalone-expressjs-42c</link>
      <guid>https://dev.to/yass1n/you-have-to-stop-using-standalone-expressjs-42c</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/yass1n/got-tired-of-rewriting-express-boilerplate-so-i-built-a-zero-config-alternative-1dil" class="crayons-story__hidden-navigation-link"&gt;Got tired of rewriting Express boilerplate, so I built a zero-config alternative&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/yass1n" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4118236%2Fae1fae14-3d9d-4e16-96ed-1d99fca24ec8.png" alt="yass1n profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/yass1n" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Yass1n
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Yass1n
                
                
              
              &lt;div id="story-author-preview-content-4617992" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/yass1n" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4118236%2Fae1fae14-3d9d-4e16-96ed-1d99fca24ec8.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Yass1n&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/yass1n/got-tired-of-rewriting-express-boilerplate-so-i-built-a-zero-config-alternative-1dil" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Sep 9&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/yass1n/got-tired-of-rewriting-express-boilerplate-so-i-built-a-zero-config-alternative-1dil" id="article-link-4617992"&gt;
          Got tired of rewriting Express boilerplate, so I built a zero-config alternative
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/backend"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;backend&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/javascript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;javascript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/node"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;node&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/yass1n/got-tired-of-rewriting-express-boilerplate-so-i-built-a-zero-config-alternative-1dil" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;4&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/yass1n/got-tired-of-rewriting-express-boilerplate-so-i-built-a-zero-config-alternative-1dil#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              3&lt;span class="hidden s:inline"&gt;&amp;nbsp;comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            1 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Got tired of rewriting Express boilerplate, so I built a zero-config alternative</title>
      <dc:creator>Yass1n</dc:creator>
      <pubDate>Wed, 09 Sep 2026 22:23:01 +0000</pubDate>
      <link>https://dev.to/yass1n/got-tired-of-rewriting-express-boilerplate-so-i-built-a-zero-config-alternative-1dil</link>
      <guid>https://dev.to/yass1n/got-tired-of-rewriting-express-boilerplate-so-i-built-a-zero-config-alternative-1dil</guid>
      <description>&lt;p&gt;Juggling client contracts and building full-stack applications means spinning up new backends constantly. But manually wiring up Express routers, configuring JWT authentication, and setting up Zod validation for every single project was completely destroying my momentum. &lt;/p&gt;

&lt;p&gt;I wanted the seamless developer experience of Next.js, but for a standalone Node API. Since nothing quite fit the bill, I built &lt;strong&gt;bro.js&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is a zero-boilerplate engine wrapper around Express that handles the tedious infrastructure out of the box, letting you focus entirely on your logic.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;File-Based Routing:&lt;/strong&gt; Just drop &lt;code&gt;[id].get.js&lt;/code&gt; into your routes folder, and the endpoint is instantly live.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in Zod Validation:&lt;/strong&gt; Pass a schema to the route definition, and the framework automatically rejects bad requests with a 400 error.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native WebSockets:&lt;/strong&gt; Socket.io is pre-configured and injected directly into your route context (&lt;code&gt;ctx.io&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-Generated SDKs:&lt;/strong&gt; Run &lt;code&gt;bro sdk&lt;/code&gt;, and it compiles a typed client SDK perfectly formatted for your frontend.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can boot a new environment instantly right from your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-bro-framework@latest my-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I would love for the community to try it out and roast the code. You can &lt;a href="https://brojs.yessindevs.me" rel="noopener noreferrer"&gt;check out the documentation here&lt;/a&gt; or drop a star on the &lt;a href="https://github.com/medyass1ne/bro.js" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>backend</category>
      <category>javascript</category>
      <category>node</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
