<?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: Kushagra Dhawan</title>
    <description>The latest articles on DEV Community by Kushagra Dhawan (@kushagradhawan).</description>
    <link>https://dev.to/kushagradhawan</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%2F3775328%2F2d028262-9b13-4fd3-a68e-690d2aaa236d.png</url>
      <title>DEV Community: Kushagra Dhawan</title>
      <link>https://dev.to/kushagradhawan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kushagradhawan"/>
    <language>en</language>
    <item>
      <title>Kookie Blocks: Higher-Level Components for Kookie UI</title>
      <dc:creator>Kushagra Dhawan</dc:creator>
      <pubDate>Fri, 20 Feb 2026 07:59:00 +0000</pubDate>
      <link>https://dev.to/kushagradhawan/kookie-blocks-higher-level-components-for-kookie-ui-35po</link>
      <guid>https://dev.to/kushagradhawan/kookie-blocks-higher-level-components-for-kookie-ui-35po</guid>
      <description>&lt;p&gt;Kookie Blocks is a collection of pre-built patterns on top of Kookie UI. Same design system, one layer higher.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Gap
&lt;/h2&gt;

&lt;p&gt;Kookie UI gives you primitives. Buttons, cards, inputs, sidebars, shells. These are the building blocks, and they work well. But every time I started a new project, I found myself rebuilding the same patterns.&lt;/p&gt;

&lt;p&gt;Documentation sites need a shell with a sidebar, a content area, and a table of contents. The sidebar needs sections, navigation items, search. The content area needs proper typography, code blocks with syntax highlighting, component previews. The table of contents needs to track scroll position and highlight the current section.&lt;/p&gt;

&lt;p&gt;AI interfaces need streaming markdown. Rendering markdown is straightforward. Rendering markdown that's still being written is not. Incomplete syntax mid-stream. Re-renders on every token. Code blocks that flicker because the closing backticks haven't arrived yet. Bold text that breaks because the second &lt;code&gt;**&lt;/code&gt; hasn't come through.&lt;/p&gt;

&lt;p&gt;Marketing pages need heroes, footers, testimonials. These aren't complex, but they take time to get right every time.&lt;/p&gt;

&lt;p&gt;I kept building these patterns from scratch. Each project started with the same work before I could get to the actual product.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhfr8v5p7042v0glh1mc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhfr8v5p7042v0glh1mc.png" alt="Kookie Blocks Hero" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Kookie Blocks is that layer between primitives and products. It takes Kookie UI's components and composes them into patterns you can use directly.&lt;/p&gt;

&lt;p&gt;The blocks fall into a few categories.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Marketing.&lt;/strong&gt; Hero, Footer, Testimonial. The pieces you need for a landing page. Drop them in, pass your content, done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Application.&lt;/strong&gt; Page Header, Section Header, Empty State. Common UI patterns that show up in almost every app. Consistent layout, consistent spacing, consistent typography.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI.&lt;/strong&gt; This is where some of the harder problems live.&lt;/p&gt;

&lt;p&gt;Markdown Components creates component mappings for react-markdown and MDX using Kookie UI components. Headings, paragraphs, code blocks, lists, tables, all styled with Kookie UI's typography and spacing. Use this utility to render markdown content that looks like it belongs in your app.&lt;/p&gt;

&lt;p&gt;Streaming Markdown handles the hard parts of rendering AI-generated content. It handles incomplete markdown gracefully during streaming. Block-level memoization means completed blocks don't re-render when new tokens arrive. The component is designed for real-time updates where content is still being written.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgz7cy2mdtz3t6lmb3g5n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgz7cy2mdtz3t6lmb3g5n.png" alt="Kookie Blocks Streaming Markdown Component" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation.&lt;/strong&gt; This is the most complete category.&lt;/p&gt;

&lt;p&gt;Code Block handles syntax highlighting, copy buttons, line numbers, language labels. Docs Shell provides the overall layout for a documentation site. Docs Sidebar handles navigation with sections, items, and collapsible groups. Docs Page structures content with proper spacing and typography. Table of Contents tracks scroll position and highlights the current section. Preview Block displays live component previews with customizable backgrounds, perfect for showcasing UI components in documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Interconnectedness
&lt;/h2&gt;

&lt;p&gt;This is the part I find interesting.&lt;/p&gt;

&lt;p&gt;Kookie UI provides Shell, a layout primitive for application frames. Kookie Blocks uses that Shell to build Docs Shell, adding the specific layout and behavior documentation sites need.&lt;/p&gt;

&lt;p&gt;Kookie UI provides Sidebar, a flexible navigation component. Kookie Blocks uses that Sidebar to build Docs Sidebar, adding documentation-specific patterns like section grouping and active state tracking.&lt;/p&gt;

&lt;p&gt;Then Kookie UI's own documentation site is built with Kookie Blocks.&lt;/p&gt;

&lt;p&gt;The libraries feed into each other. Kookie UI is the foundation. Kookie Blocks builds on it. Then Kookie UI uses Kookie Blocks for its own docs. Kookie Blocks uses Kookie Blocks for its own docs. Kookie Flow uses Kookie Blocks for its docs.&lt;/p&gt;

&lt;p&gt;When I improve something in Kookie UI, it flows up into Kookie Blocks. When I improve something in Kookie Blocks, all the documentation sites get better. When I'm building docs and notice something missing, I add it to Kookie Blocks, and every other docs site gets it too.&lt;/p&gt;

&lt;p&gt;This wasn't planned from the start. It emerged as I kept building. But it's become one of the things I like most about this setup. The system is self-reinforcing. Each piece makes the others better.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where It's Used
&lt;/h2&gt;

&lt;p&gt;Kookie Blocks powers the documentation for Kookie UI, Kookie Blocks itself, and Kookie Flow. My portfolio site uses pieces of it. Kookie AI uses the streaming markdown and markdown components.&lt;/p&gt;

&lt;p&gt;Every time I build something new, the patterns go into Kookie Blocks. Every project that uses Kookie Blocks gets those patterns for free.&lt;/p&gt;

&lt;h2&gt;
  
  
  Still Extremely Early
&lt;/h2&gt;

&lt;p&gt;Everything is in alpha. The APIs are still changing. Some blocks are more complete than others. The documentation blocks are fairly mature because I've been using them heavily. The marketing blocks are newer and less tested.&lt;/p&gt;

&lt;p&gt;I'm still figuring out the right abstractions. Where should the boundaries be? How much should each block do? How flexible versus how opinionated? These questions don't have obvious answers, and I'm learning as I go.&lt;/p&gt;

&lt;p&gt;But it's already saving me time. Instead of rebuilding a docs site from scratch, I import Docs Shell and Docs Sidebar and start writing content. Instead of solving streaming markdown again, I use the component that already handles it. Instead of styling code blocks for the fifth time, I use Code Block.&lt;/p&gt;

&lt;p&gt;That's the point. Solve the pattern once, use it everywhere.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kookieblocks.com" rel="noopener noreferrer"&gt;kookieblocks.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/KushagraDhawan1997/kookie-blocks" rel="noopener noreferrer"&gt;github.com/KushagraDhawan1997/kookie-blocks&lt;/a&gt;&lt;/p&gt;

</description>
      <category>designsystems</category>
      <category>components</category>
      <category>engineering</category>
      <category>ai</category>
    </item>
    <item>
      <title>Kookie User Interface: Building my own Design System</title>
      <dc:creator>Kushagra Dhawan</dc:creator>
      <pubDate>Tue, 17 Feb 2026 10:05:55 +0000</pubDate>
      <link>https://dev.to/kushagradhawan/kookie-user-interface-building-my-own-design-system-a4f</link>
      <guid>https://dev.to/kushagradhawan/kookie-user-interface-building-my-own-design-system-a4f</guid>
      <description>&lt;p&gt;I was using Radix Themes every day, and it did a lot of things right. It gave me components that were accessible out of the box, strong defaults, and a toolkit that let me move fast. The components worked reliably, the API felt intuitive, and I could trust that what I built would function for users. As I used it for real products, I found myself needing different choices: different patterns, different design decisions, and different opinions about how a design system should work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hellokookie.com/" rel="noopener noreferrer"&gt;KookieUI&lt;/a&gt; began as a fork of Radix Themes. I took the infrastructure they built and changed what sits on top of it. The underlying system remained, but I made considerable changes to the design layer: the tokens, the patterns, the opinions about spacing, sizing, theming, and component behavior. It's about taking something that works well and reshaping it to match how I think design systems should function.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Gap
&lt;/h2&gt;

&lt;p&gt;Radix Themes is a complete design system with its own opinions. Where I differed was in those opinions.&lt;/p&gt;

&lt;p&gt;When I started using it for real applications, I noticed places where I wanted different choices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Variants needed unification.&lt;/strong&gt; A "surface" card looked different from a "surface" button. The shadows meant different things across components. The visual language needed consistency. Some components had "classic" variants, others had different options. The system needed clear rules for when to use what.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Theming needed extension.&lt;/strong&gt; Radix had a panelBackground token for cards and tables. Dialogs, popovers, and dropdowns needed their own theming approach. The system needed per-component control so every surface could match the theme intentionally.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sizing needed alignment.&lt;/strong&gt; Each component had its own scale: cards went up to 5, buttons to 4, dropdowns to 3, selects to 2, avatars to 12. A size-1 button inside a size-1 card needed to feel related. The proportions needed to be systematic across all components.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Motion needed consistency.&lt;/strong&gt; Some transitions, like segmented controls, felt smooth and polished. Others, like tabs, snapped instantly with no easing. The system needed a consistent motion language.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Accessibility needed enforcement.&lt;/strong&gt; The core accessibility was excellent. Screen readers worked, keyboard navigation was solid. Icon buttons needed enforced aria-labels. Tooltips needed to be native. Icons needed consistent sizing across components.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Radix Themes delivered a complete system with its own choices. &lt;a href="https://hellokookie.com/" rel="noopener noreferrer"&gt;KookieUI&lt;/a&gt; is my version of those choices, built on the same infrastructure but shaped differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  The System
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://hellokookie.com/" rel="noopener noreferrer"&gt;KookieUI&lt;/a&gt; is a fork of Radix Themes with different design opinions. The infrastructure stays the same. What changed is the design layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Patterns before parts.&lt;/strong&gt; I start with spacing, radius, shadow, color, typography, and motion. These rules apply everywhere, and components inherit them consistently. When you use a size-2 button, it uses the same spacing scale as a size-2 card. When you apply a "surface" variant, it means the same thing across every component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Material system for backgrounds.&lt;/strong&gt; I replaced panelBackground with material, a system that defines how components render against whatever background they sit on. Material is more flexible and works across more use cases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At the theme level, you can decide: translucent or solid. This affects how the entire system feels.&lt;/li&gt;
&lt;li&gt;At the component level, you can override defaults. A dialog might need to be more opaque than a dropdown.&lt;/li&gt;
&lt;li&gt;Dialogs, panels, and buttons each get defaults that convey depth and elevation intentionally.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Unified tokens.&lt;/strong&gt; Sizes, radii, typography weights, and color scales all match across components. Every scale is systematic and intentional. If you see a size-3 anywhere in the system, it means the same thing everywhere. This consistency makes the system predictable and learnable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Accessibility enforced.&lt;/strong&gt; Icon buttons require labels, enforced at the component level. Tooltips are native and built in. Screen reader and keyboard support from Radix are extended with the details that matter in day-to-day use. The accessibility is built in and enforced by the API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extended patterns and components.&lt;/strong&gt; I added toggle buttons, toggle icon buttons, more typography weights, and layout primitives like shell, split view, and sidebars. Even new patterns like AI chat interfaces fit inside the same rules. The goal is to fill gaps where teams need patterns beyond what Radix Themes provided.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hellokookie.com/" rel="noopener noreferrer"&gt;KookieUI&lt;/a&gt; makes components behave consistently, as if they were designed together as a coherent system.&lt;/p&gt;

&lt;h2&gt;
  
  
  At Womp
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://hellokookie.com/" rel="noopener noreferrer"&gt;KookieUI&lt;/a&gt; started as my personal project. As I worked on it, I realized I could use it for Womp to solve real problems.&lt;/p&gt;

&lt;p&gt;The migration is ongoing. Some areas of the product run on &lt;a href="https://hellokookie.com/" rel="noopener noreferrer"&gt;KookieUI&lt;/a&gt;, others are still being migrated. Even in this partial state, the benefits are clear.&lt;/p&gt;

&lt;p&gt;Here's what changes when you have a system like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Speed.&lt;/strong&gt; Engineers get design details from the system. Update the dependency, and the new design flows in automatically. Consistency conversations are eliminated. The system handles design coherence, so engineers focus on functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Principles in code.&lt;/strong&gt; Spacing and motion rules live in the system itself as defaults. When someone uses a component, they get the right spacing automatically. When they need to override it, the system guides them toward the right choices.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Direct contribution.&lt;/strong&gt; I push design changes directly into &lt;a href="https://hellokookie.com/" rel="noopener noreferrer"&gt;KookieUI&lt;/a&gt; code, which means the team can move faster while maintaining polish. A design improvement I make on Monday can be in production by Tuesday, with full engineering implementation included.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Clear ownership.&lt;/strong&gt; Through &lt;a href="https://hellokookie.com/" rel="noopener noreferrer"&gt;KookieUI&lt;/a&gt;, design controls the design layer. If something looks wrong, the system needs to encode it. That responsibility belongs to me as the consulting design lead. Engineers implement design from the system. This creates clarity.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The migration is uneven. Some areas look and feel more coherent than others. The trend is clear: &lt;a href="https://hellokookie.com/" rel="noopener noreferrer"&gt;KookieUI&lt;/a&gt; gives design a way to lead through code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Still Learning
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://hellokookie.com/" rel="noopener noreferrer"&gt;KookieUI&lt;/a&gt; continues to evolve. I'm still figuring out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How to extend the system with new patterns while maintaining flexibility. Every new component I add has to fit the existing rules, but sometimes the rules need to evolve. Balancing consistency and flexibility is constant work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to refine motion and interaction so every component feels equally polished. Some components have smooth, thoughtful transitions. Others still feel a bit mechanical. Getting the motion language right across the entire system is harder than I expected.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to keep the system flexible enough to evolve while remaining dependable. Teams need components that work predictably. They also need a system that can grow with their needs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some days it feels like too much structure. Other days there are still gaps. That tension is part of building a design system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;Radix Themes gave me a solid foundation. &lt;a href="https://hellokookie.com/" rel="noopener noreferrer"&gt;KookieUI&lt;/a&gt; is my fork with different opinions built on that foundation.&lt;/p&gt;

&lt;p&gt;It's about noticing where I wanted different choices, and then implementing them. It's about codifying rules so design intent stays intact through implementation. It's about giving the design team a way to own how design shows up in the product through code. &lt;a href="https://hellokookie.com/" rel="noopener noreferrer"&gt;KookieUI&lt;/a&gt; remains open source because Radix Themes is open source.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hellokookie.com/" rel="noopener noreferrer"&gt;KookieUI&lt;/a&gt; is early and uneven. Some parts feel mature and stable, others are experimental. Step by step, it's making Womp faster, more consistent, and more deliberate. The team moves quicker because design decisions are encoded and consistency is enforced. I can iterate on design directly in code.&lt;/p&gt;

&lt;p&gt;That's enough reason for me to keep building. &lt;/p&gt;

</description>
      <category>designsystems</category>
      <category>radix</category>
      <category>engineering</category>
      <category>design</category>
    </item>
    <item>
      <title>New Component: Shell, a Layout Engine for Modern Apps</title>
      <dc:creator>Kushagra Dhawan</dc:creator>
      <pubDate>Mon, 16 Feb 2026 09:28:26 +0000</pubDate>
      <link>https://dev.to/kushagradhawan/about-shell-156o</link>
      <guid>https://dev.to/kushagradhawan/about-shell-156o</guid>
      <description>&lt;p&gt;Every application rebuilds the same layout. Sidebar on the left, maybe a header, content in the middle, perhaps an inspector panel on the right, sometimes a bottom panel for terminals or logs. Then you wire up the state—open, closed, pinned. Then responsive behavior—overlay on mobile, fixed on desktop. Then resize logic with drag handles and snap points.&lt;/p&gt;

&lt;p&gt;It's 500-1000 lines of layout code that has nothing to do with your actual product.&lt;/p&gt;

&lt;p&gt;I got tired of writing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Wanted
&lt;/h2&gt;

&lt;p&gt;Declare your layout, don't build it.&lt;/p&gt;

&lt;p&gt;I wanted to say "I need a sidebar that's overlay on mobile, fixed on desktop, resizable, with a thin icon-only mode" and have it work. Not wire up media queries, not manage state, not calculate positions. Just declare the intent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Root&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&lt;/span&gt;
    &lt;span class="na"&gt;presentation&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;initial&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;overlay&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fixed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;defaultState&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;initial&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;collapsed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expanded&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;resizable&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="nt"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Navigation&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;nav&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&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="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Your app&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;main&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Root&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's what Shell does. It's a layout engine that handles the infrastructure so you can focus on what goes inside the boxes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seven Slots
&lt;/h2&gt;

&lt;p&gt;Shell provides seven layout slots:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Header&lt;/strong&gt; — Fixed top bar for global navigation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rail&lt;/strong&gt; — Slim icon strip (think VS Code's activity bar)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Panel&lt;/strong&gt; — Expanded navigation that pairs with Rail&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sidebar&lt;/strong&gt; — Unified sidebar (alternative to Rail+Panel)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content&lt;/strong&gt; — Main content area (required)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inspector&lt;/strong&gt; — Right-side panel for properties, details, context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bottom&lt;/strong&gt; — Bottom panel for terminals, logs, output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why seven? Because these cover roughly 95% of application layouts I've seen. VS Code uses Header + Rail + Panel + Content + Bottom. Figma uses Header + Sidebar + Content + Inspector. Linear uses Sidebar + Content. Notion uses Sidebar + Content.&lt;/p&gt;

&lt;p&gt;The slots are composable. Use what you need, ignore what you don't. Shell figures out the layout math.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hard Decision: Composition Rules
&lt;/h2&gt;

&lt;p&gt;Early on, I had to decide: should Sidebar and Rail+Panel coexist?&lt;/p&gt;

&lt;p&gt;They're solving the same problem—left-side navigation—in different ways. Sidebar is a unified component with three states (collapsed, thin, expanded). Rail+Panel is a two-part system where the Rail (icon strip) and Panel (expanded nav) are separate components.&lt;/p&gt;

&lt;p&gt;Letting them coexist would create invalid states. What happens if Sidebar is expanded and Panel is also open? They'd overlap or fight for space.&lt;/p&gt;

&lt;p&gt;So Shell enforces composition rules. Sidebar OR Rail+Panel, never both. If you try to use both, you get a console warning.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Valid&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Root&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Root&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// Valid&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Root&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Rail&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Rail&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Panel&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Panel&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Root&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// Invalid — triggers warning&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Root&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Rail&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Rail&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Root&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This was a deliberate constraint. Invalid states should be impossible, not just discouraged.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three Presentation Modes
&lt;/h2&gt;

&lt;p&gt;How should a sidebar interact with content? It depends.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fixed&lt;/strong&gt; — The sidebar takes space in the layout. When it opens, content shrinks. When it closes, content expands. This is what you want on desktop where screen space is abundant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Overlay&lt;/strong&gt; — The sidebar floats above content as a modal sheet. Content doesn't move. This is what you want on mobile where you can't afford to shrink already-limited content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stacked&lt;/strong&gt; — The sidebar positions above content without a modal backdrop. For floating panels that don't demand attention.&lt;/p&gt;

&lt;p&gt;The key insight: presentation should be responsive. A sidebar that's fixed on desktop should become overlay on mobile. So Shell accepts responsive objects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&lt;/span&gt;
  &lt;span class="na"&gt;presentation&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;initial&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;overlay&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fixed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;defaultState&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;initial&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;collapsed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expanded&lt;/span&gt;&lt;span class="dl"&gt;'&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;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This says: "On mobile, start collapsed and use overlay presentation. On medium screens and up, start expanded and use fixed presentation."&lt;/p&gt;

&lt;p&gt;The responsive behavior is colocated with the component. You're not hunting through CSS files to understand how the sidebar behaves at different breakpoints.&lt;/p&gt;

&lt;h2&gt;
  
  
  State Management
&lt;/h2&gt;

&lt;p&gt;Each pane manages its own state: open/closed, size, presentation mode. But sometimes you need to control it programmatically.&lt;/p&gt;

&lt;p&gt;Shell supports both controlled and uncontrolled patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Uncontrolled — Shell manages state&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&lt;/span&gt; &lt;span class="na"&gt;defaultState&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"expanded"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

// Controlled — You manage state
const [state, setState] = useState&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SidebarMode&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;('expanded');
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&lt;/span&gt; &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onStateChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&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;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For common actions, Shell provides a trigger component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Trigger&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"sidebar"&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"toggle"&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;MenuIcon&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Trigger&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And a hook for programmatic control:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shell&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useShell&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;togglePane&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sidebar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expandPane&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inspector&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collapsePane&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bottom&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;h2&gt;
  
  
  Resize System
&lt;/h2&gt;

&lt;p&gt;Resizable panels are table stakes for professional apps. But the details matter.&lt;/p&gt;

&lt;p&gt;Shell's resize system includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Drag handles with proper cursor feedback&lt;/li&gt;
&lt;li&gt;Keyboard navigation (arrow keys adjust size)&lt;/li&gt;
&lt;li&gt;Snap points (drag near 300px and it snaps to exactly 300px)&lt;/li&gt;
&lt;li&gt;Collapse threshold (drag below minimum and it auto-collapses)&lt;/li&gt;
&lt;li&gt;Size persistence (remember size across sessions via localStorage)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&lt;/span&gt;
  &lt;span class="na"&gt;resizable&lt;/span&gt;
  &lt;span class="na"&gt;minSize&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;maxSize&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;snapPoints&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;250&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;350&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;snapTolerance&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;collapseThreshold&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paneId&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"main-sidebar"&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you provide &lt;code&gt;paneId&lt;/code&gt;, Shell automatically creates a localStorage adapter for persistence. Sizes survive page refreshes without any additional code. If you need custom storage (database, state management), pass a &lt;code&gt;persistence&lt;/code&gt; adapter with &lt;code&gt;load&lt;/code&gt; and &lt;code&gt;save&lt;/code&gt; methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Inset Pattern
&lt;/h2&gt;

&lt;p&gt;Modern apps often use floating panels—sidebars with rounded corners and shadows that sit above a gray backdrop. Slack, Linear, and others use this pattern.&lt;/p&gt;

&lt;p&gt;Shell supports it with a single prop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&lt;/span&gt; &lt;span class="na"&gt;inset&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="nt"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Floating navigation&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;nav&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When any pane has &lt;code&gt;inset&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Shell's body gets a gray backdrop&lt;/li&gt;
&lt;li&gt;The pane gets margin (creating gaps from edges)&lt;/li&gt;
&lt;li&gt;The pane gets rounded corners&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;code&gt;inset&lt;/code&gt; prop handles positioning. For visual treatment (background, shadow), use the child component's styling. This separation keeps concerns clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;The hard part of Shell wasn't writing code. It was deciding the API surface.&lt;/p&gt;

&lt;p&gt;Every prop is a decision. Do I expose this? Do I make it the default? Do I let users override it? Each decision has downstream consequences.&lt;/p&gt;

&lt;p&gt;Some things I learned:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Defaults matter more than options.&lt;/strong&gt; Most users won't configure anything. The defaults need to be sensible. Sidebar defaults to overlay on mobile, fixed on desktop. That's right for 80% of cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constraints enable creativity.&lt;/strong&gt; By enforcing composition rules, Shell prevents invalid states. Users don't have to think about what happens if Sidebar and Panel are both open. They can't be.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Responsive behavior should be colocated.&lt;/strong&gt; Putting &lt;code&gt;presentation={{ initial: 'overlay', md: 'fixed' }}&lt;/code&gt; on the component is better than scattering media queries across CSS files. The component documents its own behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;State callbacks need metadata.&lt;/strong&gt; When &lt;code&gt;onStateChange&lt;/code&gt; fires, you need to know &lt;em&gt;why&lt;/em&gt;. Was it a user toggle? A responsive breakpoint change? An initialization? Shell passes a &lt;code&gt;meta&lt;/code&gt; object with the reason: &lt;code&gt;init&lt;/code&gt;, &lt;code&gt;toggle&lt;/code&gt;, or &lt;code&gt;responsive&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where It's Used
&lt;/h2&gt;

&lt;p&gt;Shell powers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kookie Blocks documentation site&lt;/li&gt;
&lt;li&gt;Kookie AI (the chat interface I'm building)&lt;/li&gt;
&lt;li&gt;My personal site&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's new. I'm still finding edge cases, still refining the API. But it's in production across these projects, handling real usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shell + Sidebar
&lt;/h2&gt;

&lt;p&gt;Shell handles layout—where things go, how they resize, how they respond to breakpoints. But it doesn't handle what goes &lt;em&gt;inside&lt;/em&gt; the layout slots.&lt;/p&gt;

&lt;p&gt;That's where &lt;a href="https://www.hellokookie.com/docs/sidebar" rel="noopener noreferrer"&gt;Sidebar&lt;/a&gt; comes in. It's a separate presentational component for building navigation menus: groups, menu items, sub-menus, badges, keyboard shortcuts. It adapts between expanded (full panel) and thin (icon rail) presentations.&lt;/p&gt;

&lt;p&gt;They're designed to work together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Root&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&lt;/span&gt;
    &lt;span class="na"&gt;presentation&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;initial&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;overlay&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fixed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;defaultState&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;initial&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;collapsed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expanded&lt;/span&gt;&lt;span class="dl"&gt;'&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;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Root&lt;/span&gt; &lt;span class="na"&gt;presentation&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;sidebarMode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;thin&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;thin&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;expanded&lt;/span&gt;&lt;span class="dl"&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;Sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Header&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;Logo&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;Sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Header&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;Sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&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;Sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Menu&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;Sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MenuItem&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;Sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MenuButton&lt;/span&gt; &lt;span class="na"&gt;isActive&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;HomeIcon&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
              Dashboard
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MenuButton&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;Sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MenuItem&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;Sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Menu&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;Sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&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;Sidebar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Root&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&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="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Your app&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;main&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Content&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;Shell&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Root&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Shell.Sidebar manages layout state (open/closed/thin, responsive behavior, resize). Sidebar manages navigation presentation (menus, groups, active states, sub-menus).&lt;/p&gt;

&lt;p&gt;Two components, clear responsibilities, composable.&lt;/p&gt;

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

&lt;p&gt;Shell + Sidebar cover layout and navigation. I'm working on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CommandBar&lt;/strong&gt; — Command palette that integrates with Shell's state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NavMenu&lt;/strong&gt; — Horizontal navigation for headers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is a complete toolkit for building application interfaces. Shell is the foundation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;Every application needs layout chrome. Sidebars, panels, headers, resize handles, responsive behavior—it's infrastructure that has nothing to do with what makes your product unique. Shell encodes this pattern in KookieUI so teams get tested, accessible, composable layout primitives.&lt;/p&gt;

&lt;p&gt;Teams can focus on what goes inside the boxes instead of building the boxes themselves. That's the value Shell brings to KookieUI.&lt;/p&gt;

</description>
      <category>designsystems</category>
      <category>components</category>
      <category>layout</category>
      <category>shell</category>
    </item>
    <item>
      <title>Why Designers Should Own the Experience in Production</title>
      <dc:creator>Kushagra Dhawan</dc:creator>
      <pubDate>Mon, 16 Feb 2026 09:25:26 +0000</pubDate>
      <link>https://dev.to/kushagradhawan/why-designers-should-own-the-experience-in-production-2lao</link>
      <guid>https://dev.to/kushagradhawan/why-designers-should-own-the-experience-in-production-2lao</guid>
      <description>&lt;p&gt;I think it's time designers start owning their design in code, which is to say, owning the experience in production. I'm not saying it because I want designers to do more than what they already do, but because the end user doesn't get to use their designs as-is. What users feel and interact with is the implementation of their design, which is not entirely in their control - deadlines, speed, lack of focus on details - often ends up compromising exactly what is needed for design to feel good. Users never see the Figma file. They feel the implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I took this on for Womp
&lt;/h2&gt;

&lt;p&gt;As part of my work with Womp, I own the design layer in production. Womp is a startup without a dedicated design engineer. I sit across design, product, and code, so I took responsibility for the design layer in production. UI work does not sit in a frontend queue. The team can change the interface quickly and keep it consistent across releases.&lt;/p&gt;

&lt;p&gt;I created KookieUI to fit the way the product gets built. The frontend imports components like Button from KookieUI, while I define their appearance, tokens, and behavior. When anything needs an update, I adjust KookieUI and publish a new version. The frontend team then updates the package, and the app adopts the new standard automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  What KookieUI is
&lt;/h2&gt;

&lt;p&gt;KookieUI is the design system I built for Womp. It is large and growing. It lives next to product code and stays separate from application logic. It holds tokens, primitives, and patterns the team uses every day. It also carries best practices, accessible components, and the small engineering choices that make interactions feel clean.&lt;/p&gt;

&lt;p&gt;KookieUI is a fork of Radix UI and it is open source. Radix gives a strong baseline. I add what the product needs. The focus is on contrast, focus states, motion, density, theming hooks, keyboard paths, and predictable behavior across states.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where effort goes now
&lt;/h2&gt;

&lt;p&gt;I started by strengthening primitives like buttons, inputs, dialogs, menus, tooltips. Reliable building blocks let the team move faster everywhere else. Now I want to invest in pattern components that carry real but less glamorous work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App Shell for complex editor and creation flows&lt;/li&gt;
&lt;li&gt;StackNav for deep, panel based navigation&lt;/li&gt;
&lt;li&gt;Contracts and slots that let simple pieces work in richer contexts, for example adding an optional toolbar slot to Popover so tool groups feel integrated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Patterns reduce decision load and make changes flow through the product. They also let the team run smaller experiments because the base holds steady.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why design belongs in production
&lt;/h2&gt;

&lt;p&gt;If you ask someone uninterested in design to handle design, the result is not ideal. Do not do it. The person shaping the experience should also shape the code that delivers it.&lt;/p&gt;

&lt;p&gt;Traditional handoffs solve the same problem twice. Design in Figma, cover edge cases, pass to engineering, cover code edge cases, ship, feedback, loop. When the design layer lives in code, you solve it once where the user feels it. You still review. You still test. The work sits in the right place.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the layers work in practice
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Design layer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tokens for color, spacing, type, radius, and motion.&lt;/li&gt;
&lt;li&gt;Primitives and patterns like Button, Input, Dialog, Tabs, Chatbar, App Shell, StackNav.&lt;/li&gt;
&lt;li&gt;Interaction rules for states, keyboard paths, and focus.&lt;/li&gt;
&lt;li&gt;Accessibility checks and visual checks.&lt;/li&gt;
&lt;li&gt;Docs that sit next to the parts and explain intent, not just props.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Application layer
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Data, state, routing, permissions, and errors.&lt;/li&gt;
&lt;li&gt;Business logic, security, and platform concerns.&lt;/li&gt;
&lt;li&gt;Feature flags and tracking.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How the work actually ships
&lt;/h2&gt;

&lt;p&gt;The ideal is to add new UI patterns to KookieUI first, then use them in the app. Reality is simpler. Whoever is unblocked does it. If I am deep in product work, the feature team can build the UI inside the application layer to keep moving. Later, that work gets pulled up into KookieUI as a pattern, given proper contracts, tests and docs, and the local version gets replaced. This keeps velocity high while still growing the system.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed day to day
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;UI work moves without getting stuck.&lt;/li&gt;
&lt;li&gt;Screens behave the same across the product.&lt;/li&gt;
&lt;li&gt;The team has best practices, accessible components, and well engineered parts to rely on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When shipping fast, teams often skip the details that lift an experience from a nine to a ten. Now that work happens inside KookieUI, in isolation, while engineering focuses on application logic. Both tracks move.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the system stays healthy
&lt;/h2&gt;

&lt;p&gt;Intent is written down in the docs next to the code. APIs stay clear and narrow. One-off styling in features is avoided. Keyboard paths and focus rules stay visible. Examples match real screens, not toy cases. When a component grows too many concerns, it gets split. When a token change is risky, it gets staged and rolled in steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you want to try this
&lt;/h2&gt;

&lt;p&gt;If you can teach designers to use code, do it. If that is not possible yet, at least separate the design layer from the application layer.&lt;/p&gt;

&lt;p&gt;Building quality components is an orthogonal task to building features. Teams rarely estimate time for it in a feature sprint, so it gets missed. Shipping a well engineered component is not easy and it should not compete with a feature deadline.&lt;/p&gt;

&lt;p&gt;Start with a primitive or headless library. If your design team is advanced, or you have UI engineers, build a separate component layer and treat it as your design system. Keep it in the repo. Give it owners. Pull patterns up from features when you have breathing room.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;Design that feels good is design that survives the trip to production. Owning the design layer in code gives it that chance. KookieUI is how I do this for Womp. It helps the team move faster and gives time to raise the quality where people notice it.&lt;/p&gt;

</description>
      <category>designsystems</category>
      <category>designengineering</category>
      <category>product</category>
      <category>kookieui</category>
    </item>
  </channel>
</rss>
