<?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: Norbert Madojemu</title>
    <description>The latest articles on DEV Community by Norbert Madojemu (@norbert_madojemu_e4d44040).</description>
    <link>https://dev.to/norbert_madojemu_e4d44040</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%2F3641968%2F70ef347e-c8e6-4826-bdfa-6a7bed113657.png</url>
      <title>DEV Community: Norbert Madojemu</title>
      <link>https://dev.to/norbert_madojemu_e4d44040</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/norbert_madojemu_e4d44040"/>
    <language>en</language>
    <item>
      <title>I Got Tired of Rebuilding Admin Dashboards, So I Made One Installable</title>
      <dc:creator>Norbert Madojemu</dc:creator>
      <pubDate>Thu, 25 Dec 2025 16:55:32 +0000</pubDate>
      <link>https://dev.to/norbert_madojemu_e4d44040/i-got-tired-of-rebuilding-admin-dashboards-so-i-made-one-installable-4ie2</link>
      <guid>https://dev.to/norbert_madojemu_e4d44040/i-got-tired-of-rebuilding-admin-dashboards-so-i-made-one-installable-4ie2</guid>
      <description>&lt;p&gt;Every admin dashboard I worked on looked different on paper — but structurally, they were the same.&lt;/p&gt;

&lt;p&gt;Same sidebar.&lt;br&gt;
Same header.&lt;br&gt;
Same colors.&lt;br&gt;
Same responsiveness problems.&lt;/p&gt;

&lt;p&gt;Yet for every new project, we rebuilt the layout from scratch.&lt;/p&gt;

&lt;p&gt;That changed the day I spent several minutes debugging a slightly “off” dashboard width in a new project and realized something was wrong with our process, not the layout.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Moment I’d Had Enough&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I was collaborating with a colleague on a new internal project. He built the initial admin layout, and when I opened it, something felt… off.&lt;/p&gt;

&lt;p&gt;The width wasn’t right.&lt;/p&gt;

&lt;p&gt;Not obviously broken. Just wrong enough to be annoying.&lt;/p&gt;

&lt;p&gt;So I spent several minutes digging through the layout:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;container widths&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;padding&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;sidebar calculations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tailwind classes stacked on Tailwind classes&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eventually I found the issue, but the real question hit me harder:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why are we still debugging dashboard layouts in 2025?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We had already solved this problem before. Multiple times.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Real Problem (It Wasn’t the Layout)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The real issue wasn’t that dashboards are hard to build.&lt;/p&gt;

&lt;p&gt;It was that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We kept rewriting the same TailwindCSS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We copied files between projects and fixed breakages&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We re-tested mobile responsiveness every time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Minor inconsistencies kept creeping in across projects&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All this before writing a single line of business logic.&lt;/p&gt;

&lt;p&gt;That’s when the idea became obvious:&lt;/p&gt;

&lt;p&gt;What if the dashboard itself was just… installable?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Idea: A Reusable Dashboard as an npm Package&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of rebuilding or copying layouts, I wanted to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install a package&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get a consistent admin dashboard structure&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Skip layout and responsiveness setup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Focus purely on features and logic&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not a design system.&lt;br&gt;
Not a full-blown framework.&lt;/p&gt;

&lt;p&gt;Just a &lt;strong&gt;solid dashboard foundation.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building the Dashboard (The Comfortable Part)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I started fresh and rebuilt the dashboard using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;React&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TypeScript&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TailwindCSS&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It intentionally mirrored what we already used internally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Same color palette&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Same font face&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Same sidebar/header/content structure&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Same responsive behavior&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This part was easy. Familiar. Almost relaxing.&lt;/p&gt;

&lt;p&gt;Then I decided to package it.&lt;/p&gt;

&lt;p&gt;That’s where things got… spicy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Turning It into an npm Package (The Humbling Part)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I genuinely thought this would be straightforward.&lt;/p&gt;

&lt;p&gt;It wasn’t.&lt;/p&gt;

&lt;p&gt;I actually gave up halfway through the first attempt.&lt;br&gt;
Then came back.&lt;br&gt;
Then almost gave up again.&lt;/p&gt;

&lt;p&gt;But a new project landed — one that needed the exact same dashboard — and I refused to rebuild it from scratch.&lt;/p&gt;

&lt;p&gt;So I pushed through.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Why Is My Design Broken?” — The Debugging Saga&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I packaged the dashboard, installed it into a host project, and…&lt;/p&gt;

&lt;p&gt;The layout broke.&lt;/p&gt;

&lt;p&gt;Spacing was off.&lt;br&gt;
Styles were missing.&lt;br&gt;
Everything looked almost right — which is the worst kind of wrong.&lt;/p&gt;

&lt;p&gt;After a lot of back-and-forth, I realized two key issues:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The styles weren’t being bundled correctly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The host project wasn’t resolving the style paths properly&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This led to a painful loop:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;fix&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;build&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;publish&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;install&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;notice something else broke&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The package went through several versions.&lt;/p&gt;

&lt;p&gt;I think we’re currently on &lt;strong&gt;version 8&lt;/strong&gt; — the first one I’d confidently call “stable”.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Finally Worked&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once I slowed down and treated this like a real library (not a side hack), things clicked.&lt;/p&gt;

&lt;p&gt;The final approach looked like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Build and test the dashboard normally with React + TypeScript&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set &lt;strong&gt;React as a peer dependency&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;it is very important to note that you don’t ship React with your library, you share the host app’s React instance&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Clean up the project structure&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Properly bundle styles so they work in consuming apps&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a build step&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Publish to npm&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simple in theory. Unforgiving in practice.&lt;/p&gt;

&lt;p&gt;A Tiny Usage Example&lt;/p&gt;

&lt;p&gt;Once installed, using the dashboard looks something 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;import { DashboardLayout } from "admin-dashboard";

function App() {
  return (
    &amp;lt;DashboardLayout&amp;gt;
      &amp;lt;h1&amp;gt;Dashboard Overview&amp;lt;/h1&amp;gt;
      {/* Your actual features live here */}
    &amp;lt;/DashboardLayout&amp;gt;
  );
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;Sidebar.&lt;br&gt;
Header.&lt;br&gt;
Responsive layout.&lt;/p&gt;

&lt;p&gt;Handled.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why This Was 100% Worth It&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, when I start a new project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I install the package&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I get a familiar, consistent dashboard instantly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mobile responsiveness is already solved&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Styling is no longer a recurring discussion&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most importantly, I get to focus on functionality, not layout déjà vu.&lt;/p&gt;

&lt;p&gt;This wasn’t about building a “cool npm package”.&lt;/p&gt;

&lt;p&gt;It was about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Saving time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reducing cognitive load&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enforcing consistency&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Treating internal tooling like a first-class citizen&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;If you’ve rebuilt the same admin dashboard more than twice, this isn’t a motivation problem.&lt;/p&gt;

&lt;p&gt;It’s a systems problem.&lt;/p&gt;

&lt;p&gt;And sometimes, the most impactful solution isn’t a new feature —&lt;br&gt;
it’s packaging the thing you’re already tired of rebuilding.&lt;/p&gt;

&lt;p&gt;If this sounds familiar, maybe your next productivity win isn’t another refactor…&lt;/p&gt;

&lt;p&gt;Maybe it’s your first npm package.&lt;/p&gt;

</description>
      <category>react</category>
      <category>npm</category>
      <category>architecture</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
