<?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: Amirmahdi Sultani</title>
    <description>The latest articles on DEV Community by Amirmahdi Sultani (@amirmahdi01).</description>
    <link>https://dev.to/amirmahdi01</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%2F3825369%2F24ad97b9-43a2-449a-a8e9-0296ca4458a5.jpg</url>
      <title>DEV Community: Amirmahdi Sultani</title>
      <link>https://dev.to/amirmahdi01</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/amirmahdi01"/>
    <language>en</language>
    <item>
      <title>🤔 what i was thinking of was having the experience of using next.js routing in react</title>
      <dc:creator>Amirmahdi Sultani</dc:creator>
      <pubDate>Mon, 16 Mar 2026 13:03:29 +0000</pubDate>
      <link>https://dev.to/amirmahdi01/what-i-was-thinking-of-was-having-the-experience-of-using-nextjs-routing-in-react-24k6</link>
      <guid>https://dev.to/amirmahdi01/what-i-was-thinking-of-was-having-the-experience-of-using-nextjs-routing-in-react-24k6</guid>
      <description>&lt;p&gt;🤔 what i was thinking of was having the experience of using next.js routing in react &lt;/p&gt;

&lt;p&gt;🚀 therefore  upcoming.js — was born &lt;/p&gt;

&lt;p&gt;if you use React + Vite you know this pain.&lt;br&gt;
every new project. every new route. same boilerplate:&lt;br&gt;
&lt;br&gt;
  &lt;br&gt;
    } /&amp;gt;&lt;br&gt;
    } /&amp;gt;&lt;br&gt;
    } /&amp;gt;&lt;br&gt;
  &lt;br&gt;
&lt;br&gt;
every. single. time.&lt;/p&gt;

&lt;p&gt;meanwhile Next.js developers just create a folder&lt;br&gt;
and the route exists. no imports. no declarations. nothing.&lt;/p&gt;

&lt;p&gt;i wanted that. but i didn't want Next.js.&lt;br&gt;
i wanted React. i wanted Vite. i wanted freedom.&lt;/p&gt;

&lt;p&gt;so i built upcoming.js.&lt;/p&gt;

&lt;p&gt;a Vite plugin that brings Next.js-style file routing&lt;br&gt;
to any React + Vite project. no framework. no lock-in.&lt;br&gt;
just the one feature that actually matters.&lt;br&gt;
src/&lt;br&gt;
├── page.jsx              →  /&lt;br&gt;
├── about/&lt;br&gt;
│   └── page.jsx          →  /about&lt;br&gt;
└── blog/&lt;br&gt;
    └── [id]/&lt;br&gt;
        └── page.jsx      →  /blog/:id&lt;br&gt;
that's your entire router.&lt;br&gt;
create a folder → route appears instantly.&lt;br&gt;
delete a folder → route is gone.&lt;br&gt;
no restarts. no imports. no boilerplate. ever.&lt;/p&gt;

&lt;p&gt;and since it's built on React Router under the hood —&lt;br&gt;
useParams, useNavigate, Link — everything works&lt;br&gt;
exactly the way you already know.&lt;/p&gt;

&lt;p&gt;no new APIs. no new concepts.&lt;br&gt;
just folders.&lt;/p&gt;

&lt;p&gt;npm i upcoming.js&lt;/p&gt;

&lt;p&gt;📦 npm → npmjs.com/package/upcoming.js&lt;br&gt;
🐙 github → github.com/amirmahdi1390/upcoming.js&lt;/p&gt;

&lt;p&gt;if this saves you time, drop a ⭐️ on github.&lt;br&gt;
it means a lot for a first time package author 🙏&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>react</category>
      <category>npm</category>
    </item>
    <item>
      <title>I Got Tired of React Router Boilerplate — So I Built Next.js Routing for Vite</title>
      <dc:creator>Amirmahdi Sultani</dc:creator>
      <pubDate>Sun, 15 Mar 2026 13:43:43 +0000</pubDate>
      <link>https://dev.to/amirmahdi01/i-got-tired-of-react-router-boilerplate-so-i-built-nextjs-routing-for-vite-25lp</link>
      <guid>https://dev.to/amirmahdi01/i-got-tired-of-react-router-boilerplate-so-i-built-nextjs-routing-for-vite-25lp</guid>
      <description>&lt;p&gt;I love React. I love Vite. Fast builds, full control, no magic, no framework &lt;br&gt;
telling me how to structure my entire application. Just React the way it was &lt;br&gt;
meant to be used.&lt;/p&gt;

&lt;p&gt;But every single project, without fail, I found myself writing this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BrowserRouter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Route&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;react-router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Home&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;./pages/Home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;About&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;./pages/About&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Blog&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;./pages/Blog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;BlogPost&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;./pages/BlogPost&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;NotFound&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;./pages/NotFound&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BrowserRouter&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Routes&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Home&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/about"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;About&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/blog"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Blog&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/blog/:id"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BlogPost&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NotFound&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Routes&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;BrowserRouter&lt;/span&gt;&lt;span class="p"&gt;&amp;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;Every. Single. Project.&lt;/p&gt;

&lt;p&gt;And every time a new page gets added, I open this file, add an import at the &lt;br&gt;
top, add a Route at the bottom, save, and get back to what I was actually &lt;br&gt;
trying to do.&lt;/p&gt;

&lt;p&gt;It's not hard. It's just... noise. Pure boilerplate that adds zero value.&lt;/p&gt;


&lt;h2&gt;
  
  
  Then I Looked at Next.js
&lt;/h2&gt;

&lt;p&gt;Next.js developers don't write any of this. They just create a folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
├── page.jsx          ← that's /
├── about/
│   └── page.jsx      ← that's /about
└── blog/
    └── [id]/
        └── page.jsx  ← that's /blog/:id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The route exists the moment the file exists. No imports. No declarations. &lt;br&gt;
No ceremony.&lt;/p&gt;

&lt;p&gt;That's genuinely brilliant. File structure IS the routing structure. It's &lt;br&gt;
visual, it's intuitive, and it completely eliminates an entire category of &lt;br&gt;
boilerplate.&lt;/p&gt;

&lt;p&gt;But here's my problem — &lt;strong&gt;I don't want to use Next.js.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I don't want a full framework. I don't want server components, I don't want &lt;br&gt;
the Next.js opinions on data fetching, I don't want to be locked into Vercel's &lt;br&gt;
ecosystem. I want React. I want Vite. I want to build my app my way.&lt;/p&gt;

&lt;p&gt;I just wanted that one feature.&lt;/p&gt;

&lt;p&gt;So I built it.&lt;/p&gt;


&lt;h2&gt;
  
  
  Introducing upcoming.js
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;upcoming.js&lt;/strong&gt; is a Vite plugin that brings Next.js-style file-based routing &lt;br&gt;
to any React + Vite project. No framework. No lock-in. Just the feature.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i upcoming.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The setup is two steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Add the plugin to vite.config.js&lt;/strong&gt;&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&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;vite&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;react&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;@vitejs/plugin-react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;upcoming&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;upcoming.js&lt;/span&gt;&lt;span class="dl"&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;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;react&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nf"&gt;upcoming&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;dedupe&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;react&lt;/span&gt;&lt;span class="dl"&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;react-dom&lt;/span&gt;&lt;span class="dl"&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;react-router&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;&lt;strong&gt;Step 2 — Replace your main.jsx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&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;react-dom/client&lt;/span&gt;&lt;span class="dl"&gt;'&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;UpcomingRouter&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;upcoming.js/runtime&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UpcomingRouter&lt;/span&gt; &lt;span class="p"&gt;/&amp;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's it. You're done. Now just create folders.&lt;/p&gt;




&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Basic Routes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── page.jsx                   →  /
├── about/
│   └── page.jsx               →  /about
└── contact/
    └── page.jsx               →  /contact
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each &lt;code&gt;page.jsx&lt;/code&gt; file is a route. The folder path is the URL. Simple.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dynamic Routes
&lt;/h3&gt;

&lt;p&gt;Wrap a folder name in square brackets to create a dynamic segment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
└── blog/
    ├── page.jsx               →  /blog
    └── [id]/
        └── page.jsx           →  /blog/:id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you access the param exactly like you would in React Router:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useParams&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;react-router&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;BlogPost&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useParams&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Post: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because under the hood, it IS React Router. upcoming.js is just the layer &lt;br&gt;
that wires everything together automatically.&lt;/p&gt;
&lt;h3&gt;
  
  
  Route Groups
&lt;/h3&gt;

&lt;p&gt;Wrap a folder in parentheses to group routes without affecting the URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── (marketing)/
│   ├── about/
│   │   └── page.jsx           →  /about
│   └── contact/
│       └── page.jsx           →  /contact
└── (app)/
    ├── dashboard/
    │   └── page.jsx           →  /dashboard
    └── settings/
        └── page.jsx           →  /settings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perfect for feature-based or domain-based folder structures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Private Folders
&lt;/h3&gt;

&lt;p&gt;Prefix any folder with &lt;code&gt;_&lt;/code&gt; to exclude it from routing completely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── _components/
│   └── Navbar.jsx             →  ignored
├── _utils/
│   └── helpers.js             →  ignored
└── about/
    └── page.jsx               →  /about ✓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  404 Page
&lt;/h3&gt;

&lt;p&gt;Just create &lt;code&gt;notfound.jsx&lt;/code&gt; at the root of your routes folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;404 — This page does not exist&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Navigation
&lt;/h2&gt;

&lt;p&gt;Since upcoming.js is built on top of React Router, all navigation works &lt;br&gt;
exactly as you already know:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useNavigate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useLocation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useParams&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;react-router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// Link component&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/about&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Go&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;About&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// Programmatic navigation&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;navigate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useNavigate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;navigate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Read current location&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useLocation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// Dynamic params&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useParams&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No new APIs. No new concepts to learn. If you know React Router, you already &lt;br&gt;
know how to use upcoming.js.&lt;/p&gt;


&lt;h2&gt;
  
  
  Live Route Updates
&lt;/h2&gt;

&lt;p&gt;One of my favorite parts — when you add a new &lt;code&gt;page.jsx&lt;/code&gt; file while the dev &lt;br&gt;
server is running, the route appears instantly. No restart needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;→ create src/pricing/page.jsx
→ browser reloads automatically
→ /pricing now exists
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Vite plugin watches your folder structure using Vite's built-in file &lt;br&gt;
watcher and invalidates the virtual module whenever a route file is &lt;br&gt;
added or removed.&lt;/p&gt;


&lt;h2&gt;
  
  
  How It Works Under the Hood
&lt;/h2&gt;

&lt;p&gt;This was the most interesting part to build. Here's the short version:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Vite Plugin API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;upcoming.js registers itself as a Vite plugin. On startup it scans your &lt;br&gt;
&lt;code&gt;src/&lt;/code&gt; folder recursively looking for &lt;code&gt;page.jsx&lt;/code&gt; files and builds a routes &lt;br&gt;
array from the folder structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Virtual Modules&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The routes array gets turned into a JavaScript module that lives in memory — &lt;br&gt;
not on disk. Vite has a concept called virtual modules that lets plugins &lt;br&gt;
intercept imports and return generated code instead of reading from the &lt;br&gt;
filesystem.&lt;/p&gt;

&lt;p&gt;So when your &lt;code&gt;Router.jsx&lt;/code&gt; does:&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;routes&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;virtual:upcoming&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your plugin intercepts that import and returns the generated routes code &lt;br&gt;
on the fly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. File Watching&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vite's built-in watcher fires events when files are added or deleted. The &lt;br&gt;
plugin listens for these events, re-scans the folder, regenerates the virtual &lt;br&gt;
module, invalidates the old one in Vite's module graph, and sends a &lt;br&gt;
full-reload signal to the browser via WebSocket.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Lazy Loading&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every page component is wrapped in React's &lt;code&gt;lazy()&lt;/code&gt; automatically:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Page0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;lazy&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/src/about/page.jsx&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;So every route is automatically code-split. Users only download the code &lt;br&gt;
for the page they're actually visiting.&lt;/p&gt;




&lt;h2&gt;
  
  
  This Is My First npm Package
&lt;/h2&gt;

&lt;p&gt;I want to be honest — this is the first package I've ever published. I built &lt;br&gt;
it because I genuinely needed it, not because I wanted to build a package.&lt;/p&gt;

&lt;p&gt;I learned a lot along the way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How Vite plugins work and what hooks are available&lt;/li&gt;
&lt;li&gt;What virtual modules are and how to use them&lt;/li&gt;
&lt;li&gt;The difference between &lt;code&gt;dependencies&lt;/code&gt; and &lt;code&gt;peerDependencies&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;How to handle Windows path separators (always normalize with &lt;code&gt;/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Why duplicate React instances break everything and how &lt;code&gt;dedupe&lt;/code&gt; fixes it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're thinking about building your first npm package — just build &lt;br&gt;
something you actually need. The motivation to finish it is so much stronger &lt;br&gt;
when you're solving your own real problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;I'm planning to add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;layout.jsx&lt;/code&gt; — wraps all child routes, like Next.js layouts&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;loading.jsx&lt;/code&gt; — per-route loading state&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;error.jsx&lt;/code&gt; — per-route error boundary&lt;/li&gt;
&lt;li&gt;TypeScript support out of the box&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i upcoming.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📦 npm: &lt;a href="https://www.npmjs.com/package/upcoming.js" rel="noopener noreferrer"&gt;upcoming.js&lt;/a&gt;&lt;br&gt;&lt;br&gt;
🐙 GitHub: &lt;a href="https://github.com/amirmahdi1390/upcoming.js" rel="noopener noreferrer"&gt;github.com/amirmahdi1390/upcoming.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you try it and run into any issues, open a GitHub issue. If you find it &lt;br&gt;
useful, a star on GitHub means a lot for a first-time package author ⭐&lt;/p&gt;

&lt;p&gt;I'd love to hear what you think.&lt;/p&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>vite</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
