DEV Community

Devanshu Biswas
Devanshu Biswas

Posted on

I Cloned Linear's Sidebar in 50 Lines of HTML — One File, Zero npm

🌐 Live demo (LOOK · UNDERSTAND · BUILD): https://dev48v.infy.uk/design/day2-linear-sidebar.html

Day 2 of my DesignFromZero series — clone 50 iconic UIs in 50 days, one HTML file each, no npm, no build setup.

Today: Linear's sidebar. The dark-mode app-shell pattern that Linear, Notion, Slack, Discord, and every modern SaaS sidebar copies.


Why this UI matters

Once you build a Linear-style sidebar, you have the skeleton for:

  • Discord (servers + channels)
  • Notion (workspace + nested pages)
  • Slack (workspaces + channels + DMs)
  • Github (repos + issues + PRs)

It's the app-shell pattern: fixed left column, flexible main column, the entire app lives in that grid. Master it once.


The shape

┌──────────────────────────────────────┐
│  D  Workspace          ⌘K            │
├──────────────────────────────────────┤
│  📥  Inbox          [3]              │
│  🎯  My issues    ← active           │
│  👁  Subscribed                       │
│                                       │
│  WORKSPACE                            │
│  ●  Active projects                  │
│  ●  Roadmap                          │
│                                       │
│  TEAMS                                │
│  F  Frontend                          │
│  B  Backend                           │
├──────────────────────────────────────┤
│  v2.81.0           ●  Online         │
└──────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Six chunks: header (logo + workspace + ⌘K hint), primary nav (3 personal rows), section header ("WORKSPACE"), status-dot items, team rows with avatars, status footer. That's the whole pattern.


The whole thing (~50 lines)

<!DOCTYPE html>
<html><head><script src="https://cdn.tailwindcss.com"></script></head>
<body class="bg-[#16161a] text-slate-300 min-h-screen flex">
  <aside class="w-64 bg-[#1c1c20] border-r border-[#26262b] flex flex-col">
    <!-- Workspace header -->
    <div class="px-4 py-3 border-b border-[#26262b] flex items-center gap-2">
      <div class="w-7 h-7 bg-gradient-to-br from-fuchsia-500 to-rose-500 rounded text-white text-xs font-bold flex items-center justify-center">D</div>
      <span class="font-semibold text-white text-sm">Workspace</span>
      <span class="ml-auto text-slate-500 text-xs">⌘K</span>
    </div>

    <!-- Primary nav -->
    <nav class="flex-1 px-2 py-3 space-y-0.5 text-sm">
      <a class="flex items-center gap-2 px-2 py-1.5 rounded hover:bg-[#26262b]">📥 Inbox <span class="ml-auto bg-rose-500 text-white text-xs px-1.5 rounded-full">3</span></a>
      <a class="flex items-center gap-2 px-2 py-1.5 rounded bg-[#2a2a30] text-white">🎯 My issues</a>
      <a class="flex items-center gap-2 px-2 py-1.5 rounded hover:bg-[#26262b]">👁 Subscribed</a>

      <!-- Section header -->
      <div class="pt-4 pb-1 px-2 text-xs uppercase tracking-widest text-slate-500">Workspace</div>
      <a class="flex items-center gap-2 px-2 py-1.5 rounded hover:bg-[#26262b]"><span class="w-2 h-2 bg-emerald-500 rounded-full"></span> Active projects</a>
      <a class="flex items-center gap-2 px-2 py-1.5 rounded hover:bg-[#26262b]"><span class="w-2 h-2 bg-amber-500 rounded-full"></span> Roadmap</a>

      <!-- Teams with avatar squares -->
      <div class="pt-4 pb-1 px-2 text-xs uppercase tracking-widest text-slate-500">Teams</div>
      <a class="flex items-center gap-2 px-2 py-1.5 rounded hover:bg-[#26262b]"><div class="w-4 h-4 bg-indigo-500 rounded text-xs text-white font-bold flex items-center justify-center">F</div> Frontend</a>
      <a class="flex items-center gap-2 px-2 py-1.5 rounded hover:bg-[#26262b]"><div class="w-4 h-4 bg-emerald-500 rounded text-xs text-white font-bold flex items-center justify-center">B</div> Backend</a>
    </nav>

    <!-- Status footer -->
    <div class="px-3 py-3 border-t border-[#26262b] text-xs flex items-center justify-between">
      <span class="text-slate-500">v2.81.0</span>
      <span class="text-emerald-500">● Online</span>
    </div>
  </aside>
  <main class="flex-1 p-8">
    <h2 class="text-2xl font-bold text-white">My issues</h2>
  </main>
</body></html>
Enter fullscreen mode Exit fullscreen mode

That's it. One file. Open in browser. Done.


The 8 ideas to internalize

What it teaches
App-shell layout <body class="flex"> + fixed w-64 aside + flex-1 main. Whole app lives here.
Workspace header Logo + name + ⌘K shortcut hint. Border-bottom separates from nav.
Primary nav rows Icon + label + optional badge. Rounded hover background. Active = stronger background.
Badges Tiny rounded-full pills with counts. ml-auto pushes them to the right.
Section headers Tiny uppercase grey labels (text-xs uppercase tracking-widest) group items. Pure structure.
Status dots 2px colored dots signal state without words. Green = active, amber = WIP, grey = idle.
Team avatars Small colored squares with the first letter. Slack / Linear / Notion all use this.
Status footer Version + connection status. border-t + flex-row layout. Pushed to bottom via flex-1 on nav above.

Read each block of the HTML above and you're learning these 8 patterns simultaneously. Each one transfers to every modern app-shell UI.


Try it now

Open the LOOK · UNDERSTAND · BUILD page:
https://dev48v.infy.uk/design/day2-linear-sidebar.html

  • LOOK — the finished sidebar in your browser, no setup
  • UNDERSTAND — 9 click-through steps with preview + WHY + code for each piece
  • BUILD — copy the whole HTML file, save, double-click, done

What's next in DesignFromZero

Day 3: Vercel deploy log — the terminal-style streaming UI Vercel shows during a deploy.

Series: 50 UIs in 50 days · pure HTML + Tailwind · zero build.

🌐 All days: https://dev48v.infy.uk/designfromzero.php

Top comments (0)