<?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>Forem: lutif</title>
    <description>The latest articles on Forem by lutif (@lutif).</description>
    <link>https://forem.com/lutif</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F457209%2F748cbb4a-fdac-49db-b993-9b03e18dbd69.jpeg</url>
      <title>Forem: lutif</title>
      <link>https://forem.com/lutif</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/lutif"/>
    <language>en</language>
    <item>
      <title>HOME: Dev productivity Extension, bring Arc to chrome</title>
      <dc:creator>lutif</dc:creator>
      <pubDate>Mon, 02 Mar 2026 02:09:41 +0000</pubDate>
      <link>https://forem.com/lutif/home-the-zero-auth-chrome-extension-revolutionizing-your-digital-workspace-2ok5</link>
      <guid>https://forem.com/lutif/home-the-zero-auth-chrome-extension-revolutionizing-your-digital-workspace-2ok5</guid>
      <description>&lt;p&gt;In today’s fast-paced digital world, productivity is often lost in a sea of browser tabs, scattered notifications, and endless context switching. Developers, designers, and knowledge workers constantly juggle GitHub pull requests, Slack messages, Google Calendar events, and more—each in its own silo. What if you could unify all these signals in one place, instantly, without ever granting access to your private accounts?&lt;/p&gt;

&lt;h5&gt;
  
  
  Introducing HOME: the first truly zero-auth Chrome extension that brings your digital workday together—securely, privately, and effortlessly.
&lt;/h5&gt;

&lt;h3&gt;
  
  
  🚀 What Makes HOME Innovative?
&lt;/h3&gt;

&lt;p&gt;HOME isn’t just another productivity dashboard. It’s built on a radical, privacy-first principle: zero-auth. Here’s what sets it apart:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero-Auth, Zero Setup&lt;/strong&gt;: No API keys. No OAuth. No connecting third-party accounts. HOME works by scraping data from the services you’re already logged into, right in your browser. You never have to grant access or share credentials—ever.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unified Dashboard&lt;/strong&gt;: See your GitHub PRs, Slack mentions, Google Calendar events, and more in a single, beautiful side panel. No more tab overload or missed updates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privacy by Design&lt;/strong&gt;: All data stays local. HOME never sends your information to external servers. Your workflow is yours alone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Arc-Style Workspaces&lt;/strong&gt;: Organize tabs, links, and folders into customizable “spaces” with drag-and-drop, pinning, and themes—just like the best modern browsers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-Refresh &amp;amp; Live Updates&lt;/strong&gt;: HOME quietly scrapes and updates your dashboard in the background, so you’re always up to date without lifting a finger.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Customizable &amp;amp; Open Source&lt;/strong&gt;: Personalize each workspace with emojis, names, and color themes. As an MIT-licensed open source project, HOME is transparent and extensible.&lt;br&gt;
🛠️ How Does Zero-Auth Work?&lt;br&gt;
Traditional productivity tools require you to connect your accounts, hand over API keys, or trust third-party servers with your data. HOME’s zero-auth approach is different:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Local-Only Data Scraping&lt;/strong&gt;: HOME injects lightweight scripts into the service pages you’re already using (like GitHub or Slack). It reads only what you see, processes it locally, and never transmits it elsewhere.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No External Servers&lt;/strong&gt;: There’s no backend, no analytics, and no risk of data leaks. Everything happens on your device.&lt;br&gt;
Instant Onboarding: Just install HOME, open the side panel, and your workspaces appear—no sign-ins, no permissions, no waiting.&lt;br&gt;
🎨 Designed for Focus and Flow&lt;br&gt;
HOME is more than functional—it’s designed for deep work:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Quick Actions: Pin tabs, create folders, and save workspaces with a click.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bulk Management: Archive old tabs, manage groups, and keep your browser organized.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Beautiful Themes: Make each workspace your own with custom emojis, names, and colors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;🔒 Zero-Auth Means Zero Compromise on Privacy&lt;br&gt;
With HOME, privacy isn’t an afterthought—it’s the foundation:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No Data Leaves Your Browser: All information is stored locally using Chrome’s secure storage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No Tracking or Analytics: HOME doesn’t track your activity or usage patterns.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open Source Transparency: Anyone can review, audit, or contribute to the code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🌟 Try HOME Today
&lt;/h3&gt;

&lt;p&gt;Ready to experience the future of browser productivity—without ever connecting your accounts? Here’s how to get started:&lt;/p&gt;

&lt;p&gt;Download HOME from &lt;a href="https://github.com/Lutif/dev-home" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;.&lt;br&gt;
Load as an Unpacked Extension in Chrome.&lt;br&gt;
Open the Side Panel and see your unified, zero-auth dashboard in action.&lt;/p&gt;

&lt;p&gt;Want to contribute or leave a star? Visit the GitHub repository and join the zero-auth productivity revolution!&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Lutif" rel="noopener noreferrer"&gt;
        Lutif
      &lt;/a&gt; / &lt;a href="https://github.com/Lutif/dev-home" rel="noopener noreferrer"&gt;
        dev-home
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      developers
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;HOME - Chrome Extension&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A productivity command center that brings GitHub PRs, Slack notifications, and Google Calendar into one unified side panel with Arc-style workspace management.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/9cf42634d02e4b120233344f9a22d212884b053b924594a7487e64b750b11394/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d312e322e302d626c7565"&gt;&lt;img src="https://camo.githubusercontent.com/9cf42634d02e4b120233344f9a22d212884b053b924594a7487e64b750b11394/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d312e322e302d626c7565" alt="HOME"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/c83e2ddd4f24f6ed343a123d9420b07e31afb4b82f4a95f3c6a4bd8c5a2c83f5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6368726f6d652d657874656e73696f6e2d677265656e"&gt;&lt;img src="https://camo.githubusercontent.com/c83e2ddd4f24f6ed343a123d9420b07e31afb4b82f4a95f3c6a4bd8c5a2c83f5/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6368726f6d652d657874656e73696f6e2d677265656e" alt="Chrome"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/be07a68b57a673af622198c336264f89d82bf4cd5d87bc0cb3f7b6ae47cc43ea/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d6c6967687467726579"&gt;&lt;img src="https://camo.githubusercontent.com/be07a68b57a673af622198c336264f89d82bf4cd5d87bc0cb3f7b6ae47cc43ea/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d6c6967687467726579" alt="License"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;✨ Features&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🎯 Unified Dashboard&lt;/h3&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub PR Tracking&lt;/strong&gt;: See all PRs requesting your review, your open PRs, and assigned issues&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slack Activity Feed&lt;/strong&gt;: Monitor mentions and threads from your Slack workspace&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Calendar&lt;/strong&gt;: View upcoming events and meetings&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;🎨 Workspace Management&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multiple Spaces&lt;/strong&gt;: Create unlimited workspaces with custom emojis and names&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Themes&lt;/strong&gt;: Each space has 4 customizable colors (primary, background, surface, accent)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Designer Presets&lt;/strong&gt;: 6 beautiful pre-made themes (Default, Ocean, Forest, Sunset, Rose, Purple)&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;📁 Organization&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pinned Items&lt;/strong&gt;: Keep important tabs and links easily accessible&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Folder System&lt;/strong&gt;: Organize tabs and links into collapsible folders&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drag &amp;amp; Drop&lt;/strong&gt;: Reorder items and folders with intuitive drag-and-drop&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;⚡ Productivity&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Quick Refresh&lt;/strong&gt;: Update all services with one…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Lutif/dev-home" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;




</description>
      <category>webdev</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Stop Paying for Slack Alerts: Send Sentry Errors to Slack for Free</title>
      <dc:creator>lutif</dc:creator>
      <pubDate>Fri, 13 Feb 2026 07:33:04 +0000</pubDate>
      <link>https://forem.com/lutif/stop-paying-for-slack-alerts-send-sentry-errors-to-slack-for-free-f7f</link>
      <guid>https://forem.com/lutif/stop-paying-for-slack-alerts-send-sentry-errors-to-slack-for-free-f7f</guid>
      <description>&lt;p&gt;Tired of paying for Sentry’s Slack integration? Good news: you don’t have to.&lt;/p&gt;

&lt;p&gt;With a simple setup using Sentry webhooks, Vercel Edge Functions, and Slack’s free API, you can receive real-time error notifications in Slack—without paying for a premium plan.&lt;/p&gt;

&lt;p&gt;Here’s how to set it up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Pay for What You Can Build?
&lt;/h2&gt;

&lt;p&gt;Sentry’s built-in Slack integration sits behind a paywall. For indie developers and small projects, that cost often isn’t justified.&lt;/p&gt;

&lt;p&gt;Instead, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Sentry’s webhook integration&lt;/li&gt;
&lt;li&gt;Catch events with a Vercel Edge Function&lt;/li&gt;
&lt;li&gt;Send formatted messages using Slack’s free chat.postMessage API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same result. Zero extra cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Set Up the Sentry Webhook
&lt;/h2&gt;

&lt;p&gt;Sentry provides a legacy webhook integration that sends event data to any external endpoint.&lt;/p&gt;

&lt;p&gt;Open your Sentry project settings&lt;/p&gt;

&lt;p&gt;Go to Legacy Integrations → Webhooks&lt;/p&gt;

&lt;p&gt;Add a new webhook&lt;/p&gt;

&lt;p&gt;(You'll paste your Vercel function URL here after deployment)&lt;/p&gt;

&lt;p&gt;That’s it. Sentry will now send error events to your custom endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Create the Vercel Edge Function
&lt;/h2&gt;

&lt;p&gt;If you’re new to Vercel, it’s a serverless platform that runs code at the edge with a generous free tier.&lt;/p&gt;

&lt;p&gt;We’ll create an Edge Function that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Receives Sentry events&lt;/li&gt;
&lt;li&gt;Formats them using Slack Block Kit&lt;/li&gt;
&lt;li&gt;Sends them to Slack via API&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here’s the function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const config = {
  runtime: 'edge',
};

const sendMessage = async (
  channel,
  { level, formatted, environment, email, title, culprit, project }
) =&amp;gt; {
  const isError = level === "error";

  const blocks = [
    {
      type: "section",
      text: {
        type: "mrkdwn",
        text: `${isError ? ":red_circle:" : ""} *${title}*`,
      },
    },
    {
      type: "section",
      fields: [
        { type: "mrkdwn", text: `*Environment:*\n${environment}` },
        { type: "mrkdwn", text: `*Level:*\n${level}` },
        { type: "mrkdwn", text: `*Project:*\n${project}` },
      ],
    },
    {
      type: "section",
      fields: [
        { type: "mrkdwn", text: `*User:*\n${email}` },
      ],
    },
    { type: "divider" },
    {
      type: "section",
      text: {
        type: "mrkdwn",
        text: `*Message:*\n${formatted}`,
      },
    },
    {
      type: "section",
      text: {
        type: "mrkdwn",
        text: `*Culprit:*\n${culprit}`,
      },
    },
    { type: "divider" },
  ];

  await fetch("https://slack.com/api/chat.postMessage", {
    method: "POST",
    headers: {
      "Content-Type": "application/json; charset=utf-8",
      Authorization: `Bearer ${process.env.SLACK_ACCESS_TOKEN}`,
    },
    body: JSON.stringify({
      channel,
      blocks,
    }),
  });
};

export default async (req) =&amp;gt; {
  const body = await req.json();

  const {
    project,
    culprit,
    event: {
      level,
      logentry: { formatted },
      user: { email },
      environment,
      metadata: { title },
    },
  } = body;

  await sendMessage(process.env.CHANNEL_ID, {
    level,
    formatted,
    environment,
    email,
    title,
    culprit,
    project,
  });

  return new Response("Event received");
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What This Does&lt;/p&gt;

&lt;p&gt;Receives error events from Sentry&lt;/p&gt;

&lt;p&gt;Formats structured Slack messages using blocks&lt;/p&gt;

&lt;p&gt;Posts directly to Slack using an OAuth token&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Create and Configure Your Slack App
&lt;/h2&gt;

&lt;p&gt;To allow Slack to receive messages:&lt;/p&gt;

&lt;p&gt;Go to api.slack.com/apps&lt;/p&gt;

&lt;p&gt;Create a new app in your workspace&lt;/p&gt;

&lt;p&gt;Under OAuth &amp;amp; Permissions, add:&lt;/p&gt;

&lt;p&gt;chat:write&lt;/p&gt;

&lt;p&gt;Install the app to your workspace&lt;/p&gt;

&lt;p&gt;Copy the OAuth Bot Token&lt;/p&gt;

&lt;p&gt;Now add these environment variables in Vercel:&lt;/p&gt;

&lt;p&gt;SLACK_ACCESS_TOKEN&lt;/p&gt;

&lt;p&gt;CHANNEL_ID&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Deploy to Vercel
&lt;/h2&gt;

&lt;p&gt;Push your code to GitHub&lt;/p&gt;

&lt;p&gt;Import the repo into Vercel&lt;/p&gt;

&lt;p&gt;Add your environment variables&lt;/p&gt;

&lt;p&gt;Deploy&lt;/p&gt;

&lt;p&gt;Once deployed, copy the function URL and paste it into your Sentry webhook settings.&lt;/p&gt;

&lt;p&gt;Done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Test It
&lt;/h2&gt;

&lt;p&gt;Trigger a test error in Sentry.&lt;/p&gt;

&lt;p&gt;If everything is configured correctly, you’ll see a clean, structured error notification in Slack within seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Setup Wins
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Completely Free&lt;/li&gt;
&lt;li&gt;Real-time notifications&lt;/li&gt;
&lt;li&gt;Fully customizable Slack formatting&lt;/li&gt;
&lt;li&gt;Serverless and low maintenance&lt;/li&gt;
&lt;li&gt;Works on Sentry’s free plan&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You’re essentially recreating the paid integration—with more flexibility.&lt;/p&gt;

&lt;p&gt;Grab the Code &amp;amp; Customize It&lt;/p&gt;

&lt;p&gt;Feel free to adapt this setup for your own workflow:&lt;/p&gt;

&lt;p&gt;Add severity filtering&lt;/p&gt;

&lt;p&gt;Route different projects to different channels&lt;/p&gt;

&lt;p&gt;Format alerts differently for staging vs production&lt;/p&gt;

&lt;p&gt;If this helped you save money or level up your monitoring setup, leave a start and share it with other developers. Small optimizations like this make a big difference over time.&lt;/p&gt;

&lt;p&gt;Check out the GitHub &lt;a href="https://github.com/Lutif/sentry-to-slack/" rel="noopener noreferrer"&gt;Repository&lt;/a&gt; Here&lt;/p&gt;

&lt;p&gt;Happy building 🚀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>vercel</category>
      <category>sentry</category>
    </item>
    <item>
      <title>Solving Unnecessary Rerenders in React with eventsync</title>
      <dc:creator>lutif</dc:creator>
      <pubDate>Sun, 06 Jul 2025 09:30:52 +0000</pubDate>
      <link>https://forem.com/lutif/solving-unnecessary-rerenders-in-react-with-eventsync-kb4</link>
      <guid>https://forem.com/lutif/solving-unnecessary-rerenders-in-react-with-eventsync-kb4</guid>
      <description>&lt;p&gt;If you’ve ever used React Context for global state management, you probably ran into this: updating one small value causes your entire app to rerender. Annoying, right? Especially when only one component needed the update.&lt;/p&gt;

&lt;p&gt;Let’s break down why this happens and how eventsync fixes it using a simple, event-driven approach.&lt;/p&gt;

&lt;p&gt;The Problem: Context Rerenders Everything&lt;/p&gt;

&lt;p&gt;React Context is great for sharing global state, but it comes with a hidden cost. Imagine this setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;context.tsx

import React, { createContext, useContext, useState } from 'react';

const AppContext = createContext(null);

export const AppProvider = ({ children }) =&amp;gt; {
  const [counter, setCounter] = useState(0);
  const [user, setUser] = useState({ name: '', email: '' });

  return (
    &amp;lt;AppContext.Provider value={{ counter, setCounter, user, setUser }}&amp;gt;
      {children}
    &amp;lt;/AppContext.Provider&amp;gt;
  );
};

export const useAppContext = () =&amp;gt; useContext(AppContext);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, two components that use different parts of the state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Counter.tsx

import { useAppContext } from './context';

const Counter = () =&amp;gt; {
  const { counter, setCounter } = useAppContext();
  console.info('Counter rerendered');

  return (
    &amp;lt;button onClick={() =&amp;gt; setCounter(counter + 1)}&amp;gt;{counter}&amp;lt;/button&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UserName.tsx

import { useAppContext } from './context';

const UserName = () =&amp;gt; {
  const { user } = useAppContext();
  console.info('UserName rerendered');

  return &amp;lt;div&amp;gt;{user.name}&amp;lt;/div&amp;gt;;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you click the Counter button, both Counter and UserName rerender. But why?&lt;/p&gt;

&lt;p&gt;React Context triggers a rerender for all consumers whenever the context value changes, even if the part they care about stayed the same.&lt;/p&gt;

&lt;p&gt;This means:&lt;/p&gt;

&lt;p&gt;✅ More rerenders than necessary&lt;br&gt;
✅ Performance bottlenecks in large apps&lt;br&gt;
✅ Frustrating debugging sessions&lt;/p&gt;

&lt;p&gt;The Solution: eventsync&lt;/p&gt;

&lt;p&gt;eventsync gives you global state without the Context rerender headaches. It uses good old DOM events to notify only the components that care.&lt;/p&gt;

&lt;p&gt;Here’s the same example rewritten with eventsync:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;App.tsx

import { initGlobalState } from 'eventsync';
import Counter from './Counter';
import UserName from './UserName';

initGlobalState({
  counter: 0,
  user: { name: '', email: '' }
});

function App() {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;Counter /&amp;gt;
      &amp;lt;UserName /&amp;gt;
    &amp;lt;/&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Counter.tsx

import { useGlobalState } from 'eventsync';

const Counter = () =&amp;gt; {
  const [{ counter }, { setCounter }] = useGlobalState(["counter"]);
  console.info('Counter rerendered');

  return (
    &amp;lt;button onClick={() =&amp;gt; setCounter(counter + 1)}&amp;gt;{counter}&amp;lt;/button&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UserName.tsx

import { useGlobalState } from 'eventsync';

const UserName = () =&amp;gt; {
  const [username] = useGlobalState('user.name');
  console.info('UserName rerendered');

  return &amp;lt;div&amp;gt;{username}&amp;lt;/div&amp;gt;;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With eventsync:&lt;/p&gt;

&lt;p&gt;✅ Updating counter only rerenders Counter&lt;br&gt;
✅ UserName stays untouched&lt;br&gt;
✅ No need to split context or build complex selectors&lt;/p&gt;

&lt;p&gt;Why Use eventsync?&lt;/p&gt;

&lt;p&gt;Fine-grained updates: Components subscribe to specific state fields&lt;/p&gt;

&lt;p&gt;Cleaner code: No boilerplate splitting context for different consumers&lt;/p&gt;

&lt;p&gt;Better performance: Fewer unnecessary renders&lt;/p&gt;

&lt;p&gt;Zero context dependency: eventsync uses native DOM events under the hood&lt;/p&gt;

&lt;p&gt;Final Thoughts&lt;/p&gt;

&lt;p&gt;Tired of your whole UI rerendering when only one value changes? Give react-eventsync a try.&lt;/p&gt;

&lt;p&gt;You get global state with precise, efficient updates, powered by DOM events. It’s a simple drop-in tool that keeps your app performant without extra complexity.&lt;/p&gt;

&lt;p&gt;Curious to explore more? Check out the Getting Started guide and level up your global state management.&lt;/p&gt;

&lt;p&gt;The project is open-source and available on GitHub:&lt;br&gt;
🌟 &lt;a href="https://github.com/Lutif/eventSync" rel="noopener noreferrer"&gt;https://github.com/Lutif/eventSync&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you find it useful, please give it a star&lt;br&gt;
Want to follow my work? Follow on github to support my work. &lt;a href="https://github.com/Lutif" rel="noopener noreferrer"&gt;lutif&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>reactjsdevelopment</category>
      <category>refactorit</category>
    </item>
    <item>
      <title>Customizing the user interface on Linux:</title>
      <dc:creator>lutif</dc:creator>
      <pubDate>Sat, 10 Dec 2022 13:53:37 +0000</pubDate>
      <link>https://forem.com/lutif/customizing-the-user-interface-on-linux-69m</link>
      <guid>https://forem.com/lutif/customizing-the-user-interface-on-linux-69m</guid>
      <description>&lt;p&gt;Linux allows users to customize their user interface in many different ways, giving them the ability to create a unique and personalized experience. In this tutorial, we will explore some of the options for customizing the user interface on a Linux system.&lt;/p&gt;

&lt;p&gt;Choosing a desktop environment&lt;br&gt;
The first step in customizing the user interface on a Linux system is to choose a desktop environment. A desktop environment is a collection of tools and applications that provide the user interface for a Linux system. There are many different desktop environments to choose from, each with its own look and feel. Some popular examples include GNOME, KDE, Xfce, and LXDE.&lt;/p&gt;

&lt;p&gt;To choose a desktop environment, you can either install a Linux distribution that comes with a specific desktop environment, or you can install a desktop environment on an existing Linux system. To do this, you can use a package manager to search for and install the desktop environment of your choice.&lt;/p&gt;

&lt;p&gt;Configuring the desktop environment&lt;br&gt;
Once you have installed a desktop environment, you can start configuring it to your liking. Most desktop environments include a settings application that allows you to change various aspects of the user interface, such as the wallpaper, the color scheme, and the fonts. You can also change the layout of the desktop, the position of the panels and widgets, and the behavior of the windows and menus.&lt;/p&gt;

&lt;p&gt;In addition to the settings application, many desktop environments also provide tools for managing the applications that are installed on the system. This can include things like the application launcher, the application menu, and the system tray. You can use these tools to customize the way that applications are organized and accessed on the system.&lt;/p&gt;

&lt;p&gt;Installing and configuring a window manager&lt;br&gt;
In addition to a desktop environment, Linux systems also allow users to install and configure a window manager. A window manager is a piece of software that controls the appearance and behavior of the windows on the desktop. Unlike a desktop environment, which provides a complete user interface, a window manager only manages the windows, leaving other aspects of the user interface up to the user.&lt;/p&gt;

&lt;p&gt;There are many different window managers available for Linux, each with its own unique features and capabilities. Some popular examples include Openbox, i3, and Awesome. To install and configure a window manager, you can use a package manager to search for and install the window manager of your choice. Once it is installed, you can use its configuration files to customize its appearance and behavior to your liking.&lt;/p&gt;

&lt;p&gt;Using a theme&lt;br&gt;
Another way to customize the user interface on a Linux system is to use a theme. A theme is a collection of files that defines the appearance of the desktop environment and the window manager. A theme can change things like the color scheme, the fonts, the icons, and the cursors.&lt;/p&gt;

&lt;p&gt;To use a theme on a Linux system, you first need to install the theme files. Most themes are available as packages that can be installed using a package manager. Once the theme is installed, you can use the settings application or the configuration files of the desktop environment or window manager to apply the theme.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
Linux provides a wide range of options for customizing the user interface, allowing users to create a unique and personalized experience. By choosing a desktop environment, configuring the desktop environment and window manager, and using a theme, users can customize the look and feel of their Linux system to their liking. With the right tools and techniques, anyone can create a user interface that is tailored to their specific needs and preferences.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>windowmanager</category>
      <category>desktopenvironment</category>
      <category>theme</category>
    </item>
    <item>
      <title>Using Git for version control in software development</title>
      <dc:creator>lutif</dc:creator>
      <pubDate>Sat, 10 Dec 2022 13:47:41 +0000</pubDate>
      <link>https://forem.com/lutif/using-git-for-version-control-in-software-development-cmk</link>
      <guid>https://forem.com/lutif/using-git-for-version-control-in-software-development-cmk</guid>
      <description>&lt;p&gt;Git is a popular version control system that is widely used in the software development process. It allows developers to track and manage changes to their codebase over time, making it easier to collaborate on projects and maintain a history of their work.&lt;/p&gt;

&lt;p&gt;What is Git version control?&lt;br&gt;
To use Git, developers first need to initialize a local repository on their own computer. This is done using the git init command, which creates a new directory where all the files and changes will be tracked. The repository can then be linked to a remote repository, such as one hosted on GitHub, using the git remote add command.&lt;/p&gt;

&lt;p&gt;Using Git for collaboration in software development&lt;br&gt;
Once the local repository is set up, developers can begin adding files to it using the git add command. This stages the files for commit, meaning they are ready to be saved to the repository. Developers can then use the git commit command to save the staged files to the repository, along with a message describing the changes that were made.&lt;/p&gt;

&lt;p&gt;Git also allows developers to create branches, which are separate lines of development that can be worked on concurrently. This is useful for implementing new features or experimenting with different approaches to a problem without affecting the main codebase. To create a new branch, developers can use the git branch command, and then use the git checkout command to switch between branches.&lt;/p&gt;

&lt;p&gt;Git also provides a number of tools for collaborating with other developers. For example, the git clone command allows developers to create a local copy of a remote repository, and the git push and git pull commands can be used to synchronize changes between the local and remote repositories. This makes it easy for multiple developers to work on the same codebase and share their changes with each other.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
Overall, Git is an essential tool for managing the software development process. It allows developers to track and manage changes to their codebase, collaborate with others, and maintain a history of their work. By using Git, developers can work more efficiently and effectively, and can ensure that their projects are well-organized and easy to maintain.&lt;/p&gt;

</description>
      <category>welcome</category>
      <category>community</category>
      <category>ai</category>
    </item>
    <item>
      <title>Optimise CI to make sure your test run for only modules changed and save avoidable computation minutes</title>
      <dc:creator>lutif</dc:creator>
      <pubDate>Fri, 02 Sep 2022 13:19:29 +0000</pubDate>
      <link>https://forem.com/lutif/optimise-ci-to-run-tests-only-concerned-to-features-changed-not-whole-app-2642</link>
      <guid>https://forem.com/lutif/optimise-ci-to-run-tests-only-concerned-to-features-changed-not-whole-app-2642</guid>
      <description>&lt;p&gt;We all profess test driven development and we should. Sometimes pushing MVP to the market in certain time is important and we skip tests at all. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Whatever the case, write tests for your code as soon as you can.&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;But with huge code base, and good test means you will have hundreds if not thousands of tests to run. And all those tests could include some preparation computation before we execution and clean-up after it. There are separate strategies to optimise that much in-nutshell: tests could take a lot of time to run. Often we run those test for automatically at merge and pull requests. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That require a lot of compassion on cloud and hence cost you fortune.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Read about development pipeline strategies here. &lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/lutif" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KyzDltxt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--18mjK2-I--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/457209/748cbb4a-fdac-49db-b993-9b03e18dbd69.jpeg" alt="lutif"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/lutif/strategies-to-ship-faster-and-keep-your-development-pipeline-unblocked-at-scale-3n32" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Strategies to ship faster, and keep your development pipeline unblocked at scale&lt;/h2&gt;
      &lt;h3&gt;lutif ・ Sep 1 ・ 3 min read&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#github&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#codequality&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;So, it would be better to run only test related to the feature changed, if its UI test run test for the concerned page, and not for something that stay unchanged. &lt;/p&gt;

&lt;p&gt;Here we will see an example how to do that if you have your code hosted on Github and CI done via Github actions, but these strategies works for other tools too.&lt;/p&gt;

&lt;p&gt;Lets, assume we are doing UI tests and our code is structured such that we have &lt;code&gt;scr/pages&lt;/code&gt; folder that contains components for all pages eg: &lt;code&gt;src/pages/register&lt;/code&gt; , there could be subdirs as well eg: &lt;code&gt;src/page/register/shared&lt;/code&gt;, &lt;code&gt;src/page/register/styles&lt;/code&gt; etc.&lt;/p&gt;

&lt;p&gt;Now in your Github action where you run tests&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get files changed: For Github Actions you can use &lt;a href="https://dev.toChanged%20Files"&gt;Changed Files
&lt;/a&gt; action from action market place&lt;/li&gt;
&lt;li&gt;Filter files from your pages directory, get pages names keep unique only, that's where you UI components are right?&lt;/li&gt;
&lt;li&gt;Pass this list to whatever testing library/suit/runner you are using, be it JEST, playwright. Let your runner only run those test only.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: If you have shared components which are used on multiple pages, make sure if there are any changes in those, run all tests to be sure you are not breaking anything. &lt;/p&gt;

&lt;p&gt;Comment about your approach to tests and have you run into this issue of insane time to run tests.   &lt;/p&gt;

</description>
      <category>testing</category>
      <category>github</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Strategies to ship faster, and keep your development pipeline unblocked at scale</title>
      <dc:creator>lutif</dc:creator>
      <pubDate>Thu, 01 Sep 2022 11:43:18 +0000</pubDate>
      <link>https://forem.com/lutif/strategies-to-ship-faster-and-keep-your-development-pipeline-unblocked-at-scale-3n32</link>
      <guid>https://forem.com/lutif/strategies-to-ship-faster-and-keep-your-development-pipeline-unblocked-at-scale-3n32</guid>
      <description>&lt;p&gt;When your team size grow, you start seeing a lot of merge conflicts. Few people are making changes on same files, you have this big feature to ship, should you let smaller PRs related it to be merged on staging so other dev working on that feature can use that piece of code. Someone is blocked because someone else is working on a module that's needed. You can't even think of refactoring causing so many people are making changes on those parts of codebase.&lt;/p&gt;

&lt;p&gt;Well that chaos is worth the diving deep. Let's first see what's very common developing flow, here I might be referring github once a while but these strategies works with any other alternatives too.&lt;/p&gt;

&lt;p&gt;Mostly you have this &lt;strong&gt;master&lt;/strong&gt;/main branch - github create this by default when you create a repo - this should be your single source of truth any code merged to this branch should be tested well and have no any know bugs. This should be your production code, all CI/CD should be automated for this branch at least.&lt;/p&gt;

&lt;p&gt;Next is your dev/&lt;strong&gt;staging&lt;/strong&gt; branch, its good practice to have an intermediary stage between your development and your production code. Often this branch is also deployed to some staging deployment so devs/QA can test on real production environment. You merge your branch into this staging branch and once a while rollout to production by merging this staging branch into master/main, often these rollouts are scheduled but frequency depends on team size and the development acceleration. Better to do smaller rollout to minimise bugs and impact they can have on users. But on other hand rollout means new deployments on production which might cause some disturbances - new instances of app could cause inflight request canceled, or delay in page loads etc - you find a good balance for your team here.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;It is important to keep staging and master in sync, and merge only staging branch to master no other branches or direct commits to master.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Trunk vs Atomic branches
&lt;/h2&gt;

&lt;p&gt;Normally you branch out from staging create a feature branch, you make changes, raise a pull request and once reviewed and approved by others you merge it. But what if you have to work on a bigger feature, multiple other devs will also be working , you might be experimenting and different implementations for that feature, You can't create once big branch let many people push their commits in it, it will raise conflicts. You might just want to work on your part and let others create separate PR and work on their part but what if they need some of your code too. You both need one utility function to make your code work.  &lt;/p&gt;

&lt;p&gt;Their is a development strategy to make this easier, often referred as &lt;strong&gt;Trunk-based development&lt;/strong&gt; . So now you create a trunk branch, which will have all changes related to that specific feature.let's say you are adding login with Google feature to your website. You can create a trunk branch, and dev's branch out from this branch to work on their individual tasks. Once their atomic branches are reviewed and approved, they get merged to this trunk branch and when you have this feature ready and tested you merge your trunk branch into staging, and rollout. Often these trunk branches are deployed too to make it easy for non-dev team to test it experience it. &lt;/p&gt;

&lt;p&gt;Next we will talk about &lt;a href="https://dev.to/lutif/optimise-ci-to-run-tests-only-concerned-to-features-changed-not-whole-app-2642"&gt;testing and how to optimise CI to make sure your test run for only modules that are changed in the PR and not all tests as that might slow down your development and cost you avoidable computation minutes&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>github</category>
      <category>codequality</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to write a scalable router for express in nodejs.</title>
      <dc:creator>lutif</dc:creator>
      <pubDate>Sun, 06 Sep 2020 07:19:28 +0000</pubDate>
      <link>https://forem.com/lutif/how-to-write-a-scalable-router-for-express-in-nodejs-cfo</link>
      <guid>https://forem.com/lutif/how-to-write-a-scalable-router-for-express-in-nodejs-cfo</guid>
      <description>&lt;p&gt;I have been looking for a good way to handling routing in MERN project, scalable and robust router, there were many articles but somewhat confusing for beginners so I decided to simplify it for and what else could be a good topic for the first article at dev.to.&lt;/p&gt;

&lt;p&gt;Here we will assume we are working on a large project that provides API to front-end with a bunch of routes. &lt;/p&gt;

&lt;h2&gt;
  
  
  let's dive in
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create a folder in root directory
&lt;/h3&gt;

&lt;p&gt;I prefer it naming routes, ofcourse you can name anything you like&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/routes&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Create root router
&lt;/h3&gt;

&lt;p&gt;Now, that we have a folder to hold all of our routes, we can have the root router in it. Create a &lt;code&gt;router.js&lt;/code&gt; file in the &lt;code&gt;~/routes&lt;/code&gt; folder.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Create and export the router
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require("express"); 
const router = express.Router();
const subRouters = []; //will get subRouters soon
router.use(subRouters);
module.exports = router;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can import this router in your main file and let express use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Creating sub routers
&lt;/h3&gt;

&lt;p&gt;In the &lt;code&gt;~/routes&lt;/code&gt; folder create more folders according to your need; for demo I will create a couple of folders&lt;/p&gt;

&lt;p&gt;&lt;code&gt;~/routes/auth&lt;br&gt;
~/routes/profile&lt;br&gt;
~/routes/chat&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;create routers in subfolders accordingly, for example, &lt;code&gt;~routes/auth&lt;/code&gt; could have &lt;code&gt;login.js&lt;/code&gt; and &lt;code&gt;register.js&lt;/code&gt;.&lt;br&gt;
Here &lt;code&gt;~/routes/auth/register.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require("express"); 
const router = express.Router();


router.post(
  "/api/users",
  async (req, res) =&amp;gt; {

 //your logic here 
}
module.exports = router;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. The Fun part- telling your root router to look for subRouters
&lt;/h3&gt;

&lt;p&gt;Now that we have a couple of routers in subfolders -there can be as many as you want- we tell our root router to import them. Importing them manually one by one could be tedious also if we add any subRouter in the future we would have to come back to root router again and take care of it manually. &lt;/p&gt;

&lt;p&gt;Import file system and path module we will use them to look take a look in the directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const fs = require("fs");
const path = require("path");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's get subroutes, we are defining here an empty array to hold all imported subRoutes and a function &lt;code&gt;getAllSubroutes&lt;/code&gt; given a directory to this it will look for all files in the directory and import them in subRoutes array,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const subRouters = [];
const getAllSubroutes = (dir) =&amp;gt; {
  fs.readdirSync(dir).forEach((file) =&amp;gt; {
    const fullPath = path.join(dir, file);
    if (fs.lstatSync(fullPath).isDirectory()) {
      getAllSubroutes(fullPath);
    } else {
      if (fullPath !== __filename) {
        subRouters.push(require(fullPath));
      }
    }
    return subRouters;
  });
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if it come across a directory it will search it recursively - take note&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;if (fs.lstatSync(fullPath).isDirectory()) {&lt;br&gt;
          getAllSubrouts(fullPath);&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;incase you are wondering &lt;code&gt;forEach&lt;/code&gt; is builtin array function works similar to for loop. Also , notice in else block we check &lt;code&gt;if (fullPath !== __filename)&lt;/code&gt; this ensure we do, not import rootRouter into itslef .&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Call &lt;code&gt;getAllSubroutes&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Next, we put our function to work, call it with argument of &lt;code&gt;__dirname&lt;/code&gt;; this is global property available in every file pointing to its directory.&lt;br&gt;
now your &lt;code&gt;~routes/rootRouer/router.js&lt;/code&gt; should look like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//root router

const express = require("express");
const fs = require("fs");
const path = require("path");

const router = express.Router();

const subRouters = [];
const getAllSubroutes = (dir) =&amp;gt; {
  fs.readdirSync(dir).forEach((file) =&amp;gt; {
    const fullPath = path.join(dir, file);
    if (fs.lstatSync(fullPath).isDirectory()) {
      getAllSubroutes(fullPath);
    } else {
      if (fullPath !== __filename) {
        subRouters.push(require(fullPath));
      }
    }
    return subRouters;
  });
};

 getAllSubroutes(__dirname)
router.use(subRouters);

module.exports = router;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can add or remove as many routes according to our needs, without requiring us to change anything else.&lt;br&gt;
This is off-course one of the preferred ways, let me know in the comments what do you think about this method?&lt;br&gt;
Thanks for reading!😊&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>mern</category>
    </item>
  </channel>
</rss>
