<?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: Shourya Parashar</title>
    <description>The latest articles on DEV Community by Shourya Parashar (@im-shourya).</description>
    <link>https://dev.to/im-shourya</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%2F3898002%2F6284c5d3-4556-4805-bc4e-8fc555bbaf7e.jpg</url>
      <title>DEV Community: Shourya Parashar</title>
      <link>https://dev.to/im-shourya</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/im-shourya"/>
    <language>en</language>
    <item>
      <title>KanbanFlow</title>
      <dc:creator>Shourya Parashar</dc:creator>
      <pubDate>Sat, 25 Apr 2026 20:37:33 +0000</pubDate>
      <link>https://dev.to/im-shourya/kanbanflow-3am9</link>
      <guid>https://dev.to/im-shourya/kanbanflow-3am9</guid>
      <description>&lt;p&gt;I Built a Zero-Backend Kanban Board with React + TypeScript — Here's What I Learned&lt;/p&gt;

&lt;p&gt;No server. No database. No login. Just pure React — and it actually works great.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why I Built KanbanFlow&lt;/strong&gt;&lt;br&gt;
Every Kanban tool I used asked me to sign up, connect to a server, or pay for features I didn't need. I wanted something that just &lt;strong&gt;opened and worked&lt;/strong&gt; — instantly, privately, offline.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://kanbanflow.shouryaparashar.in" rel="noopener noreferrer"&gt;KanbanFlow&lt;/a&gt; — a fully-featured Kanban board that lives entirely in your browser. No account. No backend. No setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What It Does&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unlimited columns and tasks&lt;/strong&gt; — fully customizable&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drag &amp;amp; drop&lt;/strong&gt; task movement across columns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Priority tagging&lt;/strong&gt; — High, Medium, Low, None&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Due dates&lt;/strong&gt; with overdue highlighting&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live search&lt;/strong&gt; + priority filtering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dark / Light theme&lt;/strong&gt; toggle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-saves to localStorage&lt;/strong&gt; — data persists across sessions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tech Stack&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;React 18 + Vite 5 + TypeScript 5 + Tailwind CSS + React Router v6&lt;/p&gt;

&lt;p&gt;No Redux. No external state library. Just React's &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useReducer&lt;/code&gt; — keeping it lean.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Interesting Part — localStorage as a Database&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most people reach for Firebase or Supabase immediately. But for a personal productivity tool, &lt;code&gt;localStorage&lt;/code&gt; is genuinely underrated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Auto-save board state on every change&lt;/span&gt;
&lt;span class="nf"&gt;useEffect&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="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;kanban-board&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;board&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="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Load on mount&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;board&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setBoard&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Board&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saved&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;kanban-board&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;saved&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;saved&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;defaultBoard&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 pattern gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instant persistence with zero latency&lt;/li&gt;
&lt;li&gt;Works completely offline&lt;/li&gt;
&lt;li&gt;No auth, no API keys, no cost&lt;/li&gt;
&lt;li&gt;Data stays on the user's machine (privacy win)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tradeoff? No cross-device sync. For a personal board, that's totally acceptable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Drag &amp;amp; Drop Without a Library&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of reaching for &lt;code&gt;react-beautiful-dnd&lt;/code&gt; or &lt;code&gt;dnd-kit&lt;/code&gt;, I implemented drag and drop using the native HTML5 Drag and Drop API — which kept the bundle size tiny.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleDragStart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DragEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;taskId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataTransfer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;taskId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;taskId&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="nx"&gt;handleDrop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DragEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;targetColumnId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;taskId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataTransfer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;taskId&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;moveTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;taskId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;targetColumnId&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;Project Structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I kept the component tree flat and predictable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── types/kanban.ts         # All types + constants
├── components/kanban/
│   ├── TaskCard.tsx
│   ├── KanbanColumn.tsx
│   ├── TaskForm.tsx
│   ├── Header.tsx
│   └── Toolbar.tsx
└── pages/
    └── Index.tsx           # Main orchestrator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One rule I followed: &lt;strong&gt;no component does more than one thing&lt;/strong&gt;. &lt;code&gt;KanbanColumn&lt;/code&gt; renders a column. &lt;code&gt;TaskCard&lt;/code&gt; renders a card. &lt;code&gt;Index.tsx&lt;/code&gt; wires them together.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Try It&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live:&lt;/strong&gt; &lt;a href="https://kanbanflow.shouryaparashar.in" rel="noopener noreferrer"&gt;kanbanflow.shouryaparashar.in&lt;/a&gt; &lt;br&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/im-shourya/KanbanFlow" rel="noopener noreferrer"&gt;github.com/im-shourya/KanbanFlow&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Built by &lt;a href="https://shouryaparashar.in" rel="noopener noreferrer"&gt;Shourya Parashar&lt;/a&gt; — Full Stack Developer.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you found this useful, drop a ⭐ on GitHub — it genuinely helps!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>typescript</category>
      <category>buildinpublic</category>
    </item>
  </channel>
</rss>
