<script data-pm-proxy="intercept"></script><?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Nathan Curtis]]></title><description><![CDATA[Nathan Curtis]]></description><link>https://nathanacurtis.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!Hj04!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fnathanacurtis.substack.com%2Fimg%2Fsubstack.png</url><title>Nathan Curtis</title><link>https://nathanacurtis.substack.com</link></image><generator>Substack</generator><lastBuildDate>Fri, 04 Sep 2026 18:24:57 GMT</lastBuildDate><atom:link href="/__u/nathanacurtis.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Nathan Curtis]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[nathanacurtis@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[nathanacurtis@substack.com]]></itunes:email><itunes:name><![CDATA[Nathan Curtis]]></itunes:name></itunes:owner><itunes:author><![CDATA[Nathan Curtis]]></itunes:author><googleplay:owner><![CDATA[nathanacurtis@substack.com]]></googleplay:owner><googleplay:email><![CDATA[nathanacurtis@substack.com]]></googleplay:email><googleplay:author><![CDATA[Nathan Curtis]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[What Component Specs Leave Behind]]></title><description><![CDATA[Test what your contract drops, distorts and invents using looping round trips]]></description><link>https://nathanacurtis.substack.com/p/what-component-specs-leave-behind</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/what-component-specs-leave-behind</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Thu, 27 Aug 2026 12:55:55 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!4ro7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfe3fe4b-d29e-4ef3-8fae-fc82abf1a375_2800x1575.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!4ro7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfe3fe4b-d29e-4ef3-8fae-fc82abf1a375_2800x1575.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!4ro7!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfe3fe4b-d29e-4ef3-8fae-fc82abf1a375_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!4ro7!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfe3fe4b-d29e-4ef3-8fae-fc82abf1a375_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!4ro7!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfe3fe4b-d29e-4ef3-8fae-fc82abf1a375_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!4ro7!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfe3fe4b-d29e-4ef3-8fae-fc82abf1a375_2800x1575.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!4ro7!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfe3fe4b-d29e-4ef3-8fae-fc82abf1a375_2800x1575.png" width="1200" height="675" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bfe3fe4b-d29e-4ef3-8fae-fc82abf1a375_2800x1575.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:731929,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/211177514?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfe3fe4b-d29e-4ef3-8fae-fc82abf1a375_2800x1575.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!4ro7!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfe3fe4b-d29e-4ef3-8fae-fc82abf1a375_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!4ro7!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfe3fe4b-d29e-4ef3-8fae-fc82abf1a375_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!4ro7!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfe3fe4b-d29e-4ef3-8fae-fc82abf1a375_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!4ro7!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbfe3fe4b-d29e-4ef3-8fae-fc82abf1a375_2800x1575.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Spock stood still on the transporter pad, waiting. And then &#8230; ENERGIZE! He transforms into glittery streams of light, disappears, and is away somewhere doing good. Some time later, he reappears through that same swirling energy. His shirt&#8217;s still blue, his ears pointy, his hair still a stark, bowled edge. Spock&#8217;s back, right? Mission complete!</p><p>No systems expert would rate that sufficient evidence of a successful transport. Glancing at shirt color, ears shape and hair style isn&#8217;t &#8220;good enough.&#8221; You want Spock: half-human, half-Vulcan, hyper-calculating, mindmeld-capable and yet humanly empathetic. We love Spock for all his complicated powers and nuance.</p><p>What I see today is designers shipping kind-of-Vulcans and expecting agents and engineering teammates to make that more &#8220;Spock-like.&#8221; Contracts carry color, fold in shape, and itemize styles. They add prop tables and variant axes. Cue amazed reactions from consumers of your markdown and json? At least designers aren&#8217;t shipping <a href="https://en.wikipedia.org/wiki/Redshirt_(stock_character)">red shirts</a>, right?</p><p>Contracts should carry design intent as exhaustively as needed. One way to test is a looping &#8220;round trip:&#8221; beam away, beam back, and evaluate the difference. This will expose whether a contract carries a kind-of-Vulcan or actually Spock.</p><p>I experienced a nearly-but-not-Spock humbling by accident. Round-trip testing a new feature revealed that my specs transformation and model was incomplete and lossy. Looping revealed defects, model gaps, and a lack of clarity around what the contract can&#8217;t, doesn&#8217;t, and doesn&#8217;t yet carry. This blog post describes the journey through a contract&#8217;s loss and depth and how round trips exposed how to make it better.</p><h1>Loss</h1><p>In a spec-driven UI component workflow, we strive for <strong>lossless</strong> transformation: converting data from one structure into another without losing, altering or inventing a single bit of information. Loss accumulates in the conversion from Figma asset to spec data, and then compounds as agents and engineers make interpretations and inferences on an incomplete picture .</p><p>When translating from Figma to spec, loss can take many forms:</p><ul><li><p>Emitting a hex code when a color token is bound.</p></li><li><p>Missing a layer&#8217;s <code>maxWidth</code> applied to only the last of many options.</p></li><li><p>Omitting a change in <code>backgroundColor</code> or layer presence when properties interact, such as <code>selected:true</code> <em>and</em> <code>state:hover</code> simultaneously occur.</p></li></ul><p>Loss can occur when intent gets more complicated:</p><ul><li><p>Representing an <code>Alert</code>&#8217;s decorative icon as customizable when it shouldn&#8217;t be in an <code>error</code> variant or not customizable when it should be in a <code>neutral</code> variant.</p></li><li><p>Missing how a <code>Pill</code>'s horizontal <code>padding</code> varies across <code>size</code>s depending on if content is composable in a slot or includes just a built-in label.</p></li><li><p>Errantly consolidating a Figma <code>BOOLEAN</code> and <code>SLOT</code> prop into a single <code>nullable</code> slot property when the layer is only bound as a <code>SLOT</code> in some but not all variants.</p></li></ul><p>These complicated examples are like Spock&#8217;s capabilities for logic, Vulcan pinch and mindmeld. These losses are worse: dropping or inventing complicated, powerful intent <em>and</em> easiest to miss when reviewing an asset visually. Nobody noticed because the contract had no place for it.</p><h1>Depth</h1><p>Contracts can carry a little or contracts can carry a lot. It&#8217;s simple to devise a format (in markdown and/or json) and an agentic skill to extract colors, spacing, corner radius, width and height across a tree of named layers. Another iteration, and a contract may also emit detected changes across each variant axis and generate a props table. A simple contract is easy to evaluate and unlikely to lose much. But it&#8217;s not carrying much, either.</p><p>Shallow contracts don&#8217;t work when UI components are intricate. </p><p>Design system teams express far more intent, authored at far finer grain in Figma assets. Variants subtly shift styling across interdependent props. Cases vary tokens and prop bindings, rules and intents. </p><p>The focus on contract depth is evident in the very first setting I implemented in the latest Specs generation: <a href="https://www.specsplugin.com/guides/variant-depth/">variant depth</a>. Many publicized contract tools evaluate a Figma component set&#8217;s variant axes, comparing how design changes across enumerated options.  That&#8217;s <code>variantDepth:1</code>. The Specs Classic (first generation) tool offered a &#8220;Two way&#8221; feature that evaluated difference of every combination of two properties, such as <code>selected:true|false</code> and <code>state:rest|hover|pressed</code>. That&#8217;s <code>variantDepth:2</code>. </p><p>Most tools and demos I see go no more than two levels deep. Why stop there? Designers express intent in any variant, and contracts promise exhaustiveness, right? I run Specs on <code>variantDepth:9999</code> every time: no variant, layer, styling, or binding is ever missed.</p><p>Plus, depth isn&#8217;t just about variants. Subcomponents, nested instances, slots, content and props all interact in fantastic ways. Implicit naming is used to express explicit concepts. Layouts makes layers shift, appear and disappear, show and hide. Phew, I&#8217;m out of breath, and that&#8217;s not all of it! Design intent can gets deep and complicated across these concerns.</p><p>The reward for expressing more intent is that you have more to lose. A shallow contract round-trips perfectly: carry eight properties, render eight, empty diff. That&#8217;s flawless yet entirely misleading losslessness, because so much wasn&#8217;t carried in the first place. The trap is thinking shallow contracts are good. What matters for a strong contract is both <strong>how much the contract carries </strong>and<strong> how much survives the trip</strong>.</p><h1>The round trip</h1><p>So how would you rate depth and losslessness? Reading a schema tells you what it meant to model. It doesn&#8217;t tell what the contract actually carried. The best way to find out what a contract holds is to make it give the component back.</p><h2>Starting in reverse</h2><p>I recently built a <code>render</code> command in my Specs ecosystem, which takes a spec and renders it as a component asset in Figma via a script. It takes a few seconds per component. Why? Design system intent is originating outside of Figma. If a design system is supports building and expressing designs in both Figma and prototype, then the system must be able to move the expression between them cleanly. Therefore, the <code>render</code> command bring a spec&#8217;ed expression back into a Figma library.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!y5iZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04dd65f8-1484-4274-b0af-afb502c7610f_2400x620.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!y5iZ!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04dd65f8-1484-4274-b0af-afb502c7610f_2400x620.png 424w, /__u/substackcdn.com/image/fetch/$s_!y5iZ!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04dd65f8-1484-4274-b0af-afb502c7610f_2400x620.png 848w, /__u/substackcdn.com/image/fetch/$s_!y5iZ!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04dd65f8-1484-4274-b0af-afb502c7610f_2400x620.png 1272w, /__u/substackcdn.com/image/fetch/$s_!y5iZ!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04dd65f8-1484-4274-b0af-afb502c7610f_2400x620.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!y5iZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04dd65f8-1484-4274-b0af-afb502c7610f_2400x620.png" width="1456" height="376" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/04dd65f8-1484-4274-b0af-afb502c7610f_2400x620.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:376,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:84074,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/211177514?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04dd65f8-1484-4274-b0af-afb502c7610f_2400x620.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!y5iZ!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04dd65f8-1484-4274-b0af-afb502c7610f_2400x620.png 424w, /__u/substackcdn.com/image/fetch/$s_!y5iZ!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04dd65f8-1484-4274-b0af-afb502c7610f_2400x620.png 848w, /__u/substackcdn.com/image/fetch/$s_!y5iZ!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04dd65f8-1484-4274-b0af-afb502c7610f_2400x620.png 1272w, /__u/substackcdn.com/image/fetch/$s_!y5iZ!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F04dd65f8-1484-4274-b0af-afb502c7610f_2400x620.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A <code>render</code> command transforms specs into a Figma asset via a script without AI</figcaption></figure></div><p>The challenge is that the schema model underlying specs is incredibly rich: components, anatomy, props, styling, bindings, variants, slots and recursive nested composition, code only props and more. Generating a Figma asset could be agentically done, but it&#8217;d likely be lossy and error prone. Writing a deterministic <code>render</code> script instead was possible if bloody complicated.</p><h2>The loop</h2><p>As <code>render</code> development progressed and most features were implemented, I found inspiration in <a href="/__u/substack.com/home/post/p-211112800">Addy Osmani&#8217;s writings like Loop Engineering</a>. As a result, I began to loop between <code>generate</code>d specs and <code>render</code>ed Figma assets to refine and polish the <code>render</code>'s implemented features. The goal is to remove as much loss at depth as possible, proving that <code>render</code> has reached parity with <code>generate</code> in the opposite direction.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!cEVP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7a5bc47-0fb9-486c-88b1-ef2fb2bc6bd9_2400x1220.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!cEVP!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7a5bc47-0fb9-486c-88b1-ef2fb2bc6bd9_2400x1220.png 424w, /__u/substackcdn.com/image/fetch/$s_!cEVP!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7a5bc47-0fb9-486c-88b1-ef2fb2bc6bd9_2400x1220.png 848w, /__u/substackcdn.com/image/fetch/$s_!cEVP!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7a5bc47-0fb9-486c-88b1-ef2fb2bc6bd9_2400x1220.png 1272w, /__u/substackcdn.com/image/fetch/$s_!cEVP!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7a5bc47-0fb9-486c-88b1-ef2fb2bc6bd9_2400x1220.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!cEVP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7a5bc47-0fb9-486c-88b1-ef2fb2bc6bd9_2400x1220.png" width="1456" height="740" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e7a5bc47-0fb9-486c-88b1-ef2fb2bc6bd9_2400x1220.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:740,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:132862,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/211177514?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7a5bc47-0fb9-486c-88b1-ef2fb2bc6bd9_2400x1220.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!cEVP!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7a5bc47-0fb9-486c-88b1-ef2fb2bc6bd9_2400x1220.png 424w, /__u/substackcdn.com/image/fetch/$s_!cEVP!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7a5bc47-0fb9-486c-88b1-ef2fb2bc6bd9_2400x1220.png 848w, /__u/substackcdn.com/image/fetch/$s_!cEVP!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7a5bc47-0fb9-486c-88b1-ef2fb2bc6bd9_2400x1220.png 1272w, /__u/substackcdn.com/image/fetch/$s_!cEVP!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7a5bc47-0fb9-486c-88b1-ef2fb2bc6bd9_2400x1220.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>An agent would run each round, using an orchestrating script to set the harness for one component or entire catalog. The harness uses a <code>bridge</code> to connect Figma through a plugin to the LLM chat and cached library data (variables, icons, assets). The loop takes these steps:</p><ol><li><p><code>generate</code> a baseline spec from an existing Figma component</p></li><li><p><code>render</code> a test Figma component from a baseline spec</p></li><li><p><code>generate</code> a test spec from the test Figma component</p></li><li><p><code>diff</code> the baseline and test specs</p></li><li><p>Create a <code>report</code> of what&#8217;s change (once for an entire library)</p></li><li><p><code>delete</code> the test Figma component</p></li></ol><p>Anything the pipeline loses, mangles, or invents shows up concretely rather than a hunch. The report skill validates diff counts and variant shapes and separates signals of unimplemented features from defects and regressions. Data in hand, the skill then groups symptoms into themes with root causes and create prioritized Github issues that I smash immediately or save for later. Let the loop-by-loop-burn-down commence! </p><p>The first loop against an entire library was loud: many big themes, each requiring an investment to parse, plan and smooth the <code>render</code> engine. Over many loops, differences diminished to residue that I could precisely inspect, refine the code, and loop more narrowly. As themes and defects quieted down, I gained confidence as less and less data was being lost. Eventually, the <code>render</code> command converged on feature parity with <code>generate</code> command.</p><p>Whether or not you build a <code>render</code> script, the broader takeaway is to use round trips and loops to test your contract. Agents and skills can beam back and compare to what agents beamed out. Even if it&#8217;s not deterministic, you can still find ways to distinguish carried intent from loss and lacking depth. </p><p>Yet, the loop yielded something more valuable than getting <code>render</code> done.</p><h1>The Reckoning</h1><p>I began my <code>render</code> work more than confident that the Figma-to-Specs <code>generate</code> transform and underlying schema was complete and stable. Yet, each loop exposed pipeline weaknesses. <code>generate</code> was dropping details silently. The schema lacked shape to express details. The contract wasn&#8217;t capturing intent I didn&#8217;t realize I valued. Mind you, my confidence in <code>generate</code> + <code>schema</code>'s viability wasn&#8217;t shaken. But the tools were neither perfect nor reaching their potential.</p><div class="pullquote"><p>A round trip is a brutal test of a contract.</p></div><p>Turns out, a<strong> </strong>round trip is a <strong>brutal test of a contract</strong>. Anything a transform and schema can&#8217;t capture gets dropped beaming out, and anything a spec captures too loosely risks loss and differences beaming back. </p><p>So, converging a round trip&#8217;s baseline and test differences to zero wasn&#8217;t actually the right goal. The diff doesn&#8217;t converge to nothing. Instead, it converges on sets I can name: reaffirmed assumptions, defects to fix, and what the contract can&#8217;t, won&#8217;t, or doesn&#8217;t yet carry that I can clearly communicate.</p><h2>Expose assumptions</h2><p>As I&#8217;ve built Specs, there are choices about data that I knew and others I sensed. Making the round trip made them explicit and visible, such as:</p><ul><li><p>Alphabetical order is not neutral; instead, it destroys authored order.</p></li><li><p>Booleans must be booleans everywhere, if that&#8217;s how you want to treat them. Even <code>VARIANT</code> prop options that are <code>true</code> or <code>True</code>, <code>false</code> or <code>False</code>.</p></li><li><p>Visibility is not existence; instead, hidden layers must be respected exhaustively.</p></li></ul><p>If not recognized and handled correctly, transformations break. Speaking of which&#8230;</p><h2>Fix the transformation</h2><p>Lots of small defect emerged over time, implemented feature by implemented feature:</p><ul><li><p><strong>Broken styling</strong>: <code>clipsContent</code> &#8211; very rarely used and lacking unit tests and text fixtures &#8211; sneakily never worked defined as <code>clipContent</code>. Not just a transformer fix, but an <a href="https://www.specsplugin.com/adr/069-clips-content/">ADR</a> because it changed the model&#8217;s mistake. Sigh. Details.</p></li><li><p><strong>Warnings where there had been silence</strong>: unresolved slot constraint keys, an ignored binding, an unbindable property. Knowing when and how much processing trips up enables smoothing more rough edges.</p></li><li><p><strong><a href="/__u/substack.com/home/post/p-199324016">Examples</a> lacked top-level rules</strong>: content in slots wasn&#8217;t evaluating the relationship with the slot layer parent. As a result, data suggested content with a fixed width, when instead it was filling horizontally.</p></li></ul><p>Such small defects go unnoticed to those reviewing visual test cases. Even visual regression snapshot tests would have missed the last Examples issue. Yet round trip transformations and differencing of data caught so much more.</p><p>Other defects rest in the backlog, with an unclear priority awaiting when they&#8217;ll actually negatively impact transmission. Authors in Figma shouldn&#8217;t be naming a code-only prop as the same name as a native prop. Detecting that <em>should</em> be some other tool&#8217;s job even if a Specs warning might be nice.</p><h2>Expand the schema</h2><p>The model does a great job carrying intent, but surprisingly tripped over basic identities. Naming is hard. </p><p>Converting Figma labels to camelCase or snake_case (a long supported, high-demand feature) is lossy, dropping characters and capitalization on round trips. Therefore, it became essential to add a <a href="https://www.specsplugin.com/adr/066-lossless-key-formatting/">safe key grammar to carry names losslessly and preserve Figma names</a> when needed. Establishing a <code>figmaKey:NONE|SENTENCE|TITLE</code> convention to declare how designers are naming in Figma came along for the ride.</p><h2>What can&#8217;t be supported</h2><p>Unfortunately, the round trip also made clear intent that Specs can&#8217;t support, like:</p><ul><li><p><strong>Customized prop order</strong> in Figma&#8217;s Props panel. You <em>can</em> derive <code>VARIANT</code> prop order from component layer names. However, Figma&#8217;s plugin API doesn&#8217;t carry the order of remaining <code>BOOLEAN</code>, <code>INSTANCE_SWAP</code>, <code>TEXT</code>, and <code>SLOT</code> props.</p></li><li><p><strong>Locking aspect ratio</strong> means that bound variables for <em>both</em> <code>width</code> and <code>height</code> can&#8217;t both be carried even if both remain bound &#8220;under the covers&#8221; of Figma&#8217;s UI. </p></li></ul><p>Designers won&#8217;t care about the bound variable-dropping of locked aspect ratio. But I&#8217;ve witnessed more than enough designers fiddling with Figma Props panel property order to know there&#8217;s intent there. Through order, there&#8217;s priority and proximity. Through proximity, there&#8217;s groups and relationships. Those mean something, even if implicit.</p><h2>What isn&#8217;t yet supported</h2><p>Doing the work on the opposite <code>render</code> direction reaffirmed the boundary of how much Figma expression is carried through Specs. I don&#8217;t prematurely optimize to cover all cases, and demand suggests how the model and transformations grow.</p><p>As a result, I continue to <em>not yet</em> support Figma features like Grid autolayout, esoteric line end point styles, and stacks of stroke and fill colors. Designers aren&#8217;t yet using them in work I support (although Liquid Glass seems to have something to say about that; stay tuned!).</p><h2>What won&#8217;t be supported</h2><p>This exercise also reinforced the higher cost that outweighs any current benefit of building around Figma&#8217;s new motion capabilities. Figma&#8217;s motion data model is necessarily very complicated: <em>pages and pages</em> of docs and many nested levels of data depth, making typography and effects look elementary.</p><p>Motion is a whole separate language, few in our field know it well, nobody I know is yet expressing it in Figma, and it&#8217;d be enormously expensive for me to build a whole ecosystem around it. Maybe that day will come. But I&#8217;m not planning on it, and I&#8217;m overt about it to curious customers.</p><div><hr></div><p>So, if you beamed your component back, what wouldn&#8217;t it return? Most don&#8217;t know, having focused on only the good and obvious stuff they&#8217;d beamed out. So take a round trip. Or two. Or some series of loops until you settle where you need to. Look for what you are missing, and how much you value it. Your diffs probably won&#8217;t converge on empty either. But you&#8217;ll be able to name the gaps and provide the polish elsewhere to ensure the components you make are the best they can be.</p><p></p>]]></content:encoded></item><item><title><![CDATA[Spec-Driven UI Component Development]]></title><description><![CDATA[Deliver design intent from multiple origins across design, code and doc libraries]]></description><link>https://nathanacurtis.substack.com/p/spec-driven-ui-component-development</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/spec-driven-ui-component-development</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Fri, 14 Aug 2026 16:40:59 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!6ip2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc808fcc9-d9f6-4812-bb8e-058848a33a64_2800x1575.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!6ip2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc808fcc9-d9f6-4812-bb8e-058848a33a64_2800x1575.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!6ip2!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc808fcc9-d9f6-4812-bb8e-058848a33a64_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!6ip2!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc808fcc9-d9f6-4812-bb8e-058848a33a64_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!6ip2!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc808fcc9-d9f6-4812-bb8e-058848a33a64_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!6ip2!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc808fcc9-d9f6-4812-bb8e-058848a33a64_2800x1575.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!6ip2!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc808fcc9-d9f6-4812-bb8e-058848a33a64_2800x1575.png" width="1200" height="675" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c808fcc9-d9f6-4812-bb8e-058848a33a64_2800x1575.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:106691,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/210787579?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc808fcc9-d9f6-4812-bb8e-058848a33a64_2800x1575.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!6ip2!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc808fcc9-d9f6-4812-bb8e-058848a33a64_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!6ip2!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc808fcc9-d9f6-4812-bb8e-058848a33a64_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!6ip2!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc808fcc9-d9f6-4812-bb8e-058848a33a64_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!6ip2!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc808fcc9-d9f6-4812-bb8e-058848a33a64_2800x1575.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>People encounter my specs tooling often first through the Specs Figma plugin that&#8217;s been around for years. They see it as a designer-to-engineer handoff helper. That&#8217;s understandable, since the plugin&#8217;s origin was &#8220;Select a component, automate production of a specifications document on Figma&#8217;s canvas.&#8221;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!NO6I!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdd65b63-8374-4273-b8ae-8c74e11798fd_2000x1017.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!NO6I!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdd65b63-8374-4273-b8ae-8c74e11798fd_2000x1017.png 424w, /__u/substackcdn.com/image/fetch/$s_!NO6I!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdd65b63-8374-4273-b8ae-8c74e11798fd_2000x1017.png 848w, /__u/substackcdn.com/image/fetch/$s_!NO6I!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdd65b63-8374-4273-b8ae-8c74e11798fd_2000x1017.png 1272w, /__u/substackcdn.com/image/fetch/$s_!NO6I!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdd65b63-8374-4273-b8ae-8c74e11798fd_2000x1017.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!NO6I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdd65b63-8374-4273-b8ae-8c74e11798fd_2000x1017.png" width="1456" height="740" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fdd65b63-8374-4273-b8ae-8c74e11798fd_2000x1017.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:740,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:234041,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/210787579?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdd65b63-8374-4273-b8ae-8c74e11798fd_2000x1017.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!NO6I!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdd65b63-8374-4273-b8ae-8c74e11798fd_2000x1017.png 424w, /__u/substackcdn.com/image/fetch/$s_!NO6I!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdd65b63-8374-4273-b8ae-8c74e11798fd_2000x1017.png 848w, /__u/substackcdn.com/image/fetch/$s_!NO6I!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdd65b63-8374-4273-b8ae-8c74e11798fd_2000x1017.png 1272w, /__u/substackcdn.com/image/fetch/$s_!NO6I!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffdd65b63-8374-4273-b8ae-8c74e11798fd_2000x1017.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Specs 2 Figma Plugin output generated on canvas from a Figma asset</figcaption></figure></div><p>As AI emerged over 2024 and 2025, it became clear that agents and tools value the underlying data emitted in a structured, predictable schema. So I evolved the specs tooling to generate specs both via the Plugin API and Rest API interfaces, per component at for an entire library.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Woog!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f3851b-b3c0-46e7-b5ce-0bdc6aa451a3_1722x504.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Woog!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f3851b-b3c0-46e7-b5ce-0bdc6aa451a3_1722x504.png 424w, /__u/substackcdn.com/image/fetch/$s_!Woog!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f3851b-b3c0-46e7-b5ce-0bdc6aa451a3_1722x504.png 848w, /__u/substackcdn.com/image/fetch/$s_!Woog!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f3851b-b3c0-46e7-b5ce-0bdc6aa451a3_1722x504.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Woog!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f3851b-b3c0-46e7-b5ce-0bdc6aa451a3_1722x504.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Woog!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f3851b-b3c0-46e7-b5ce-0bdc6aa451a3_1722x504.png" width="1456" height="426" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/55f3851b-b3c0-46e7-b5ce-0bdc6aa451a3_1722x504.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:426,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:52202,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/210787579?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f3851b-b3c0-46e7-b5ce-0bdc6aa451a3_1722x504.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Woog!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f3851b-b3c0-46e7-b5ce-0bdc6aa451a3_1722x504.png 424w, /__u/substackcdn.com/image/fetch/$s_!Woog!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f3851b-b3c0-46e7-b5ce-0bdc6aa451a3_1722x504.png 848w, /__u/substackcdn.com/image/fetch/$s_!Woog!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f3851b-b3c0-46e7-b5ce-0bdc6aa451a3_1722x504.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Woog!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55f3851b-b3c0-46e7-b5ce-0bdc6aa451a3_1722x504.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Specs data generation from Figma into structured data</figcaption></figure></div><p>Yet, these narrower tools don&#8217;t necessarily convey how specs fits into a larger UI component production environment. </p><p>My work in 2026 builds further towards a single place where a design system records, evolves, projects, and synchronizes expressions of design intent. Specs serve as a hub for expressions across all the surfaces &#8211; Figma, prototypes, code libraries, docs &#8211; each a source of intent and a surface on which to render intent. To many, that probably sounds like THE <em>source</em>-of-truth. Well, kinda. It&#8217;s a place that normalizes, synchronizes, and versions the intent expressed across the many <em>origins</em>-of-truth.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!v2C2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3b7686-e8f2-426c-9e63-585e57edf530_2080x1160.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!v2C2!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3b7686-e8f2-426c-9e63-585e57edf530_2080x1160.png 424w, /__u/substackcdn.com/image/fetch/$s_!v2C2!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3b7686-e8f2-426c-9e63-585e57edf530_2080x1160.png 848w, /__u/substackcdn.com/image/fetch/$s_!v2C2!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3b7686-e8f2-426c-9e63-585e57edf530_2080x1160.png 1272w, /__u/substackcdn.com/image/fetch/$s_!v2C2!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3b7686-e8f2-426c-9e63-585e57edf530_2080x1160.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!v2C2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3b7686-e8f2-426c-9e63-585e57edf530_2080x1160.png" width="1456" height="812" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dd3b7686-e8f2-426c-9e63-585e57edf530_2080x1160.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:812,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:192069,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/210787579?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3b7686-e8f2-426c-9e63-585e57edf530_2080x1160.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!v2C2!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3b7686-e8f2-426c-9e63-585e57edf530_2080x1160.png 424w, /__u/substackcdn.com/image/fetch/$s_!v2C2!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3b7686-e8f2-426c-9e63-585e57edf530_2080x1160.png 848w, /__u/substackcdn.com/image/fetch/$s_!v2C2!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3b7686-e8f2-426c-9e63-585e57edf530_2080x1160.png 1272w, /__u/substackcdn.com/image/fetch/$s_!v2C2!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3b7686-e8f2-426c-9e63-585e57edf530_2080x1160.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Specs as hub of design expression across implemented surfaces</figcaption></figure></div><p>Designers continue with design tools (mostly, Figma and &#8220;prototyping kits&#8221;) and engineers are expanding code factories to produce React, iOS and Android libraries. My current work provides a home for specs and translations across surfaces, building models and tools that contain design intent of components, tokens, icons and more. I make parts of a broader puzzle:&nbsp;tools (a Figma plugin, a command-line interface, agent skills), models (schemas, ADRs), and also still features (components and tokens) that help me grow as an architect. </p><p>I&#8217;ll sometimes blog, post or comment about a part in isolation. What&#8217;s missing is the broader picture, threading these parts with a designer&#8217;s expression in Figma or an engineer&#8217;s code factory. No one person or team owns everything. And we must agree on the edges that connect our parts. And the edges are where it gets hard.</p><p>This post maps the current specs architecture into which many emerging tools fit. I&#8217;ll start with specs: what they contain, how they are authored, and the sophistication we&#8217;ve grown into gradually. I&#8217;ll then expand on how specs connects into multiple design &#8220;origins-of-truth&#8221; (Figma <em>and</em> prototypes) and consuming code factories, with a break to ground the reader in the underlying architecture gluing those edges together.</p><div><hr></div><h1>About Specs</h1><p>Spec serve as the hub of design intent as content to completely describe a component as best as we can. Our specs come in two flavors: <em>generated</em> through deterministic transformation versus <em>authored</em> by humans, agents or both. We favor generated over authored, and build tools that arc specs towards more generated outputs over time.</p><h2>Generated specs</h2><p>My specs focus is on component concerns, each extracted from Figma.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!0jAo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea369af4-79bd-477d-ab18-e2c4b6c82a7d_2000x468.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!0jAo!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea369af4-79bd-477d-ab18-e2c4b6c82a7d_2000x468.png 424w, /__u/substackcdn.com/image/fetch/$s_!0jAo!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea369af4-79bd-477d-ab18-e2c4b6c82a7d_2000x468.png 848w, /__u/substackcdn.com/image/fetch/$s_!0jAo!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea369af4-79bd-477d-ab18-e2c4b6c82a7d_2000x468.png 1272w, /__u/substackcdn.com/image/fetch/$s_!0jAo!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea369af4-79bd-477d-ab18-e2c4b6c82a7d_2000x468.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!0jAo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea369af4-79bd-477d-ab18-e2c4b6c82a7d_2000x468.png" width="1456" height="341" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ea369af4-79bd-477d-ab18-e2c4b6c82a7d_2000x468.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:341,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:37550,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/210787579?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea369af4-79bd-477d-ab18-e2c4b6c82a7d_2000x468.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!0jAo!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea369af4-79bd-477d-ab18-e2c4b6c82a7d_2000x468.png 424w, /__u/substackcdn.com/image/fetch/$s_!0jAo!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea369af4-79bd-477d-ab18-e2c4b6c82a7d_2000x468.png 848w, /__u/substackcdn.com/image/fetch/$s_!0jAo!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea369af4-79bd-477d-ab18-e2c4b6c82a7d_2000x468.png 1272w, /__u/substackcdn.com/image/fetch/$s_!0jAo!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fea369af4-79bd-477d-ab18-e2c4b6c82a7d_2000x468.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Generated per-component specs files</figcaption></figure></div><ol><li><p><strong>API</strong> declares component names, props and elements, serving as the exposed surface to configure and override it.</p></li><li><p><strong>Variants</strong> declare layered rules (much like CSS) that declare the styles, tokens, prop bindings, slots, composition, layout, structure, and more. This data is complicated, rich, and best authored today solely in Figma.</p></li><li><p><strong>Examples</strong> carries composed relationships via nested slots, content, and images leveraged for docs, test cases, and reusable scaffolds.</p></li></ol><p>To learn more, try the <a href="https://www.figma.com/community/plugin/1549454283615386215/specs-2-formerly-anova">Specs 2 Figma plugin</a> and emit &#8220;Data&#8221; or visit the <a href="https://www.specsplugin.com/">Specs site</a> and follow the simple steps to generate specs for your library.</p><h2>Authored specs</h2><p>Figma can&#8217;t express every intent you have for a component. Therefore, it&#8217;s inevitable that generated outputs are paired with authored content to describe what&#8217;s left. Designers I work with don&#8217;t use Figma to express <code>behaviors</code> or <code>accessibility</code>. Additionally, Figma can&#8217;t express advanced <code>layout</code> and <code>configurations</code> like discriminated unions and other prop relationships.</p><p>Therefore, teams augment generated specs with authored <strong>supplemental requirements</strong> also stored in the specifications repo. Supplemental requirements can be general to all components (such as the precedence of <code>disabled</code> over <code>read-only</code>) as well as platform- and component-specific, stored in files like <code>configurations.md</code> or <code>card.accessibility.android.md</code>. Downstream agents and scripts find and filter requirements as needed.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!lThb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e06b7e-1e9b-4b27-aac5-864a64525357_2000x626.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!lThb!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e06b7e-1e9b-4b27-aac5-864a64525357_2000x626.png 424w, /__u/substackcdn.com/image/fetch/$s_!lThb!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e06b7e-1e9b-4b27-aac5-864a64525357_2000x626.png 848w, /__u/substackcdn.com/image/fetch/$s_!lThb!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e06b7e-1e9b-4b27-aac5-864a64525357_2000x626.png 1272w, /__u/substackcdn.com/image/fetch/$s_!lThb!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e06b7e-1e9b-4b27-aac5-864a64525357_2000x626.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!lThb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e06b7e-1e9b-4b27-aac5-864a64525357_2000x626.png" width="1456" height="456" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d9e06b7e-1e9b-4b27-aac5-864a64525357_2000x626.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:456,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83410,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/210787579?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e06b7e-1e9b-4b27-aac5-864a64525357_2000x626.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!lThb!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e06b7e-1e9b-4b27-aac5-864a64525357_2000x626.png 424w, /__u/substackcdn.com/image/fetch/$s_!lThb!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e06b7e-1e9b-4b27-aac5-864a64525357_2000x626.png 848w, /__u/substackcdn.com/image/fetch/$s_!lThb!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e06b7e-1e9b-4b27-aac5-864a64525357_2000x626.png 1272w, /__u/substackcdn.com/image/fetch/$s_!lThb!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9e06b7e-1e9b-4b27-aac5-864a64525357_2000x626.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Supplemental requirements files, both general and component-specific</figcaption></figure></div><p>Designers use agents and skills to research, analyze generated specs, author requirements, and post pull requests for teammates to review, comment and approve. Requirements are consistently formatted (often with MUST, SHOULD, COULD, &#8230;) and skills keep descriptions tight and consistent.</p><p>Notwithstanding the considerable Figma motion tools released at Config 2026, designers continue to express <code>motion</code> requirements via a combination of prototypes and supplemental requirements for now.</p><h2>Foundations</h2><p>Undoubtedly, design system specs are more than just components. Critically, components are served by foundations that include tokens, fonts, icons, images, and other product marks and assets.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!o3i9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d93a5a-d9bc-4a90-bd3a-1b8390127770_2000x692.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!o3i9!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d93a5a-d9bc-4a90-bd3a-1b8390127770_2000x692.png 424w, /__u/substackcdn.com/image/fetch/$s_!o3i9!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d93a5a-d9bc-4a90-bd3a-1b8390127770_2000x692.png 848w, /__u/substackcdn.com/image/fetch/$s_!o3i9!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d93a5a-d9bc-4a90-bd3a-1b8390127770_2000x692.png 1272w, /__u/substackcdn.com/image/fetch/$s_!o3i9!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d93a5a-d9bc-4a90-bd3a-1b8390127770_2000x692.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!o3i9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d93a5a-d9bc-4a90-bd3a-1b8390127770_2000x692.png" width="1456" height="504" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/50d93a5a-d9bc-4a90-bd3a-1b8390127770_2000x692.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:504,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:48071,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/210787579?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d93a5a-d9bc-4a90-bd3a-1b8390127770_2000x692.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!o3i9!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d93a5a-d9bc-4a90-bd3a-1b8390127770_2000x692.png 424w, /__u/substackcdn.com/image/fetch/$s_!o3i9!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d93a5a-d9bc-4a90-bd3a-1b8390127770_2000x692.png 848w, /__u/substackcdn.com/image/fetch/$s_!o3i9!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d93a5a-d9bc-4a90-bd3a-1b8390127770_2000x692.png 1272w, /__u/substackcdn.com/image/fetch/$s_!o3i9!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50d93a5a-d9bc-4a90-bd3a-1b8390127770_2000x692.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">One design system&#8217;s folder of tokens and assets alongside component specs</figcaption></figure></div><p>Enterprise design systems build tools to store, publish, and manage these assets. Formats per type per enterprise vary. Sometimes it&#8217;s a repository consolidating all of them. Other times, it&#8217;s databases built with custom UI front ends to manage icons and theming tokens across countless brands.</p><p>While I&#8217;m involved in architecting relationships and taxonomies, they are highly variable across clients and worthy of a separate post.</p><div><hr></div><h1>Handling specs from multiple origins</h1><p>Designers should express intent in whatever tool fits best and specs tools blend and normalize those expressions. These days, I encounter designers expressing intent in both Figma <em>and</em> web-based prototypes. </p><p>Imagine designing a date picker first in Figma and product card first in a prototyping kit. If intent starts in different places, the system must support porting that intent from one place to another quickly and precisely. It&#8217;s not just about <em>generating</em> specs based on an expression of design intent, but <em>rendering</em> that intent elsewhere too. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!QR-X!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8a48b88-f17b-4b62-8c63-b5894a2f2f30_2000x1288.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!QR-X!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8a48b88-f17b-4b62-8c63-b5894a2f2f30_2000x1288.png 424w, /__u/substackcdn.com/image/fetch/$s_!QR-X!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8a48b88-f17b-4b62-8c63-b5894a2f2f30_2000x1288.png 848w, /__u/substackcdn.com/image/fetch/$s_!QR-X!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8a48b88-f17b-4b62-8c63-b5894a2f2f30_2000x1288.png 1272w, /__u/substackcdn.com/image/fetch/$s_!QR-X!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8a48b88-f17b-4b62-8c63-b5894a2f2f30_2000x1288.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!QR-X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8a48b88-f17b-4b62-8c63-b5894a2f2f30_2000x1288.png" width="1456" height="938" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f8a48b88-f17b-4b62-8c63-b5894a2f2f30_2000x1288.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:938,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:172853,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/210787579?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8a48b88-f17b-4b62-8c63-b5894a2f2f30_2000x1288.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!QR-X!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8a48b88-f17b-4b62-8c63-b5894a2f2f30_2000x1288.png 424w, /__u/substackcdn.com/image/fetch/$s_!QR-X!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8a48b88-f17b-4b62-8c63-b5894a2f2f30_2000x1288.png 848w, /__u/substackcdn.com/image/fetch/$s_!QR-X!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8a48b88-f17b-4b62-8c63-b5894a2f2f30_2000x1288.png 1272w, /__u/substackcdn.com/image/fetch/$s_!QR-X!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff8a48b88-f17b-4b62-8c63-b5894a2f2f30_2000x1288.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Multiple origins of component intent, connected by bi-directional transformation</figcaption></figure></div><p>As a result, my work is expanding from one edge to four: from Figma to specs (existing), specs to Figma, specs to prototype code, and prototype code to specs.</p><h2>From Figma to specs</h2><p>Specs from Figma can be generated now in three ways:</p><ol><li><p>Via <strong>plugin</strong> as designers build and review assets, producing an on-canvas report. </p></li><li><p>Via <strong>commands</strong> leveraging Figma&#8217;s Rest API via command line, Github action or LLM chat. Commands fetch files, scan for components marked <code>READY_FOR_DEV</code> and generate a library&#8217;s worth of specs in less than a minute.</p></li><li><p>Via <strong>bridge</strong> into the Figma file via the plugin UI generating specs based on a current selection.</p></li></ol><p>Great care has been put into how  multiple paths produce &#8220;byte-equivalent&#8221; (identical) specs whether from the Figma Plugin API or Rest API. These APIs are <em>not </em>the same, and thus require development (skills, fixtures, loops and harnesses) to sustain equivalent emission across both.</p><h2>From specs to Figma </h2><p>A specs <code>render</code> command leverages a <code>bridge</code> and a <code>cache</code> of system data to build a Figma asset from specs in complete detail: <a href="https://www.specsplugin.com/schema/styles/">&gt;50 style properties</a>, <a href="https://www.specsplugin.com/schema/props/">props</a>, <a href="https://www.specsplugin.com/schema/token-reference/">tokens</a>, Figma styles, prop bindings across <a href="https://www.specsplugin.com/schema/variants/">variants</a>, <a href="https://www.specsplugin.com/schema/layout/">layout</a>, and <a href="https://www.specsplugin.com/schema/slot-content/">slots</a> including default content. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Cjyr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2714e81c-ec00-4621-b824-66c00e0b5535_2000x787.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Cjyr!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2714e81c-ec00-4621-b824-66c00e0b5535_2000x787.png 424w, /__u/substackcdn.com/image/fetch/$s_!Cjyr!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2714e81c-ec00-4621-b824-66c00e0b5535_2000x787.png 848w, /__u/substackcdn.com/image/fetch/$s_!Cjyr!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2714e81c-ec00-4621-b824-66c00e0b5535_2000x787.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Cjyr!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2714e81c-ec00-4621-b824-66c00e0b5535_2000x787.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Cjyr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2714e81c-ec00-4621-b824-66c00e0b5535_2000x787.png" width="1456" height="573" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2714e81c-ec00-4621-b824-66c00e0b5535_2000x787.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:573,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:301626,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/210787579?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2714e81c-ec00-4621-b824-66c00e0b5535_2000x787.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Cjyr!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2714e81c-ec00-4621-b824-66c00e0b5535_2000x787.png 424w, /__u/substackcdn.com/image/fetch/$s_!Cjyr!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2714e81c-ec00-4621-b824-66c00e0b5535_2000x787.png 848w, /__u/substackcdn.com/image/fetch/$s_!Cjyr!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2714e81c-ec00-4621-b824-66c00e0b5535_2000x787.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Cjyr!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2714e81c-ec00-4621-b824-66c00e0b5535_2000x787.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Specs&#8217; <code>render</code> command rendering a component from specs to Figma in 1 second</figcaption></figure></div><p>Sure, agents <em>could</em> do this. Yet, inference comes with costs and risks. Specs data is layered and complicated, and imprecision and loss through inference is inevitable. The solitary <code>render</code> script is deterministic, demonstrated through &#8220;round trips&#8221; (specs to Figma to specs) that prove specs remain byte-identical: no variant, style, element or layout choice is dropped or degraded along the way.</p><h2>From specs to prototypes </h2><p>The specs <code>transform</code> command scripts <a href="https://www.specsplugin.com/cli/transforms/css/">CSS</a>, a <a href="https://www.specsplugin.com/cli/transforms/contract/">TypeScript contract</a>, <a href="https://www.specsplugin.com/cli/transforms/react/">React</a> component scaffold, and Storybook <a href="https://www.specsplugin.com/cli/transforms/stories/">stories</a>. These leverage Figma authoring conventions for <code>states</code> and component and element-specific <code>role</code>s to generate behaviors beyond what Figma enables designers to author out of the box.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!_l2_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e0cbc4-f092-48b1-bc2f-2db3980680c0_2000x564.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!_l2_!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e0cbc4-f092-48b1-bc2f-2db3980680c0_2000x564.png 424w, /__u/substackcdn.com/image/fetch/$s_!_l2_!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e0cbc4-f092-48b1-bc2f-2db3980680c0_2000x564.png 848w, /__u/substackcdn.com/image/fetch/$s_!_l2_!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e0cbc4-f092-48b1-bc2f-2db3980680c0_2000x564.png 1272w, /__u/substackcdn.com/image/fetch/$s_!_l2_!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e0cbc4-f092-48b1-bc2f-2db3980680c0_2000x564.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!_l2_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e0cbc4-f092-48b1-bc2f-2db3980680c0_2000x564.png" width="1456" height="411" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/28e0cbc4-f092-48b1-bc2f-2db3980680c0_2000x564.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:411,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:44368,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/210787579?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e0cbc4-f092-48b1-bc2f-2db3980680c0_2000x564.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!_l2_!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e0cbc4-f092-48b1-bc2f-2db3980680c0_2000x564.png 424w, /__u/substackcdn.com/image/fetch/$s_!_l2_!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e0cbc4-f092-48b1-bc2f-2db3980680c0_2000x564.png 848w, /__u/substackcdn.com/image/fetch/$s_!_l2_!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e0cbc4-f092-48b1-bc2f-2db3980680c0_2000x564.png 1272w, /__u/substackcdn.com/image/fetch/$s_!_l2_!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F28e0cbc4-f092-48b1-bc2f-2db3980680c0_2000x564.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The code isn&#8217;t intended for production, although teams could use it as a fast-forwarded starting point to coding work. Nevertheless, the files are evolving to a point suitable as a starting point for an prototyping kit that need not wait for hardened testing or engineering capacity.</p><h2>From prototypes to specs </h2><p>A blend of agents and scripts will likely extract data from prototypes into specs.</p><p>Early concepts rely on well-scaffolded and organized code that separates &#8220;spec worthy&#8221; decisions from the platform-specific code specs can&#8217;t represent. For example, imagine separate <code>generated.css</code>, <code>extensions.css</code> and <code>overrides.css</code> to relate spec-generated choices to prototype-specific expressions. It&#8217;s early days, not everything is simple (particularly the layout tree itself), but results are promising.</p><p>These <strong>transformations</strong> must be lossless, cheap, and fast to scale, regardless of direction or expression surface. Until they are in place and reliable, we can&#8217;t pursue the bigger objective: <strong>reconciliation</strong> and <strong>synchronization</strong> across surfaces.</p><div><hr></div><h1>Architecting specs</h1><h2>Versions</h2><p>Specs versions express the evolution of design intent over time. Each version is accompanied by change logs, change sets, and skill-derived release notes. These serve both to validate impact and intent (&#8220;Are these the changes we want?&#8221;) and communicate to consumers (&#8220;What&#8217;s different?&#8221;).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!I108!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa85d07fc-5c9f-4f02-a057-92658139c29f_2000x1116.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!I108!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa85d07fc-5c9f-4f02-a057-92658139c29f_2000x1116.png 424w, /__u/substackcdn.com/image/fetch/$s_!I108!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa85d07fc-5c9f-4f02-a057-92658139c29f_2000x1116.png 848w, /__u/substackcdn.com/image/fetch/$s_!I108!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa85d07fc-5c9f-4f02-a057-92658139c29f_2000x1116.png 1272w, /__u/substackcdn.com/image/fetch/$s_!I108!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa85d07fc-5c9f-4f02-a057-92658139c29f_2000x1116.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!I108!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa85d07fc-5c9f-4f02-a057-92658139c29f_2000x1116.png" width="1456" height="812" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a85d07fc-5c9f-4f02-a057-92658139c29f_2000x1116.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:812,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:80442,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/210787579?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa85d07fc-5c9f-4f02-a057-92658139c29f_2000x1116.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!I108!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa85d07fc-5c9f-4f02-a057-92658139c29f_2000x1116.png 424w, /__u/substackcdn.com/image/fetch/$s_!I108!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa85d07fc-5c9f-4f02-a057-92658139c29f_2000x1116.png 848w, /__u/substackcdn.com/image/fetch/$s_!I108!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa85d07fc-5c9f-4f02-a057-92658139c29f_2000x1116.png 1272w, /__u/substackcdn.com/image/fetch/$s_!I108!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa85d07fc-5c9f-4f02-a057-92658139c29f_2000x1116.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Organizing successive specs releases, with changelogs and release notes</figcaption></figure></div><p>When specs can be validated against an explicit schema,  you remove all doubt about what changes are major/breaking, minor or patch fixes. </p><ul><li><p>Change or remove  <code>&lt;component name&gt;.props.&lt;prop name&gt;</code>? Breaking!</p></li><li><p>Add a <code>&lt;component name&gt;.anatomy.&lt;element name&gt;</code>? Minor. </p></li><li><p>Bind a different token value to an element in a particular variant? Patch.</p></li></ul><p>I am excited about a future where discussions of &#8220;Is this breaking or not?&#8221; shift from long, tedious debates relying on subjective taste to immediate, inarguable facts.</p><h2>Schema</h2><p>Specs content is delivered within an established schema. This enables us to describe the structure and relationships of all the different intent a system collects. Combining a schema with the content we put in it forms a contract by which any consumer of the specs can build predictably and absorb changes gradually.</p><p>For more, read <a href="/__u/nathanacurtis.substack.com/p/component-contracts-and-schemas">Component Contracts and Schema</a> and browse my Specs&#8217; <a href="https://www.specsplugin.com/schema/">schema</a>.</p><h2>Architecture Decision Records (ADRs)</h2><p>Schema, tools and models are evolved using architectural decision records, or ADRs. These documents record decisions in a format with structured sections: </p><ul><li><p>metadata </p></li><li><p>context</p></li><li><p>problem</p></li><li><p>alternatives</p></li><li><p>decision</p></li><li><p>consequences</p></li><li><p>other concerns. </p></li></ul><p>Authors use straightforward skills to create, implement, and update ADRs. Once initiated, authors work with LLMs using an ADR as the baseline to evolve. They&#8217;ll explore divergent ideas, express examples, challenge assumptions, and quickly converge on a recommendation. From there, teammates can predictably review, comment on and approve the familiar format.</p><p>While we started using ADRs to ground the schema first, the approach has expanded to cover wider architecture (design and code conventions and transformations, library and asset relationships, and more). Additionally, authors now commit to <strong>visions</strong> that organize many ADRs helping teams understand the scope and impact of work often spanning many system parts.</p><p>For juicy ADR examples, read <a href="https://github.com/DirectedEdges/specs/blob/main/adr/041-layout-positioning.md">layout positioning</a> and <a href="https://github.com/DirectedEdges/specs/blob/main/adr/010-sides-and-corners.md">sides and corners</a>.</p><h2>Analysis and monitoring</h2><p>Specs rich with structured data offers ample opportunity to analyze and monitor how design intent is evolving. Every release, the specs <code>analyze</code> command autogenerates reports that itemize the library&#8217;s <a href="https://www.specsplugin.com/cli/analyze/styling/">tokens and styling</a> usage, <a href="https://www.specsplugin.com/cli/analyze/props/">props</a> models, <a href="https://www.specsplugin.com/cli/analyze/dependencies/">dependencies</a> and &#8220;keys&#8221; (naming is hard for <code>props</code> and layers/<code>elements</code>). Each report pivots spec data to many perspectives, answering questions like:</p><ul><li><p>Where is the <code>text-tertiary</code> token used across components and elements?</p></li><li><p>How do options available for <code>state</code> vary across components?</p></li><li><p>If I change the API of the <code>icon</code> component, what components are impacted?</p></li></ul><p>No agent needs to call a library via MCP, extract and pivot the data themselves. Most questions are directly answered by the data on offer. Adding and generating more reports is extremely cheap, and 5-10 more are already on the docket.</p><h1>Consuming specs</h1><p>Once specs is populated with well-structured content, our downstream engineering partners consume it with ease. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!08Pg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0aafa6b-75fe-4888-aef2-0fd899bab1a9_2000x1290.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!08Pg!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0aafa6b-75fe-4888-aef2-0fd899bab1a9_2000x1290.png 424w, /__u/substackcdn.com/image/fetch/$s_!08Pg!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0aafa6b-75fe-4888-aef2-0fd899bab1a9_2000x1290.png 848w, /__u/substackcdn.com/image/fetch/$s_!08Pg!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0aafa6b-75fe-4888-aef2-0fd899bab1a9_2000x1290.png 1272w, /__u/substackcdn.com/image/fetch/$s_!08Pg!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0aafa6b-75fe-4888-aef2-0fd899bab1a9_2000x1290.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!08Pg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0aafa6b-75fe-4888-aef2-0fd899bab1a9_2000x1290.png" width="1456" height="939" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e0aafa6b-75fe-4888-aef2-0fd899bab1a9_2000x1290.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:939,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:193963,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/210787579?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0aafa6b-75fe-4888-aef2-0fd899bab1a9_2000x1290.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!08Pg!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0aafa6b-75fe-4888-aef2-0fd899bab1a9_2000x1290.png 424w, /__u/substackcdn.com/image/fetch/$s_!08Pg!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0aafa6b-75fe-4888-aef2-0fd899bab1a9_2000x1290.png 848w, /__u/substackcdn.com/image/fetch/$s_!08Pg!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0aafa6b-75fe-4888-aef2-0fd899bab1a9_2000x1290.png 1272w, /__u/substackcdn.com/image/fetch/$s_!08Pg!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0aafa6b-75fe-4888-aef2-0fd899bab1a9_2000x1290.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Engineers build scripts and agents to transform specs into production-grade code</figcaption></figure></div><h2>From specs to code</h2><p>Specs are consumed to build component code across platforms like React, iOS and Android. My engineer teammates are architecting and building subsystems: </p><ul><li><p>Cross-platform <strong>factories</strong> that transform specs data and compare to existing code for things like CSS, contracts, and React TSX</p></li><li><p>Per-platform <strong>skills</strong> and <strong>workflows</strong> where humans and agents polish the components to completion together, grounded in specs data</p></li><li><p>Cross-platform <strong>learning </strong>capabilities to identify gaps, weaknesses and areas of improvement, including specs</p></li><li><p><strong>Testing </strong>capabilities automate spec data like variants, content and examples to ease designer review and quicken validation passes</p></li></ul><h2>From code to specs and design</h2><p>Engineers express design intent, too. As they work, they&#8217;ll evolve and extend API, identify and resolve accessibility issues, and fill behavior gaps designers hadn&#8217;t considered. That&#8217;s <em>design</em> work, just not done by a designer. Some choices already filter upstream into requirements that designers see and approve. </p><p>That work pushes how specs schema models sophisticated prop patterns, composition, behaviors and accessibility. My hope is that engineers &#8220;downstream&#8221; engage more and originate intent upstream, not just via requirements but also during planning and design.</p><p>Additionally, requests flow upstream from factories, workflows and learnings. These require changes across the ecosystem: schema, transformers, supplemental requirements and how components are built in Figma. I enjoy serving as trafficer, routing tickets to teammates and rapidly resolving them myself. The trafficer roles helps me see the system&#8217;s stability and where we can improve. Some parts hum along, others bend but stick together, and a few leak in ways smaller by the day.</p><h2>From specs to docs? Some, but not much</h2><p>Undoubtedly, specs inform docs but not so much so far . Specs are a record of names and change. Yet, prop tables and &#8220;how to use&#8221; React, iOS and Android originate more appropriately from coded implementations. Exhibit artwork remains generated from Figma assets. </p><p>Specs are far more about <em>how to make</em> the components well. The other content &#8211;&nbsp;<em>how to use</em> components &#8211;&nbsp;is really a separate enterprise driven by a partner team.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!KmMU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86ffedb6-7250-4bed-8e3c-59f606660eb2_2720x1160.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!KmMU!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86ffedb6-7250-4bed-8e3c-59f606660eb2_2720x1160.png 424w, /__u/substackcdn.com/image/fetch/$s_!KmMU!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86ffedb6-7250-4bed-8e3c-59f606660eb2_2720x1160.png 848w, /__u/substackcdn.com/image/fetch/$s_!KmMU!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86ffedb6-7250-4bed-8e3c-59f606660eb2_2720x1160.png 1272w, /__u/substackcdn.com/image/fetch/$s_!KmMU!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86ffedb6-7250-4bed-8e3c-59f606660eb2_2720x1160.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!KmMU!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86ffedb6-7250-4bed-8e3c-59f606660eb2_2720x1160.png" width="1200" height="511.8131868131868" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/86ffedb6-7250-4bed-8e3c-59f606660eb2_2720x1160.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:621,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:283000,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/210787579?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86ffedb6-7250-4bed-8e3c-59f606660eb2_2720x1160.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!KmMU!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86ffedb6-7250-4bed-8e3c-59f606660eb2_2720x1160.png 424w, /__u/substackcdn.com/image/fetch/$s_!KmMU!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86ffedb6-7250-4bed-8e3c-59f606660eb2_2720x1160.png 848w, /__u/substackcdn.com/image/fetch/$s_!KmMU!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86ffedb6-7250-4bed-8e3c-59f606660eb2_2720x1160.png 1272w, /__u/substackcdn.com/image/fetch/$s_!KmMU!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F86ffedb6-7250-4bed-8e3c-59f606660eb2_2720x1160.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Spec-driven UI component development current state, August 2026</figcaption></figure></div><h1>Where do we go from here?</h1><p>Teams commit to supporting surfaces like Figma and prototypes for design, React, Android and iOS from development. These choices&nbsp;guide our focus and priority in optimizing how specs threads through each.</p><p>Yet, open questions remain:</p><ul><li><p>Is there a future where designers express intent in prototypes but not Figma?</p></li><li><p>Will we reach a point where design intent can be transpiled across code implementations such that &#8220;designer&#8221; surfaces cease being valuable? </p></li><li><p>Can one code implementation serve as the predominant reference implementation other platforms derive from, or will all implementations remain peers to synchronize? Most but not all teams I work with would likely name their &#8220;most important&#8221; web-based implementation as their reference design.</p></li><li><p>Will AI just do it? &#129335;&#127995;&#8205;&#9794;&#65039;</p></li></ul><p>On that last point, maybe in a way I can&#8217;t visualize today. I believe our tools and systems must make our design intent visible, manageable, and verifiable. We need to make decisions, see their impact, and evolve our systems with intent.</p>]]></content:encoded></item><item><title><![CDATA[Component Contracts and Schemas]]></title><description><![CDATA[Establish principles to shape, decide and communicate design intent]]></description><link>https://nathanacurtis.substack.com/p/component-contracts-and-schemas</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/component-contracts-and-schemas</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Tue, 28 Jul 2026 11:34:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!v2JT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a8dc69-9799-4326-abfa-735999c3137f_2800x1575.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!v2JT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a8dc69-9799-4326-abfa-735999c3137f_2800x1575.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!v2JT!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a8dc69-9799-4326-abfa-735999c3137f_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!v2JT!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a8dc69-9799-4326-abfa-735999c3137f_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!v2JT!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a8dc69-9799-4326-abfa-735999c3137f_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!v2JT!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a8dc69-9799-4326-abfa-735999c3137f_2800x1575.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!v2JT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a8dc69-9799-4326-abfa-735999c3137f_2800x1575.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/44a8dc69-9799-4326-abfa-735999c3137f_2800x1575.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:130574,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/208764433?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a8dc69-9799-4326-abfa-735999c3137f_2800x1575.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!v2JT!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a8dc69-9799-4326-abfa-735999c3137f_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!v2JT!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a8dc69-9799-4326-abfa-735999c3137f_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!v2JT!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a8dc69-9799-4326-abfa-735999c3137f_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!v2JT!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a8dc69-9799-4326-abfa-735999c3137f_2800x1575.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><span>Models to define </span><a href="/__u/nathanacurtis.substack.com/p/components-as-data-2be178777f21"><span>components as data</span></a><span> are spawning across our industry. Markdown formats are proliferating. Schema models like my </span><a href="https://www.specsplugin.com/"><span>Specs plugin and command&#8217;s schema</span></a><span> and PJ Onori&#8217;s </span><a href="https://designsystemdocspec.org/"><span>Design System Doc spec</span></a><span> are emerging. </span><a href="/__u/open.substack.com/pub/southleft/p/use-ai-to-need-less-ai?r=4bvdtq&amp;utm_campaign=post&amp;utm_medium=web"><span>TJ Pitre</span></a><span>, </span><a href="/__u/open.substack.com/pub/christinevallaure/p/design-system-contracts-the-component?r=4bvdtq&amp;utm_campaign=post&amp;utm_medium=web"><span>Christine Vallaure</span></a><span>, and </span><a href="https://www.giorris.dev/thoughts/design-systems-are-contracts-not-libraries"><span>Christian Morales Achiardi</span></a><span> are diving into contracts. Perspectives abound, solving distinct and sometimes overlapping problems in similar ways.</span></p><p><span>These artifacts record UI component decisions that humans and machines read to build a component. Builders interrogate a detail and decide &#8220;What should this implementation do about it?&#8221; System designers change specs and communicate to builders to revise what&#8217;s made. In my role as a system architect, I&#8217;m responsible for &#8220;shaping specs,&#8221; evolving the model of how specs express design intent.</span></p><p><span>A library of 25 components used to change once or twice a year. Now systems span hundreds of components across libraries and platforms. Any given change lands on a spec&#8217;s shape, content, tooling or the many implementations that depend on it &#8212; sometimes all at once. The impact is wide, and widens daily. I&#8217;ve spent the past 18 months building schema and tools that describe component design as contracts, largely because we couldn&#8217;t handle change any other way.</span></p><p><span>This post describes conveying the design intent of a UI component as a </span><strong><span>contract</span></strong><span> and how that contract can be modeled as a </span><strong><span>schema</span></strong><span>. It then follows with facets of good contracts &#8211; </span><strong><span>well-typed, normalized, independent, verifiable, deterministic, efficient and evolvable</span></strong><span> &#8211; I&#8217;ve embraced as principles to guide work.</span></p><div><hr></div><h2><strong><span>The Contract</span></strong></h2><p><span>A UI component </span><strong><span>contract</span></strong><span> is an artifact that centralizes design intent in one place so that it can be implemented, verified and evolved across implementations. For example, an intent for button size resolves into a contract of &#8220;The </span><code>button</code><span> can be one of three </span><code>size</code><span>s (</span><code>medium</code><span> by default, or </span><code>small</code><span> or </span><code>large</code><span>), with </span><code>styles</code><span> varying as&#8230;&#8221;.</span></p><p><span>Teams are leveraging AI to increase the formality with which they store, change, and communicate component specs as contracts. A published component spec serving as a contract declares intent formally in a way implementers can rely on. Literally, as data to consume, build upon, and verify against. There&#8217;s often a </span><code>specifications</code><span> repository with component contracts, published with the changelogs and release notes to derive and build what&#8217;s changed.</span></p><div class="pullquote"><p><span>A description informs. A contract arbitrates.</span></p></div><p><span>As a contract, a component spec isn&#8217;t just about recording truth. Instead, a contract arbitrates interpreting truth across each implementing party. In a multi-platform design system, React, iOS, Android, Web Components and &#8211; yes &#8211; even Figma are all parties to that contract. As a multi-party agreement, no platform owns it and each platform is meant to sign and abide by it through its implementation.</span></p><p><span>Without a contract and infrastructure around it, the system&#8217;s promise of consistency, quality and pace rests on human vigilance. Humans on teams I work with have no time for that anymore, as expectations have changed.</span></p><p><span>So, contracts have replaced meetings with automated and verifiable communication and checks. Before, delivering a component would require a handoff meeting per platform team. Now we&#8217;re mass-delivering an entire library&#8217;s spec from Figma with a single, repeatable command. Designers simply mark a component </span><code>READY_FOR_DEV</code><span>, conduct an agentic pass to compose the behaviors and accessibility Figma can&#8217;t, and field occasional Slack threads to clarify requirements as needed.</span></p><p></p><h2><strong><span>The Schema, Shaping the Contract</span></strong></h2><p><span>Less formal component specs may represent decisions in a file with templated sections, such as a markdown file with tables for </span><code>Layout</code><span>, </span><code>Props</code><span> and </span><code>Anatomy</code><span>. Markdown components specs have spread for a reason: anyone can author it, PR tools can review it, agents can read and write it, and no tooling is needed to adopt it. Yet, markdown is loosely structured and not structurally validated, leaving it weak to arbitration and verification. Contracts should be formal and strict, and developing a schema for a contract is a way to do so.</span></p><p><span>A schema is the model a contract is written in. It defines what and how to define a component while deliberately saying nothing about any component in particular. The schema is the structure: a model of types, hierarchies, and relationships that express the system&#8217;s elements and relationships explicitly. </span></p><div class="pullquote"><p><span>A schema models what a contract </span><em><span>can</span></em><span> say.<br>A spec based on that schema is what a contract </span><em><span>does</span></em><span> say. </span></p></div><p><span>I&#8217;ve spent the last 18 months modeling a component contract into </span><a href="https://www.specsplugin.com/schema/"><span>Specs schema</span></a><span>. In the button example above, the schema models decisions in a grammar. A </span><code>Component</code><span> has </span><code>Props</code><span>, including an </span><code>EnumProp</code><span> with a name (like </span><code>size</code><span>) and </span><code>enum</code><span> options, each a string (like </span><code>large</code><span> and </span><code>small</code><span>), one of which is the </span><code>default</code><span> (like </span><code>medium</code><span>). A UI component schema is a meta system one level deeper: an abstraction of component decisions shaped into a model.</span></p><p><span>The spec&#8217;s content (there&#8217;s a </span><code>Button</code><span> with a </span><code>size</code><span> prop) is versioned, and the schema model (a </span><code>Component</code><span> has </span><code>Props</code><span> such as an </span><code>EnumProp</code><span>) is versioned too, separately. Implementing a component&#8217;s contract depends on both. It&#8217;s this model that makes a component contract being &#8220;wrong&#8221; both computable and inarguable.</span></p><p><span>The more rigorous the contract and schema, the more deterministic transformation (to CSS, stories, TypeScript contracts, scaffolds, etc) can become boring infrastructure, too. With a strong contract, component production is supported by scripts that generate 80-90% of the code you need </span><em><span>before</span></em><span> agents get to work. This leaves agentic inference for last strides, not foundation-up construction, and also isolates what you&#8217;ve generated when things change.</span></p><div><hr></div><h2><strong><span>What makes a good contract and schema?</span></strong></h2><h3><strong><span>1. Favor well-typed over loosely formed</span></strong></h3><p><span>A type declares what kind of value is legal in a given position: a number, a true/false, or one choice from a fixed list &#8212; an enum. A well-typed contract makes it impossible to write malformed things. </span></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;yaml&quot;,&quot;nodeId&quot;:&quot;b1d1a8b7-92f7-41f8-8b5c-c1220934e9a7&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-yaml">props:
  size:
    type: string
    enum:
      - small
      - medium
      - large
    default: medium</code></pre></div><p>A <code>size</code> <code>enum</code> reduces any possible size to three legal choices. <span>In a loosely formed document, every value is just text, and text accepts anything, such as </span><code>size:med</code><span> or size: </span><code>kind of</code><span> </span><code>large</code><span>.</span></p><p><span>An </span><code>Element</code><span> is included in a </span><code>Variant</code><span> and is bound to </span><code>Styles</code><span> like </span><code>backgroundColor</code><span> and </span><code>itemSpacing</code><span> (if a </span><code>container</code><span>) or </span><code>textColor</code><span> (as a themed token) and </span><code>typography.fontSize</code><span> (if </span><code>text</code><span>). All of these types and relationships are explicitly structured. No text element should have a </span><code>backgroundColor</code><span>, and no container should ever have a </span><code>glyph</code><span> name.</span></p><p><span>Additionally, contracts are too loosely formed when signals are left to implicit naming conventions. For example, a markdown file might encode states implicitly in token or variant names like </span><code>button-primary</code><span>, </span><code>button-primary-hover</code><span>, and </span><code>button-primary-active</code><span>. An agentic pass usually figures it out, but the contract can&#8217;t verify and hold every implementation accountable.</span></p><p></p><h3><strong><span>2. Favor normalized over redundant</span></strong></h3><p><span>Good contracts state each decision once. My favorite example remains the </span><code>button</code><span>&#8217;s </span><code>disabled</code><span> state. A contract need only state this as a configuration variant, specifying an </span><code>opacity</code><span> of the </span><code>root</code><span> element once.</span></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;yaml&quot;,&quot;nodeId&quot;:&quot;e74d5b91-2044-4dd7-9484-b5999f6d65bd&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-yaml">button:
  variants:
    - configurations:
        disabled: true
      elements:
        root:
          opacity: 0.36</code></pre></div><p><span>Yet a Figma button with 96 variants requires 96 more variants, each carrying the varied </span><code>opacity</code><span> property.  </span>This exposes Figma&#8217;s verbose data model as an imperfect contract. <span>That&#8217;s massive redundancy &#8211; maybe 500ish layers &#8211; for one simple intent.</span></p><p><span>Contracts are bad when you state the same decision twice, in different positions or contexts. A self-contradicting artifact cannot arbitrate anything. For example, a markdown file describing colors like </span><code>text-primary</code><span> (</span><code>#21272A</code><span>) in a prose description </span><em><span>and</span></em><span> </span><code>text-primary: &#8220;#1A1C1E&#8221;</code><span> in a YAML inventory is redundant. This de-normalization isn&#8217;t an accident; it&#8217;s an intentional, documented format that risks drift intrinsically.</span></p><div class="pullquote"><p><span>A self-contradicting artifact cannot arbitrate anything.</span></p></div><p><span>Be wary of contracts positioned as a &#8220;single source of truth&#8221; that then encode decisions in multiple locations. I think to myself, &#8220;Is this declaration </span><em><span>here</span></em><span> the source, or is that declaration </span><em><span>there</span></em><span> the source?&#8221; Nobody knows.</span></p><p><span>The moment a decision lives in two places, the contract risks disagreeing with itself. A spec architect could write rules into skills to prevent drift. Yet guarding against conflicts of intentional redundancies is wrong; avoid the redundancy in the first place.</span></p><p></p><h3><strong><span>3. Favor independent over platform biased</span></strong></h3><p><span>A good contract minimizes the bias of its shape away from any predominant platform, whether Figma, CSS, iOS, Android. A definition extracted untransformed from one party&#8217;s point-of-view (like a Figma file) is testimony, not a contract.</span></p><p><span>It&#8217;s challenging to model schema when you spend as much time as I do extracting intent from Figma. Figma&#8217;s biased point-of-view is evident in ways glaring (like prop types of </span><code>INSTANCE_SWAP</code><span>) or subtle (like absolute positioning anchored in </span><code>constraints</code><span> rather than edges). Grounding contracts in Figma-only types is wrong, since Figma&#8217;s model is an approximation relative to web, iOS and Android code.</span></p><div class="pullquote"><p>A definition biased to one party&#8217;s point-of-view is testimony, not a contract.</p></div><p><span>As I&#8217;ve been modeling </span><a href="https://www.specsplugin.com/schema/"><span>Specs schema</span></a><span>, I&#8217;ve spent considerable effort bringing spec data to be more platform neutral. Example cases include:</span></p><ul><li><p><span>The &#8220;Sides&#8221; of </span><code>padding</code><span>, </span><code>strokeWeight</code><span> and </span><code>absolute</code><span>ly positioned elements as </span><code>start</code><span> and </span><code>end</code><span> rather than the familiar </span><code>left</code><span> and </span><code>right</code><span> (</span><a href="https://github.com/DirectedEdges/specs/blob/main/adr/010-sides-and-corners.md"><span>Sides ADR</span></a><span>) and </span><code>constraints</code><span> (</span><a href="https://github.com/DirectedEdges/specs/blob/main/adr/041-layout-positioning.md"><span>Positioning ADR</span></a><span>). In each case, Figma&#8217;s model is weaker as a contract.</span></p></li><li><p><span>Mass-transforming Figma </span><code>TEXT</code><span> props from </span><code>string</code><span> to </span><code>number</code><span> when </span><code>default</code><span> values match specific numeric formats (</span><a href="https://github.com/DirectedEdges/specs/blob/main/adr/029-number-prop.md"><span>Numbers ADR</span></a><span>). Here, Figma&#8217;s model is incomplete, requiring us to concede the risk of misclassification to correctly re-type props en-masse based on a heuristic.</span></p></li></ul><p><span>Avoiding bias is hard. My Specs&#8217; </span><code>layout</code><span> echoes Figma&#8217;s layer hierarchy. Admittedly, all code platforms diverge and achieving a deterministically transformable hierarchy across platforms is a fool&#8217;s errand (or, at least for now, not a priority). So, I&#8217;ll cull unintentional leaks over time. Other times, we&#8217;ll simply override Figma generated outputs with authored versions, such as declaring more sophisticated component props because Figma&#8217;s limited prop types lack the needed expressiveness.</span></p><p><span>Critics could also point to Specs&#8217; </span><a href="https://www.specsplugin.com/schema/variants/"><span>Variants structure</span></a><span> and cry foul. The bias is right there in the name &#8211; Variants! &#8211; encoded as a type (</span><code>Variants</code><span>, </span><code>Variant</code><span>) and the </span><code>variants.yaml</code><span> file output by the generator. Yet, reading further exposes schema&#8217;s </span><a href="https://www.specsplugin.com/guides/variant-layering/"><span>layered, compact data model</span></a><span>, which is far closer to web&#8217;s CSS. So bias may remain by name (towards Figma) and model (towards web). Yet the concept has proven very suitable across all implementations. We&#8217;re sticking with it.</span></p><p></p><h3><strong><span>4. Favor verifiable over readable</span></strong></h3><p><span>Verifiable contracts can be evaluated and decided as right or wrong by a machine, without human intervention. Two questions, two levels: is this a validly structured spec, and is it precisely implemented? A verifiable contract can reject a definition that references a dependency that doesn&#8217;t exist, sets a property the schema doesn&#8217;t support, or names an icon glyph the library doesn&#8217;t ship. Reading a markdown file answers none of that.</span></p><div class="pullquote"><p><span>Reading is review, not verification.</span></p></div><p><span>Markdown readers are built to tolerate ambiguity. Unknown token name? Accept it. Unknown component property describing this variant? Maybe fire a warning. A format where nothing is invalid is a format where nothing is verifiable. A linter can still check WCAG contrast or a broken link. However, when malformed isn&#8217;t defined, a reader is left to guess or hunt.</span></p><p><span>I am uncomfortable with spec prose describing types of decisions that frequently recur when they can be more strictly modeled. When prose like &#8220;Depth is achieved through tonal layers rather than heavy shadows&#8221; is load bearing, I&#8217;m lost. What makes a shadow heavy? What makes a layer tonal? What are the tones? When I can&#8217;t verify something, I want to delete it. And if deleting that sentence changes the contract, that sentence was bearing too much load. That&#8217;s not the contract I want.</span></p><p><span>A validated extract isn&#8217;t strict if downstream recipients consume a markdown file that an LLM already smoothed and elaborated. The verification data got stuck at the boundary and every consumer downstream is inferring from inference.</span></p><p></p><h3><strong><span>5. Favor determinism over inference</span></strong></h3><p><span>Determinism means the same input produces the same output, every time. Generate the spec twice with nothing changed, and your diff should be empty &#8211; no reordered keys, no noise. I change a </span><code>textTruncation</code><span> property buried deep in a text layer in a variant combining three props, regenerate, and that admittedly esoteric intent appears as a single additive change.</span></p><p><span>In 2026, solely markdown formats serving as &#8220;THE System&#8221; &#8211; foundational context to guide agents making decisions &#8211; makes me nervous. Even when a workflow extracts data deterministically to start, agents layering intent through skills and rules inject uncertainty early and invisibly. Errors are introduced upstream before becoming spec, propagate wider and harden right when we thought we were recording truth.</span></p><div class="pullquote"><p><span>Deterministic compilation isn&#8217;t the goal. It&#8217;s evidence the contract is good.</span></p></div><p><span>Transformations are necessary, such as overlaying </span><a href="https://www.specsplugin.com/guides/subcomponent-scoping/"><span>subcomponents</span></a><span>, </span><a href="https://www.specsplugin.com/guides/glyph-name-pattern/"><span>icon glyphs</span></a><span>, and </span><a href="https://www.specsplugin.com/settings/states/"><span>states</span></a><span> onto Figma&#8217;s model using naming conventions. Reading them back out takes real logic, but it&#8217;s achievable, maintainable and based on conventions set by system architects. That&#8217;s my line: inference I configure, not inference I hope for. We know what comes out based on what goes in, it&#8217;s mechanical, and it takes seconds.</span></p><p></p><h3><strong><span>6. Favor efficiency over expense to keep true</span></strong></h3><p><span>Efficiency means the cost of bringing the contract current is close to zero &#8211; in time, in tokens, and in human attention. Not the cost of building it, the cost of keeping it true. Once built, we used to change a component infrequently. Now we want to adjust and evolve constantly &#8211; a minor tweak, new element, added configuration, fixed defect &#8211; because we can. Every tweak comes with a bill, and nobody likes to be kept waiting.</span></p><p><span>The more deterministic the infrastructure, the more the marginal cost of regeneration converges on zero. That matters, because a contract too costly to maintain will rot. A rotted contract is worse than no contract at all, because people trust contracts. If you&#8217;ve got 25 simple components on one platform, this doesn&#8217;t matter and you shouldn&#8217;t spend on it. But if your vision is updating 100+ components across 4 implementations changing weekly? Economics decides the architecture for you.</span></p><div class="pullquote"><p><span>A rotted contract is worse than no contract at all.</span></p></div><p><span>Using </span><a href="https://www.specsplugin.com/cli/"><span>Specs&#8217; command line tools</span></a><span> to (re)fetch and (re)generate has made this possible for clients. Want to update </span><code>backgroundColor</code><span> for an </span><code>active</code><span>, </span><code>selected</code><span>, </span><code>tertiary</code><span> variant? Go ahead. Regenerating specs will pick up the change, whether we run it next sprint, tomorrow, or the moment a watcher notices the Figma library file&#8217;s main branch moved.</span></p><p></p><h3><strong><span>7. Favor evolvable over simply flexible</span></strong></h3><p><span>Strict doesn&#8217;t mean static. A contract that can&#8217;t change dies, and a contract that changes without governance was never actually a contract. Is there a record of why the contract is shaped the way it is, and how that shape changed over time?</span></p><p><span>I recently integrated a new contract feature: </span><a href="https://www.specsplugin.com/settings/images/"><span>images</span></a><span>. The feature impacted many components and spread across the schema&#8217;s surface: a component&#8217;s API (a new </span><code>image</code><span> prop type), </span><code>styles</code><span> bindings (via a </span><code>backgroundImage</code><span> property), </span><code>examples</code><span> and even storage.</span></p><p><span>I could have just winged it, adding notes to markdown files of impacted components. Yet, that&#8217;s evolving the contract privately, in a manner undetectable downstream without reading the entire contract from scratch every time. This is &#8220;flexibility&#8221; masquerading as evolvability, which is like branding drift with a more favorable descriptor.</span></p><div class="pullquote"><p><span>A contract that can&#8217;t change dies. A contract changing without governance isn&#8217;t a contract.</span></p></div><p><a href="https://github.com/DirectedEdges/specs/blob/main/adr/INDEX.md"><span>Architectural decision records (ADRs)</span></a><span> are the machinery to evolve component specs. The </span><a href="https://github.com/DirectedEdges/specs/blob/main/adr/063-image-content.md"><span>images ADR</span></a><span> sprawled, but the breadth fostered iteration and alignment with teammates. Decisions in ADRs drive new schema versions, keep specs valid, and communicate downstream to consumers who see exactly what&#8217;s changed and opt in when ready.</span></p><p><span>My downstream partners pushed back on the </span><code>images</code><span> update, if only because their tools include deterministic scripts that weren&#8217;t ready. Delaying the next generating pass for a week is a welcome outcome. It reinforced that conversations had shifted from complicated interpretations to simple coordination. For everybody, the change felt more like business-as-usual than a threat to stability.</span></p><p></p><div><hr></div><p><span>Settling on the correct form(s) of component contracts will take time. JSON schema took two decades. The W3C design tokens community group needed a full decade after tokens hit the scene. Formats will continue to spawn and refine. They&#8217;ll also solve different problems for different systems.</span></p><p><span>Heck, my own work has come so far that I look back unamused with how much less effective my schema was this time last year. Sometimes Figma bias still leaks through and other gaps reveal themselves. So I push on, one ADR and tooling update after another.</span></p><p><span>Can you point implementing teams at a contract, change its content and its model over time, and regenerate it so they consume it cost-effectively as needed?  If you are delivering specs manually or via a contract with less structure, skeptically critique your setup to identify where and how you can do better. For some, markdown may be all you need. For others, the journey continues somewhere more structured.</span></p>]]></content:encoded></item><item><title><![CDATA[Component Examples as Data]]></title><description><![CDATA[Demonstrating what&#8217;s possible for designers and machines alike]]></description><link>https://nathanacurtis.substack.com/p/component-examples-as-data</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/component-examples-as-data</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Tue, 26 May 2026 17:38:43 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!5Muc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F368a0e18-e5ca-4869-a66a-5cfb743a5f74_2800x1575.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!5Muc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F368a0e18-e5ca-4869-a66a-5cfb743a5f74_2800x1575.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!5Muc!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F368a0e18-e5ca-4869-a66a-5cfb743a5f74_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!5Muc!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F368a0e18-e5ca-4869-a66a-5cfb743a5f74_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!5Muc!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F368a0e18-e5ca-4869-a66a-5cfb743a5f74_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!5Muc!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F368a0e18-e5ca-4869-a66a-5cfb743a5f74_2800x1575.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!5Muc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F368a0e18-e5ca-4869-a66a-5cfb743a5f74_2800x1575.png" width="728" height="409.5" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/368a0e18-e5ca-4869-a66a-5cfb743a5f74_2800x1575.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:134253,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/199324016?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F368a0e18-e5ca-4869-a66a-5cfb743a5f74_2800x1575.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!5Muc!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F368a0e18-e5ca-4869-a66a-5cfb743a5f74_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!5Muc!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F368a0e18-e5ca-4869-a66a-5cfb743a5f74_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!5Muc!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F368a0e18-e5ca-4869-a66a-5cfb743a5f74_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!5Muc!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F368a0e18-e5ca-4869-a66a-5cfb743a5f74_2800x1575.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The empty card. Drop it on a canvas and it stares back: unopinionated, empty, waiting for instruction.</p><p>In composable component catalogs, it&#8217;s common for assets like a <code>Card</code> to either offer a default scaffold of simplistic content or &#8211; when there&#8217;s no predominant default &#8211; nothing at all. The starting point leaves an author tremendous flexibility, but uncertainty too. What am I to do with this? What am I permitted to do with this? What&#8217;s possible with this?</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Qyyx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0214150b-0a26-4e87-a3bf-199147070bac_1400x642.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Qyyx!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0214150b-0a26-4e87-a3bf-199147070bac_1400x642.png 424w, /__u/substackcdn.com/image/fetch/$s_!Qyyx!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0214150b-0a26-4e87-a3bf-199147070bac_1400x642.png 848w, /__u/substackcdn.com/image/fetch/$s_!Qyyx!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0214150b-0a26-4e87-a3bf-199147070bac_1400x642.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Qyyx!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0214150b-0a26-4e87-a3bf-199147070bac_1400x642.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Qyyx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0214150b-0a26-4e87-a3bf-199147070bac_1400x642.png" width="1400" height="642" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0214150b-0a26-4e87-a3bf-199147070bac_1400x642.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:642,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:25831,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/199324016?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0214150b-0a26-4e87-a3bf-199147070bac_1400x642.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Qyyx!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0214150b-0a26-4e87-a3bf-199147070bac_1400x642.png 424w, /__u/substackcdn.com/image/fetch/$s_!Qyyx!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0214150b-0a26-4e87-a3bf-199147070bac_1400x642.png 848w, /__u/substackcdn.com/image/fetch/$s_!Qyyx!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0214150b-0a26-4e87-a3bf-199147070bac_1400x642.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Qyyx!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0214150b-0a26-4e87-a3bf-199147070bac_1400x642.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">DS Card component placed on a Figma canvas with no default content</figcaption></figure></div><p>Crafting the best UI component isn&#8217;t just authoring configurable props and varying visual style and layout. System designers should also express a component&#8217;s composable potential and intended use. Those downstream depend on examples: designers see range and start fast, system engineers get pre-validated, on-foundation starting points, and AI gets a corpus encoding patterns, rules and guidance.</p><p>Which components actually need examples? It&#8217;s definitely not all of them, but it&#8217;s more than you think. Sure, the <code>Card</code>, <code>Modal</code> and <code>Sheet</code>s of your system intend to provide a composable body and even customizable headers and footers within. These shells benefit greatly from examples. Other components like <code>Row</code>s in feeds and e-commerce tightly orchestrate visuals, content and actions. Even configurable atomics like <code>Pill</code> and <code>Button</code> &#8211; used at high volume and customized <em>very infrequently</em> &#8211; may require a composition from time to time.</p><p>This post describes what examples are, where they fit, why they matter, how they demonstrate a range of composable possibilities, legible to both humans and AI alike.</p><h2>About Examples</h2><p>Ready-made examples build upon the configurable component asset that all catalogs start with. They are additive, built beside the configurable asset to represent the component&#8217;s potential distinct from what otherwise could become a sprawling matrix of brittle variants. Composing examples redirects teams to spend time to demonstrate possibility rather than engineering yet another multitude of variants to achieve a single requirement. It answers what can I make with this as an improved well crafted starting point that people can duplicate and take from there.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!OBL-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7844f6c3-01b4-4e9c-9278-c4e9cc73b203_3776x1824.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!OBL-!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7844f6c3-01b4-4e9c-9278-c4e9cc73b203_3776x1824.png 424w, /__u/substackcdn.com/image/fetch/$s_!OBL-!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7844f6c3-01b4-4e9c-9278-c4e9cc73b203_3776x1824.png 848w, /__u/substackcdn.com/image/fetch/$s_!OBL-!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7844f6c3-01b4-4e9c-9278-c4e9cc73b203_3776x1824.png 1272w, /__u/substackcdn.com/image/fetch/$s_!OBL-!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7844f6c3-01b4-4e9c-9278-c4e9cc73b203_3776x1824.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!OBL-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7844f6c3-01b4-4e9c-9278-c4e9cc73b203_3776x1824.png" width="724.953125" height="350.0288783482143" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7844f6c3-01b4-4e9c-9278-c4e9cc73b203_3776x1824.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:703,&quot;width&quot;:1456,&quot;resizeWidth&quot;:724.953125,&quot;bytes&quot;:322404,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/199324016?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7844f6c3-01b4-4e9c-9278-c4e9cc73b203_3776x1824.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!OBL-!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7844f6c3-01b4-4e9c-9278-c4e9cc73b203_3776x1824.png 424w, /__u/substackcdn.com/image/fetch/$s_!OBL-!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7844f6c3-01b4-4e9c-9278-c4e9cc73b203_3776x1824.png 848w, /__u/substackcdn.com/image/fetch/$s_!OBL-!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7844f6c3-01b4-4e9c-9278-c4e9cc73b203_3776x1824.png 1272w, /__u/substackcdn.com/image/fetch/$s_!OBL-!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7844f6c3-01b4-4e9c-9278-c4e9cc73b203_3776x1824.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Atlassian&#8217;s library, demonstrating &#8220;Ready-made examples&#8221; beside component assets</figcaption></figure></div><p>Design systems have been crafting ready-made examples for years, as demonstrated by <a href="https://www.figma.com/@atlassian">Atlassian&#8217;s Figma library</a> published on the Figma community. Examples are often positioned to the right of the component set and parts as one of often many other authored outputs (such as specs and change history). While historically also possibly in a sticker sheet on another page or even in another file, most teams today position these directly adjacent to the component asset itself.</p><div class="pullquote"><p>Make the common configurable. Make the uncommon composable</p></div><p>The craft that makes a component quality clear to a designer is the same that makes it legible to a machine. Props aren&#8217;t enough. Ready-made examples are not variants that show up as a configurable surface. Those props represented as a Figma variant grid or Storybook stories represent what&#8217;s built into the component. Composition goes wider, and examples take us there. </p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Hspi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30d8cd8-312c-42b0-84a0-49adbb234016_6226x1066.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Hspi!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30d8cd8-312c-42b0-84a0-49adbb234016_6226x1066.png 424w, /__u/substackcdn.com/image/fetch/$s_!Hspi!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30d8cd8-312c-42b0-84a0-49adbb234016_6226x1066.png 848w, /__u/substackcdn.com/image/fetch/$s_!Hspi!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30d8cd8-312c-42b0-84a0-49adbb234016_6226x1066.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Hspi!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30d8cd8-312c-42b0-84a0-49adbb234016_6226x1066.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Hspi!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30d8cd8-312c-42b0-84a0-49adbb234016_6226x1066.png" width="1200" height="205.21978021978023" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f30d8cd8-312c-42b0-84a0-49adbb234016_6226x1066.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:249,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:1000148,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/199324016?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30d8cd8-312c-42b0-84a0-49adbb234016_6226x1066.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Hspi!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30d8cd8-312c-42b0-84a0-49adbb234016_6226x1066.png 424w, /__u/substackcdn.com/image/fetch/$s_!Hspi!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30d8cd8-312c-42b0-84a0-49adbb234016_6226x1066.png 848w, /__u/substackcdn.com/image/fetch/$s_!Hspi!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30d8cd8-312c-42b0-84a0-49adbb234016_6226x1066.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Hspi!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff30d8cd8-312c-42b0-84a0-49adbb234016_6226x1066.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Card component composed examples</figcaption></figure></div><p>Component test cases pressure test a component, but lack nuance and intent. As configured alternatives, they&#8217;ll miss the real thing: composed arrangements, real content, custom binding and styles that bring a component to life. Examples bring humans and machines out of the narrow, configurable essence towards how components fit together to solve problems. </p><h2>Slot Default Content is an Example, Too</h2><p>Now that Figma has enabled slots, examples take on an extended importance. Component assets can now include example slot content as a customizable scaffold directly in the asset itself. Make no mistake: this content is NOT part of the component&#8217;s configurable contract. Nevertheless, a slot&#8217;s default content expands how system designers convey intent and provide a starting point to be extended and overridden.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!SC-x!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45e7892a-fb7b-414f-b450-f0f12240bdb6_814x566.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!SC-x!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45e7892a-fb7b-414f-b450-f0f12240bdb6_814x566.png 424w, /__u/substackcdn.com/image/fetch/$s_!SC-x!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45e7892a-fb7b-414f-b450-f0f12240bdb6_814x566.png 848w, /__u/substackcdn.com/image/fetch/$s_!SC-x!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45e7892a-fb7b-414f-b450-f0f12240bdb6_814x566.png 1272w, /__u/substackcdn.com/image/fetch/$s_!SC-x!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45e7892a-fb7b-414f-b450-f0f12240bdb6_814x566.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!SC-x!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45e7892a-fb7b-414f-b450-f0f12240bdb6_814x566.png" width="814" height="566" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/45e7892a-fb7b-414f-b450-f0f12240bdb6_814x566.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:566,&quot;width&quot;:814,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:28372,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/199324016?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45e7892a-fb7b-414f-b450-f0f12240bdb6_814x566.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!SC-x!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45e7892a-fb7b-414f-b450-f0f12240bdb6_814x566.png 424w, /__u/substackcdn.com/image/fetch/$s_!SC-x!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45e7892a-fb7b-414f-b450-f0f12240bdb6_814x566.png 848w, /__u/substackcdn.com/image/fetch/$s_!SC-x!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45e7892a-fb7b-414f-b450-f0f12240bdb6_814x566.png 1272w, /__u/substackcdn.com/image/fetch/$s_!SC-x!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45e7892a-fb7b-414f-b450-f0f12240bdb6_814x566.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Default slot content also challenges system designers to assess the component&#8217;s configurable boundary. What elements should only be configured? What elements are suitably composed in a slot? When the latter, to achieve what kinds of result? Formalizing examples &#8211; including the content scaffolded within an asset&#8217;s slot &#8211; enables system practitioners to illustrate both configurations and compositions beside and within assets.</p><h2>Examples Illustrate Common Customization</h2><p>&#8220;Simple, atomic&#8221; components like button may warrant only one or two examples, such as with a counter or loading spinner. Having a composed example sends a signal: it&#8217;s OK to customize when the time is right. From there, ready made examples provide the place to demonstrate a range of component concerns across many axes. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!d0hs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cb0e97-2d5c-46e6-a5d8-12ebde5c404d_1544x715.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!d0hs!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cb0e97-2d5c-46e6-a5d8-12ebde5c404d_1544x715.png 424w, /__u/substackcdn.com/image/fetch/$s_!d0hs!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cb0e97-2d5c-46e6-a5d8-12ebde5c404d_1544x715.png 848w, /__u/substackcdn.com/image/fetch/$s_!d0hs!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cb0e97-2d5c-46e6-a5d8-12ebde5c404d_1544x715.png 1272w, /__u/substackcdn.com/image/fetch/$s_!d0hs!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cb0e97-2d5c-46e6-a5d8-12ebde5c404d_1544x715.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!d0hs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cb0e97-2d5c-46e6-a5d8-12ebde5c404d_1544x715.png" width="1456" height="674" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/61cb0e97-2d5c-46e6-a5d8-12ebde5c404d_1544x715.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:674,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:118917,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/199324016?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cb0e97-2d5c-46e6-a5d8-12ebde5c404d_1544x715.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!d0hs!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cb0e97-2d5c-46e6-a5d8-12ebde5c404d_1544x715.png 424w, /__u/substackcdn.com/image/fetch/$s_!d0hs!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cb0e97-2d5c-46e6-a5d8-12ebde5c404d_1544x715.png 848w, /__u/substackcdn.com/image/fetch/$s_!d0hs!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cb0e97-2d5c-46e6-a5d8-12ebde5c404d_1544x715.png 1272w, /__u/substackcdn.com/image/fetch/$s_!d0hs!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F61cb0e97-2d5c-46e6-a5d8-12ebde5c404d_1544x715.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Pill component with simple composed examples</figcaption></figure></div><p>The Alert component demonstrates a widening array of shifts. Variants capture changes in icon and color per configuration and examples broaden the story </p><p>When using <em>this</em> <code>Alert</code>, it&#8217;s ok to&#8230;</p><ul><li><p>insert <code>elements</code>  like <code>badge</code>, dismiss button, o drawer<code> </code></p></li><li><p>customize <code>style</code> of elements like text to increase a font size or a frame to create additional emphasis or space</p></li><li><p>rearrange <code>layout</code>, like vertical or horizontal direction of elements and areas</p></li><li><p>exhibit what elements are essential elements, like a title or description or both</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Mg-n!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f9f958-b24b-4b84-8fbe-405ce2b5876f_3458x1730.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Mg-n!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f9f958-b24b-4b84-8fbe-405ce2b5876f_3458x1730.png 424w, /__u/substackcdn.com/image/fetch/$s_!Mg-n!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f9f958-b24b-4b84-8fbe-405ce2b5876f_3458x1730.png 848w, /__u/substackcdn.com/image/fetch/$s_!Mg-n!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f9f958-b24b-4b84-8fbe-405ce2b5876f_3458x1730.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Mg-n!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f9f958-b24b-4b84-8fbe-405ce2b5876f_3458x1730.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Mg-n!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f9f958-b24b-4b84-8fbe-405ce2b5876f_3458x1730.png" width="726.546875" height="363.2734375" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/98f9f958-b24b-4b84-8fbe-405ce2b5876f_3458x1730.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:726.546875,&quot;bytes&quot;:244947,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/199324016?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f9f958-b24b-4b84-8fbe-405ce2b5876f_3458x1730.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Mg-n!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f9f958-b24b-4b84-8fbe-405ce2b5876f_3458x1730.png 424w, /__u/substackcdn.com/image/fetch/$s_!Mg-n!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f9f958-b24b-4b84-8fbe-405ce2b5876f_3458x1730.png 848w, /__u/substackcdn.com/image/fetch/$s_!Mg-n!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f9f958-b24b-4b84-8fbe-405ce2b5876f_3458x1730.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Mg-n!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f9f958-b24b-4b84-8fbe-405ce2b5876f_3458x1730.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Alert component, positioning configurable assets (on the left) beside composed examples (on the right)</figcaption></figure></div><p>So look at a component with a different lens: how might its elements, styles, and layout shift in ways that configurable props don&#8217;t &#8211; and shouldn&#8217;t &#8211; control?</p><h2>Examples Data Consumed Downstream</h2><p>Example data fidelity matters: screenshots may be good, code may be better, but well modeled component data is best. As examples proliferate, we&#8217;re building mechanics to capture these examples and project them through the rest of the pipeline. Generating examples as data from Figma can be useful for generating many outputs. The same Card example renders the React doc page, seeds a Storybook story, and answers a Cursor prompt for a pricing card.</p><p>As such, I&#8217;ve integrated `examples` into my <a href="https://www.figma.com/community/plugin/1549454283615386215/specs-2-formerly-anova">Specs plugin</a> and <a href="https://directededges.github.io/specs/">Specs CLI</a> framework as a first class component output alongside `api` (props and elements) and styling rich `variants` (default and variant-based shifts in styling, layout and bindings). This positions examples in the same flow as handing off design: author examples (today, in Figma), generate the data, use for downstream applications over and over.</p><p>Two new data shapes are emitted:</p><ul><li><p><code>instanceExamples</code>, corresponding to the ready-made instances of the component assets matching particular naming patterns and/or <code>parent</code>s in the Figma page (like a frame or section named &#8220;Examples&#8221;)</p></li><li><p><code>slotContentExamples</code> for each slot composition of content referenced in an <code>instanceExample</code> or embedded as default slot content in the component assets</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!1l-g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79e0391a-05ec-4064-bfe4-c5bf97022056_1010x1209.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!1l-g!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79e0391a-05ec-4064-bfe4-c5bf97022056_1010x1209.png 424w, /__u/substackcdn.com/image/fetch/$s_!1l-g!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79e0391a-05ec-4064-bfe4-c5bf97022056_1010x1209.png 848w, /__u/substackcdn.com/image/fetch/$s_!1l-g!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79e0391a-05ec-4064-bfe4-c5bf97022056_1010x1209.png 1272w, /__u/substackcdn.com/image/fetch/$s_!1l-g!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79e0391a-05ec-4064-bfe4-c5bf97022056_1010x1209.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!1l-g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79e0391a-05ec-4064-bfe4-c5bf97022056_1010x1209.png" width="1010" height="1209" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/79e0391a-05ec-4064-bfe4-c5bf97022056_1010x1209.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1209,&quot;width&quot;:1010,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:212682,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/199324016?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79e0391a-05ec-4064-bfe4-c5bf97022056_1010x1209.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!1l-g!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79e0391a-05ec-4064-bfe4-c5bf97022056_1010x1209.png 424w, /__u/substackcdn.com/image/fetch/$s_!1l-g!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79e0391a-05ec-4064-bfe4-c5bf97022056_1010x1209.png 848w, /__u/substackcdn.com/image/fetch/$s_!1l-g!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79e0391a-05ec-4064-bfe4-c5bf97022056_1010x1209.png 1272w, /__u/substackcdn.com/image/fetch/$s_!1l-g!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F79e0391a-05ec-4064-bfe4-c5bf97022056_1010x1209.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Alert data, including <code>instanceExamples</code> and <code>slotContentExamples</code></figcaption></figure></div><p>For now, we&#8217;re limited to using the instance layer name to connote a basic description and we&#8217;ll experiment with how to layer in guidance (do/don&#8217;t, must/should/could/avoid/never, etc.) as relevant.</p><h2>Example Intent and Guidance</h2><p>In the case of a <code>Row</code> component, the subtle shifts of structure and styling are evident across this gallery of seemingly similar variants. When you look closely, it&#8217;s clear that capturing all of these shifts as configurations is a fool&#8217;s errand. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!SgJ4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76565d8d-56f5-4141-b8ba-4348465e63dc_2122x1502.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!SgJ4!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76565d8d-56f5-4141-b8ba-4348465e63dc_2122x1502.png 424w, /__u/substackcdn.com/image/fetch/$s_!SgJ4!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76565d8d-56f5-4141-b8ba-4348465e63dc_2122x1502.png 848w, /__u/substackcdn.com/image/fetch/$s_!SgJ4!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76565d8d-56f5-4141-b8ba-4348465e63dc_2122x1502.png 1272w, /__u/substackcdn.com/image/fetch/$s_!SgJ4!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76565d8d-56f5-4141-b8ba-4348465e63dc_2122x1502.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!SgJ4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76565d8d-56f5-4141-b8ba-4348465e63dc_2122x1502.png" width="726.390625" height="514.3603944883242" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/76565d8d-56f5-4141-b8ba-4348465e63dc_2122x1502.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:1031,&quot;width&quot;:1456,&quot;resizeWidth&quot;:726.390625,&quot;bytes&quot;:575722,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/199324016?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76565d8d-56f5-4141-b8ba-4348465e63dc_2122x1502.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!SgJ4!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76565d8d-56f5-4141-b8ba-4348465e63dc_2122x1502.png 424w, /__u/substackcdn.com/image/fetch/$s_!SgJ4!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76565d8d-56f5-4141-b8ba-4348465e63dc_2122x1502.png 848w, /__u/substackcdn.com/image/fetch/$s_!SgJ4!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76565d8d-56f5-4141-b8ba-4348465e63dc_2122x1502.png 1272w, /__u/substackcdn.com/image/fetch/$s_!SgJ4!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76565d8d-56f5-4141-b8ba-4348465e63dc_2122x1502.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>All three areas &#8211; visuals, text, and actions &#8211; are wildly divergent.</p><ul><li><p><strong>Visuals</strong> may be square or round, image or avatar, and include or exclude a highlighting border.</p></li><li><p><strong>Text</strong> may include two or three lines, strategically included links and actions, formatted and highly structured data, and even a child highlight box (and that, with an image too!).</p></li><li><p><strong>Actions</strong> may include buttons or icon buttons, horizontal versus vertical displays, menus, one or many. Even the right corner can include plain text too!</p></li></ul><p>So as you craft examples, you&#8217;ll focus on expressing:</p><ul><li><p><strong>Structure</strong> of <code>elements</code> and <code>layout</code> that composition extends and bends</p></li><li><p><strong>Style</strong>, favoring formal, semantic tokens over hardcoded hexes and cheap, one-off spacer frames</p></li><li><p><strong>Content</strong> expressed as real data or structured labels like <code>{Title}</code> and <code>{Description}</code> that carry sufficient intent within clear boundaries that&#8217;s easy to swap. You&#8217;ll be the judge to leverage just enough specificity &#8211; such as <code>{Vacation package title}</code> &#8211; in examples to carry the intent needed to make evident your context, flexibility and intent.</p></li></ul><p>There&#8217;s just too much to control in any of those spaces. Examples, not component properties or component set variants, can be a place to record variation and guidance.</p><h2>Where Examples Can Break Down</h2><p>A place to author examples carries a certain gravity. Yet, System practitioners should remain cautious. You don&#8217;t want to slide towards challenges of composition ownership and maintenance. </p><p>Once people perceive the system as the place to store some compositions, they may perceive that it&#8217;s the place to store and govern all compositions. That is the wrong signal. Instead, you&#8217;re demonstrating potential, not an exhaustive catalogue. You also aren&#8217;t demonstrating limits, constraints, or final decisions around how to compose in a certain space. Just because you see rows depicted in this way in this location doesn&#8217;t mean that a new idea about a new row format isn&#8217;t suitable or can&#8217;t be done.</p><p>Additionally, more examples means a widened surface area of assets for the system to maintain. Examples help us compose customized style and rearrange elements in interesting ways. But those decisions can grow stale. As tokens and nested components change, so too must the examples that leverage them. As with all system assets, balance is needed.</p><p>Yet, tooling like <a href="https://directededges.github.io/specs/">Specs CLI</a> addresses the hard part. Examples are real instances that inherit token and component changes. Rerunning generators, linters and other tools as your versions change catch and often enable quick, direct resolution to limit the challenge altogether. </p><div><hr></div><p>Examples help us move past thinking of components as independent and narrow, configurable objects. Instead, they move us towards a language of space and structure and composition that can be machine readable. The composer&#8217;s freedom and potential is supported with a map with new types of reference points: drawn in Figma, carried as data, read by everyone and sustained as a growing corpus over time.</p>]]></content:encoded></item><item><title><![CDATA[Figma Component Specs on Command]]></title><description><![CDATA[An entire library. 1sec per component. 99%+ compressed. 100% of what Figma captures.]]></description><link>https://nathanacurtis.substack.com/p/figma-component-specs-on-command</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/figma-component-specs-on-command</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Mon, 20 Apr 2026 12:34:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!JMcE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4764c97-f393-41eb-8ecc-4a6acc1e937d_2800x1575.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!JMcE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4764c97-f393-41eb-8ecc-4a6acc1e937d_2800x1575.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!JMcE!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4764c97-f393-41eb-8ecc-4a6acc1e937d_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!JMcE!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4764c97-f393-41eb-8ecc-4a6acc1e937d_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!JMcE!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4764c97-f393-41eb-8ecc-4a6acc1e937d_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!JMcE!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4764c97-f393-41eb-8ecc-4a6acc1e937d_2800x1575.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!JMcE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4764c97-f393-41eb-8ecc-4a6acc1e937d_2800x1575.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b4764c97-f393-41eb-8ecc-4a6acc1e937d_2800x1575.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:91109,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/194785461?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4764c97-f393-41eb-8ecc-4a6acc1e937d_2800x1575.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!JMcE!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4764c97-f393-41eb-8ecc-4a6acc1e937d_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!JMcE!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4764c97-f393-41eb-8ecc-4a6acc1e937d_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!JMcE!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4764c97-f393-41eb-8ecc-4a6acc1e937d_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!JMcE!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4764c97-f393-41eb-8ecc-4a6acc1e937d_2800x1575.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When I watch an AI agent spend four minutes crawling a Figma file to answer a question I already knew the answer to, I get impatient. I get frustrated. Not because I&#8217;d memorized it &#8212; because the answer is <em>computable</em>. The agent was reading 45 variants, one by one, not even trying to infer which properties change across states. C&#8217;mon isn&#8217;t even an inference problem! It should be a diff!</p><p>To date we&#8217;ve worked like this: an engineer is assigned a component, opens a connection to a Figma file, pokes around, learns structure, infers decisions, and writes code. MCP is genuinely useful and fits this workflow well. It&#8217;s human-paced exploration now with an AI turboboost.</p><p>Yet, design system teams face two kinds of decisions. The hard kind &#8212; which components belong in the library, how to structure variant hierarchies, polishing up design intent, when to compose versus configure &#8212; require judgment, context, and experience. Our workflows necessarily involve inspection and reflection, inference and decision making. MCP tools help with that. Crafting code from Figma&#8217;s (partial) rendering of our intent can be similarly nuanced, and there are moments MCP can help there too.</p><p>But that moment in between &#8211; what we&#8217;ve called &#8220;handoff&#8221; that extracts a Button&#8217;s anatomy from 45 variants, diffs states, resolves token references &#8212; has no ambiguity at all. It&#8217;s mechanical, known, deterministic. The answers are in the data. And today&#8217;s agents seem happy to dawdle and lollygag around all that data over and over over, tokens be damned.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!eMq4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffadb0f62-9ad6-4844-9c79-75fcfc303202_1400x440.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!eMq4!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffadb0f62-9ad6-4844-9c79-75fcfc303202_1400x440.png 424w, /__u/substackcdn.com/image/fetch/$s_!eMq4!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffadb0f62-9ad6-4844-9c79-75fcfc303202_1400x440.png 848w, /__u/substackcdn.com/image/fetch/$s_!eMq4!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffadb0f62-9ad6-4844-9c79-75fcfc303202_1400x440.png 1272w, /__u/substackcdn.com/image/fetch/$s_!eMq4!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffadb0f62-9ad6-4844-9c79-75fcfc303202_1400x440.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!eMq4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffadb0f62-9ad6-4844-9c79-75fcfc303202_1400x440.png" width="1400" height="440" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fadb0f62-9ad6-4844-9c79-75fcfc303202_1400x440.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:440,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:32018,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/194785461?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffadb0f62-9ad6-4844-9c79-75fcfc303202_1400x440.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!eMq4!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffadb0f62-9ad6-4844-9c79-75fcfc303202_1400x440.png 424w, /__u/substackcdn.com/image/fetch/$s_!eMq4!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffadb0f62-9ad6-4844-9c79-75fcfc303202_1400x440.png 848w, /__u/substackcdn.com/image/fetch/$s_!eMq4!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffadb0f62-9ad6-4844-9c79-75fcfc303202_1400x440.png 1272w, /__u/substackcdn.com/image/fetch/$s_!eMq4!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffadb0f62-9ad6-4844-9c79-75fcfc303202_1400x440.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I see teams shaping a different model for tomorrow. Coding agents take a spec and generate types, structure, styling, behaviors, and accessibility in parallel, governed by rules and skills. Humans review this at gates rather than doing discovery themselves. As components change, the work is knowing what&#8217;s different and changing just that. That pipeline needs a pre-computed, durable, and comparable artifact.</p><p>I built a tool to generate specs mechanically, and design systems of enterprise scale are using this as a primary Figma-to-code input to agentically generate code. Sure, making decisions downstream remains the hard part. But extracting complete and compact specs from Figma should be a blazingly fast, repeatable activity. This post describes the problems I see, how to think mechanically about specs, the command line tool I built that my teams use, and examples of why it matters. </p><div><hr></div><h2>The Problem: <br>Raw Figma Data Is the Wrong Starting Point</h2><p>However you get it &#8212; MCP, REST API, plugin &#8212; raw Figma data has limitations when thrown to AI to generate components at scale.</p><h4>Figma data is expensive and ephemeral</h4><p>MCP fetches and processes vast payloads every time, throwing countless tokens to take it through its paces. Nothing persists. The work is disposable. The chat ends, the data dies, the memory largely flushed as attention diverts elsewhere.</p><h4>Figma data is a noisy dumping ground</h4><p>Data isn&#8217;t incomplete, it&#8217;s overloaded. 26,901 properties when you need ~350. Signal-to-noise ratio is abysmal. Plus, you get 45 full variant copies when what matters is 15 subtle differences between them, organized by simple rules that trigger each.</p><h4>Figma data isn&#8217;t clean</h4><p>Even library files have inconsistent naming, orphaned variants, dead variables, and experimental components mixed in. It&#8217;s messy in there. But that&#8217;s the job of the systems designer to clean that up, and MCP tools help to clean that up. It&#8217;s just that handoff isn&#8217;t the time to expose that. Just because we are using AI doesn&#8217;t mean letting our guard down.</p><h4>Figma data is unprocessed</h4><p>The raw data speaks Figma&#8217;s language: opaque IDs (<code>5641:6912</code>), float RGBA wrapped in solids, gradients and effects when a style already mapped to your design token will do. Hash-suffixed property names (<code>Label#3813:0</code>) when a prop binding reference can be set cleanly. </p><h4>Figma favors Figma</h4><p>Figma&#8217;s data model is Figma&#8217;s, not your platform&#8217;s. Figma says <code>paddingLeft</code> &#8212; but iOS needs <code>.padding(.leading)</code> and CSS needs <code>padding-inline-start</code>. Figma treats an icon glyph as a nested component instance, while code typically references SVG assets you color. Figma lacks a native model for ARIA roles and screen reader labels, but your components ship with each. A cross-platform spec needs to be neutral ground, not one tool&#8217;s more limited view. Your pipeline speaks token references using your formats, clean prop names, semantic anatomy. </p><p>Something somewhere has to translate. AI should be <strong>reading</strong>, not <strong>writing</strong>, these specs from Figma. As it turns out, all this requires is a scriptable algorithm.</p><div><hr></div><h2>The Right Tool for the Job: <br>Mechanical Transformation</h2><p>Figma&#8217;s data model is stable, incomplete and evolving slowly. Surely you&#8217;ll have &#8220;unstructured&#8221; and &#8220;less structured&#8221; specs to describe behaviors, motion, accessibility and more. But what it does cover, it covers cleanly.</p><p>Therefore, you can build tools to <a href="/__u/nathanacurtis.substack.com/p/analysis-of-variants-9e440c30b93e">derive rules-based decisions from variant data</a> using a dependable and durable algorithm. I want my design intent in an artifact that&#8217;s:</p><ul><li><p><strong>complete</strong>, such that every property of every layer of every variant is examined meticulously and every decision that matters is recorded</p></li><li><p><strong>compact</strong>, compressing data from MB to KB to remove 99% of the noise</p></li><li><p><strong>precise</strong>, with differences across variants reduced to simple, layered rules</p></li><li><p><strong>translated</strong> into a more platform-neutral language and using token, data, and file formats that work for you</p></li><li><p><strong>versioned</strong> so that as you evolve, it detects what&#8217;s changed since last time</p></li><li><p><strong>human-readable</strong>, that designers can scan and see intent, details and mistakes </p></li></ul><p>Specs must yield the same output given the same input, every time deterministically. This class of problem demands speed, not inference and improvisation. Never rely on a predictive model when you can count something directly. At this step in the process, you can count everything. If you can transform what is known faster, completely, precisely and far more compactly, then computation should win. Every time.</p><div><hr></div><h2>specs-cli:<br>Commands To Generate Your Specs For You</h2><p>The <code>specs-cli</code> available at <a href="https://github.com/DirectedEdges/specs">https://github.com/DirectedEdges/specs</a> requires four terminal commands. The two main commands &#8211; <code>fetch</code> and <code>generate</code> run cleanly and quickly in ~30 seconds per library each time you need specs. The other two are one-time setup tasks that take a few minutes and are covered in <a href="https://github.com/DirectedEdges/specs/blob/main/docs/cli/getting-started.md">getting started docs</a> &#8212; or you can paste a <a href="https://github.com/DirectedEdges/specs/blob/main/docs/cli/claude-onboarding.md">single line into Claude Code</a> and let Claude walk you through it.</p><p><code>## Install from npm<br>npm install -g @directededges/specs-cli</code></p><p><code>## Initialize and configure an environment (~1-2 min, one time)<br>specs init</code></p><p><code>## Fetch the Figma library file (5-15 seconds)<br>specs fetch</code></p><p><code>## Find and select components to generate (~1-2 min, one time)<br>specs scan</code></p><p><code>## Generates specs for an entire library file (10-30 seconds)<br>specs generate</code></p><p>In a few minutes, you have an entire, well-organized, compact specification of all the relevant design decisions you&#8217;ve put into <em>an entire library</em>. Need to refresh library data? Run <code>fetch</code> then <code>generate</code> again in less than a minute. Need to compare it against the last run? Ask AI, use Git to discern your changelog, or wait for tools I intend to build soon. Want to run it every week, day or hour using a Github action? Sure, however often you want.</p><p>Could AI do all this for you? Sure, but it&#8217;d take so so much longer, require so many tokens, and probably hallucinate in ways you can&#8217;t detect. Why do that?</p><h2>Examples: A Disabled Button and Action List with Subcomponents</h2><p>The proof? Imagine a button with 45 variations, 9 of which are disabled. The raw Figma data is <strong>1.38MB</strong> large, <strong>42,000+</strong> lines of JSON comprising <strong>280</strong> nodes and their <strong>26,000+</strong> properties. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!zX7k!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3904a-5a79-4cad-bbf8-0f989d6dc185_1634x973.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!zX7k!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3904a-5a79-4cad-bbf8-0f989d6dc185_1634x973.png 424w, /__u/substackcdn.com/image/fetch/$s_!zX7k!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3904a-5a79-4cad-bbf8-0f989d6dc185_1634x973.png 848w, /__u/substackcdn.com/image/fetch/$s_!zX7k!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3904a-5a79-4cad-bbf8-0f989d6dc185_1634x973.png 1272w, /__u/substackcdn.com/image/fetch/$s_!zX7k!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3904a-5a79-4cad-bbf8-0f989d6dc185_1634x973.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!zX7k!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3904a-5a79-4cad-bbf8-0f989d6dc185_1634x973.png" width="1456" height="867" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c7a3904a-5a79-4cad-bbf8-0f989d6dc185_1634x973.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:867,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:161172,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/194785461?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3904a-5a79-4cad-bbf8-0f989d6dc185_1634x973.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!zX7k!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3904a-5a79-4cad-bbf8-0f989d6dc185_1634x973.png 424w, /__u/substackcdn.com/image/fetch/$s_!zX7k!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3904a-5a79-4cad-bbf8-0f989d6dc185_1634x973.png 848w, /__u/substackcdn.com/image/fetch/$s_!zX7k!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3904a-5a79-4cad-bbf8-0f989d6dc185_1634x973.png 1272w, /__u/substackcdn.com/image/fetch/$s_!zX7k!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7a3904a-5a79-4cad-bbf8-0f989d6dc185_1634x973.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Process this with the specs-cli, and in about 1 second, and you are left with <strong>10 KB</strong>, <strong>442</strong> lines, <strong>4</strong> anatomy elements and <strong>15</strong> configurations that yield rules with design decisions. It&#8217;s <strong>99.25%</strong> less data, <strong>134:1</strong> compression into a well-organized schema.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!zGYQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa24873e9-de2e-47f9-bee6-5ddac131a46c_1213x763.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!zGYQ!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa24873e9-de2e-47f9-bee6-5ddac131a46c_1213x763.png 424w, /__u/substackcdn.com/image/fetch/$s_!zGYQ!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa24873e9-de2e-47f9-bee6-5ddac131a46c_1213x763.png 848w, /__u/substackcdn.com/image/fetch/$s_!zGYQ!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa24873e9-de2e-47f9-bee6-5ddac131a46c_1213x763.png 1272w, /__u/substackcdn.com/image/fetch/$s_!zGYQ!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa24873e9-de2e-47f9-bee6-5ddac131a46c_1213x763.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!zGYQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa24873e9-de2e-47f9-bee6-5ddac131a46c_1213x763.png" width="1213" height="763" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a24873e9-de2e-47f9-bee6-5ddac131a46c_1213x763.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:763,&quot;width&quot;:1213,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:157139,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/194785461?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa24873e9-de2e-47f9-bee6-5ddac131a46c_1213x763.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!zGYQ!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa24873e9-de2e-47f9-bee6-5ddac131a46c_1213x763.png 424w, /__u/substackcdn.com/image/fetch/$s_!zGYQ!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa24873e9-de2e-47f9-bee6-5ddac131a46c_1213x763.png 848w, /__u/substackcdn.com/image/fetch/$s_!zGYQ!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa24873e9-de2e-47f9-bee6-5ddac131a46c_1213x763.png 1272w, /__u/substackcdn.com/image/fetch/$s_!zGYQ!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa24873e9-de2e-47f9-bee6-5ddac131a46c_1213x763.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Button design specss, including anatomy, props, styling and variants</figcaption></figure></div><p>That spec is semantic anatomy, clean prop names, token references, diff-based variants, invalid variant analysis, structured metadata, and platform-neutral directions. Along the way, it discards bounding boxes, transforms, geometry paths, opaque IDs, duplicate variant copies, paint object wrappers, useless and exceedingly redundant information. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!N3fs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8010d8dc-c108-4da3-9429-8a46de4c35f6_774x506.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!N3fs!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8010d8dc-c108-4da3-9429-8a46de4c35f6_774x506.png 424w, /__u/substackcdn.com/image/fetch/$s_!N3fs!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8010d8dc-c108-4da3-9429-8a46de4c35f6_774x506.png 848w, /__u/substackcdn.com/image/fetch/$s_!N3fs!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8010d8dc-c108-4da3-9429-8a46de4c35f6_774x506.png 1272w, /__u/substackcdn.com/image/fetch/$s_!N3fs!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8010d8dc-c108-4da3-9429-8a46de4c35f6_774x506.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!N3fs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8010d8dc-c108-4da3-9429-8a46de4c35f6_774x506.png" width="774" height="506" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8010d8dc-c108-4da3-9429-8a46de4c35f6_774x506.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:506,&quot;width&quot;:774,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:34202,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/194785461?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8010d8dc-c108-4da3-9429-8a46de4c35f6_774x506.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!N3fs!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8010d8dc-c108-4da3-9429-8a46de4c35f6_774x506.png 424w, /__u/substackcdn.com/image/fetch/$s_!N3fs!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8010d8dc-c108-4da3-9429-8a46de4c35f6_774x506.png 848w, /__u/substackcdn.com/image/fetch/$s_!N3fs!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8010d8dc-c108-4da3-9429-8a46de4c35f6_774x506.png 1272w, /__u/substackcdn.com/image/fetch/$s_!N3fs!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8010d8dc-c108-4da3-9429-8a46de4c35f6_774x506.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A simple rule defining disabled&#8217;s opacity is much better than 250KB+ of raw data</figcaption></figure></div><p>AI doesn&#8217;t need 80 nodes with 30+ properties each when your design intent is &#8220;When the button is disabled, make the root layer 0.36 opacity.&#8221; A simple rule will suffice. And humans can read it too. Not that designers want to spend their time reading YAML. Yet, acclimating to the structure and scanning it quickly can yield small corrections to unexpected misses that polish the delivery.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!skOt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc400fe0a-26bb-4067-b5c1-616232ee6b07_1431x1031.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!skOt!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc400fe0a-26bb-4067-b5c1-616232ee6b07_1431x1031.png 424w, /__u/substackcdn.com/image/fetch/$s_!skOt!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc400fe0a-26bb-4067-b5c1-616232ee6b07_1431x1031.png 848w, /__u/substackcdn.com/image/fetch/$s_!skOt!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc400fe0a-26bb-4067-b5c1-616232ee6b07_1431x1031.png 1272w, /__u/substackcdn.com/image/fetch/$s_!skOt!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc400fe0a-26bb-4067-b5c1-616232ee6b07_1431x1031.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!skOt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc400fe0a-26bb-4067-b5c1-616232ee6b07_1431x1031.png" width="1431" height="1031" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c400fe0a-26bb-4067-b5c1-616232ee6b07_1431x1031.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1031,&quot;width&quot;:1431,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:158493,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/194785461?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc400fe0a-26bb-4067-b5c1-616232ee6b07_1431x1031.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!skOt!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc400fe0a-26bb-4067-b5c1-616232ee6b07_1431x1031.png 424w, /__u/substackcdn.com/image/fetch/$s_!skOt!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc400fe0a-26bb-4067-b5c1-616232ee6b07_1431x1031.png 848w, /__u/substackcdn.com/image/fetch/$s_!skOt!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc400fe0a-26bb-4067-b5c1-616232ee6b07_1431x1031.png 1272w, /__u/substackcdn.com/image/fetch/$s_!skOt!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc400fe0a-26bb-4067-b5c1-616232ee6b07_1431x1031.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Action list with subcomponents for item, group, header and group header</figcaption></figure></div><p>Do you think the Button example flatters this approach, but remain unconvinced? More complicated components with a bevy of subcomponents result in **even more** compression. The Action List, with its subcomponents for items, headers, groups and group headers, resulted in a <strong>2.6MB &#8594; 14KB</strong> (<strong>188:1</strong> compression, <strong>99.47%</strong> reduction), and yet included even more that Figma doesn&#8217;t like conditional visibility, code only props and invalid combination mappings. </p><p>Where was AI this time? At most, running your commands, although you can do this without AI and use zero tokens. AI belongs in this pipeline: *downstream*, not necessarily to generate specs. A mechanical engine can produces a durable, precise artifact; AI agents can consume it to generate code, answer questions, build components.</p><h2>Extending and Moving Beyond Components</h2><p>There are clear places where the specs tools will need to grow in the short term. Capturing slot content and instance examples is imminent. VPs are demanding refined motion and behaviors, yet nobody uses Figma for that. From there, questions about how to capture and relate deeper behavior (usually reserved for code) and accessibility persist.</p><p>At the same time, the tools are already in use at clients, and more than one see git versioning as insufficient. I would anticipate building in versioning capabilities that  include automated changesets, changelogs and classification of major, minor and patch changes.</p><p>Leadership, however, has already moved their attention to other things. Components seem like well understood territory, but AI&#8217;s pattern recognition and speed of automation has them clearly desiring to go up the chain to layout patterns, scaffolds, and full page compositions. Not just what they are but also when to use and relate and compose each one. I cannot imagine how fast these things will change or look in months let alone years.</p>]]></content:encoded></item><item><title><![CDATA[Implementing Slots in a Figma Library]]></title><description><![CDATA[Go beyond "Swap swaps" to explore, decide on and implement slot patterns]]></description><link>https://nathanacurtis.substack.com/p/implementing-slots-in-a-figma-library</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/implementing-slots-in-a-figma-library</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Mon, 02 Mar 2026 17:29:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qPUg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf192482-56fe-4b51-ba46-fda9e7866472_2800x1575.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!qPUg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf192482-56fe-4b51-ba46-fda9e7866472_2800x1575.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!qPUg!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf192482-56fe-4b51-ba46-fda9e7866472_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!qPUg!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf192482-56fe-4b51-ba46-fda9e7866472_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!qPUg!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf192482-56fe-4b51-ba46-fda9e7866472_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!qPUg!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf192482-56fe-4b51-ba46-fda9e7866472_2800x1575.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!qPUg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf192482-56fe-4b51-ba46-fda9e7866472_2800x1575.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bf192482-56fe-4b51-ba46-fda9e7866472_2800x1575.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:131855,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/189671784?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf192482-56fe-4b51-ba46-fda9e7866472_2800x1575.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!qPUg!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf192482-56fe-4b51-ba46-fda9e7866472_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!qPUg!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf192482-56fe-4b51-ba46-fda9e7866472_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!qPUg!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf192482-56fe-4b51-ba46-fda9e7866472_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!qPUg!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbf192482-56fe-4b51-ba46-fda9e7866472_2800x1575.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Figma&#8217;s native slots promise a more flexible and easily composable future for design libraries. System owners are eager to transform their components, often with the expectation of a simple, one-to-one swap of existing slot utility instances for the new slot layers.</p><p>&#8220;I can&#8217;t wait. Our components will be delightfully easier to use.&#8221; True</p><p>&#8220;Figma&#8217;s native slot layers are simple to set up.&#8221; Also true.</p><p>&#8220;Just swap slot utilities for slot layers!&#8221; Hold up a minute. That&#8217;s not quite right.</p><p>A transition to native slots should reach further than replacing your slot utility asset. Migrating to Figma&#8217;s slots should force system architects to critically look at how components are composed and customized.</p><p>This post describes the journey of implementing native slots in a Figma library, from discovery with exploration through deciding your patterns and implementing them across the catalog.</p><div><hr></div><h2><strong>Discovery</strong></h2><p>Don&#8217;t expect to just open a Figma library branch, rapidly change a bunch of components and hit publish. Migrating a library to slots with deliberate care can be informed by discovery activities like a library audit, research, and synthesis to identify patterns.</p><h3><strong>Audit</strong></h3><p>Start by auditing your existing Figma assets. Begin with already-composable components that may include slot utility instances, but don&#8217;t stop there. My audit included any component or subcomponent asset, and I catalogued each component with:</p><ul><li><p><strong>Name</strong>, like <code>Button</code> or <code>Pill / Start Visual</code>.</p></li><li><p><strong>Role</strong> in the composition, such as <code>Root</code> / the &#8220;Main Component&#8221; versus its <code>Header</code>, <code>Body</code>, <code>Footer</code>, <code>Actions</code>, <code>Start</code> Element, <code>End</code> Element, or Other purpose</p></li><li><p><strong>Slot utility?</strong>, indicating if it has a slot utility bound to an instance swap prop.</p></li><li><p><strong>Slot utility as variant option?</strong>, if the slot utility is available in some variants but not others. For example, a <code>Content</code> prop with options for <code>Icon</code>, <code>Mark</code>, <code>Avatar</code>, and <code>Slot</code> option (that shows a slot utility).</p></li><li><p><strong>Composable nested instances?</strong>, if any nested instance had a slot utility in it. For example, a <code>Button</code> that has an <code>End Visual</code> with a slot utility option.</p></li><li><p><strong>Props</strong> (all types) to determine which variant, text, and boolean configurations will be kept, changed or removed.</p></li></ul><p>I found myself sorting component props that I expected to keep versus those to consider more deeply or expect to remove (at least some instance swap props, obviously!).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!hMvw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78dcf710-23e0-47cf-8160-814fb98af060_1400x946.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!hMvw!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78dcf710-23e0-47cf-8160-814fb98af060_1400x946.png 424w, /__u/substackcdn.com/image/fetch/$s_!hMvw!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78dcf710-23e0-47cf-8160-814fb98af060_1400x946.png 848w, /__u/substackcdn.com/image/fetch/$s_!hMvw!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78dcf710-23e0-47cf-8160-814fb98af060_1400x946.png 1272w, /__u/substackcdn.com/image/fetch/$s_!hMvw!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78dcf710-23e0-47cf-8160-814fb98af060_1400x946.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!hMvw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78dcf710-23e0-47cf-8160-814fb98af060_1400x946.png" width="1400" height="946" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/78dcf710-23e0-47cf-8160-814fb98af060_1400x946.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:946,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:288464,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/189671784?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78dcf710-23e0-47cf-8160-814fb98af060_1400x946.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!hMvw!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78dcf710-23e0-47cf-8160-814fb98af060_1400x946.png 424w, /__u/substackcdn.com/image/fetch/$s_!hMvw!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78dcf710-23e0-47cf-8160-814fb98af060_1400x946.png 848w, /__u/substackcdn.com/image/fetch/$s_!hMvw!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78dcf710-23e0-47cf-8160-814fb98af060_1400x946.png 1272w, /__u/substackcdn.com/image/fetch/$s_!hMvw!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F78dcf710-23e0-47cf-8160-814fb98af060_1400x946.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Component slot audit, including component props</figcaption></figure></div><p>In hindsight, I would structure the data I collected (and the decisions to come) in the format of this <a href="https://docs.google.com/spreadsheets/d/1creGsbaqWyYbMa8jH6DFKv6DlbWlkQebUB7LPsH7kok/edit?usp=sharing">Slots Audit Google Sheet</a>. It boils down what can feel like myriad different cases and examples into the kinds of patterns and decisions to plan around.</p><div><hr></div><h3><strong>Comparative research</strong></h3><p>The migration&#8217;s intended to balance incorporating legacy code patterns with  adopting a modern, composable shape. While working through Figma assets, I also researched both:</p><ul><li><p>Compare against and align with <strong>existing code implementations</strong>, across platforms as needed and ideally via LLM prompts and agents</p></li><li><p>Gain inspiration from <strong>public libraries with strong compositional qualities</strong>, like Github Primer and MUI React.</p></li></ul><div><hr></div><h3><strong>Exploration</strong></h3><p>Before making decisions, I dug in and experimented with many approaches within and across components. I varied many aspected of the architecture like where props were exposed, where elements were included, how content was available by default, and how to name each slot. This led to an array of working examples to workshop with the team.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!RL1-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ac73370-1075-4580-b779-950c14eef9c5_1653x718.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!RL1-!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ac73370-1075-4580-b779-950c14eef9c5_1653x718.png 424w, /__u/substackcdn.com/image/fetch/$s_!RL1-!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ac73370-1075-4580-b779-950c14eef9c5_1653x718.png 848w, /__u/substackcdn.com/image/fetch/$s_!RL1-!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ac73370-1075-4580-b779-950c14eef9c5_1653x718.png 1272w, /__u/substackcdn.com/image/fetch/$s_!RL1-!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ac73370-1075-4580-b779-950c14eef9c5_1653x718.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!RL1-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ac73370-1075-4580-b779-950c14eef9c5_1653x718.png" width="1456" height="632" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2ac73370-1075-4580-b779-950c14eef9c5_1653x718.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:632,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:52876,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/189671784?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ac73370-1075-4580-b779-950c14eef9c5_1653x718.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!RL1-!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ac73370-1075-4580-b779-950c14eef9c5_1653x718.png 424w, /__u/substackcdn.com/image/fetch/$s_!RL1-!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ac73370-1075-4580-b779-950c14eef9c5_1653x718.png 848w, /__u/substackcdn.com/image/fetch/$s_!RL1-!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ac73370-1075-4580-b779-950c14eef9c5_1653x718.png 1272w, /__u/substackcdn.com/image/fetch/$s_!RL1-!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ac73370-1075-4580-b779-950c14eef9c5_1653x718.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Explorations file format for slot patterns with examples and alternative approaches</figcaption></figure></div><p>I prepared a Figma file with sections per pattern, establishing dedicated zones for:</p><ul><li><p><strong>Examples</strong> established the pattern&#8217;s relevance. For example, the <a href="/__u/nathanacurtis.substack.com/p/figma-slots-for-repeating-items">Group and repeating items</a> pattern included <code>Checkbox Group</code>, <code>Tabs</code>, <code>Radio Buttons</code>, <code>Breadcrumbs</code>, <code>Action List</code> and <code>Avatar Group</code>. I annotated each likely slot area in magenta.</p></li><li><p><strong>Alternatives</strong> distinguished choices around component hierarchy, layer structure, props, slot layer depth, and slot default content.</p></li></ul><p>In the periphery, I tracked:</p><ul><li><p><strong>Open questions</strong> in the form of voting dots and rationale.</p></li><li><p><strong>Architecture</strong> decisions addressing conventions of slots, props and layout. If I felt strongly, I recommended a decision as a starting point.</p></li></ul><p>This enabled me to learn by building and thinking through how to communicate distinctions per slot model.  As we worked through options and examples, we riffed and made decisions.</p><div><hr></div><h2><strong>Decisions</strong></h2><p>It may <em>feel</em> like you are just working through components (<code>Checkbox Group</code>, <code>Card</code>, <code>Button</code>), but the reality is that you are defining <strong>rules and standards</strong> to apply across your entire catalog as core patterns.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!h80g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f7529e-7234-44da-b11a-06f7a7fe7926_1400x490.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!h80g!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f7529e-7234-44da-b11a-06f7a7fe7926_1400x490.png 424w, /__u/substackcdn.com/image/fetch/$s_!h80g!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f7529e-7234-44da-b11a-06f7a7fe7926_1400x490.png 848w, /__u/substackcdn.com/image/fetch/$s_!h80g!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f7529e-7234-44da-b11a-06f7a7fe7926_1400x490.png 1272w, /__u/substackcdn.com/image/fetch/$s_!h80g!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f7529e-7234-44da-b11a-06f7a7fe7926_1400x490.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!h80g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f7529e-7234-44da-b11a-06f7a7fe7926_1400x490.png" width="1400" height="490" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a4f7529e-7234-44da-b11a-06f7a7fe7926_1400x490.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:490,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:185922,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/189671784?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f7529e-7234-44da-b11a-06f7a7fe7926_1400x490.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!h80g!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f7529e-7234-44da-b11a-06f7a7fe7926_1400x490.png 424w, /__u/substackcdn.com/image/fetch/$s_!h80g!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f7529e-7234-44da-b11a-06f7a7fe7926_1400x490.png 848w, /__u/substackcdn.com/image/fetch/$s_!h80g!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f7529e-7234-44da-b11a-06f7a7fe7926_1400x490.png 1272w, /__u/substackcdn.com/image/fetch/$s_!h80g!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4f7529e-7234-44da-b11a-06f7a7fe7926_1400x490.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Sheet, shifted from audit to decisions focus</figcaption></figure></div><p>The spreadsheet started with the audit serves as a structured way to record and plan implementation of your slot approach, props, and layout as you refactor each and align them with code.</p><div><hr></div><h3><strong>Slot approach</strong></h3><p>As decisions gave way to patterns, we ultimately decided on an <strong>approach</strong>. Each component or subcomponent was either EOL&#8217;ed (deleted) or kept with a slot architecture of:</p><ul><li><p>Slot, empty default</p></li><li><p>Slot, with default content</p></li><li><p>Configuration-first (props bound to layers, but no slot), &#8220;Custom&#8221; escape hatch (a slot with layers not bound to props)</p></li><li><p>Named slot, always visible</p></li><li><p>Named slot with visibility prop</p></li><li><p>Items slot</p></li><li><p>Subcomponent, no slot</p></li><li><p>Subcomponent with slot</p></li><li><p>No slot</p></li></ul><div><hr></div><h3><strong>Slot properties</strong></h3><p>Slot property conventions are straightforward yet require agreement:</p><ul><li><p><strong>Name</strong> of both &#8220;default&#8221; slots (like <code>children</code> or <code>items</code>) and other named slots if needed</p></li><li><p><strong>Default content</strong>, whether <code>none</code>, <code>uniform</code>, or <code>varying</code> across variants</p></li><li><p><strong>Permissiveness</strong>, whether closed (to a strict set of <code>anyOf</code> children) or open (to set <code>preferred values</code>) as well as <code>minItems</code> and <code>maxItems</code><strong> </strong>as relevant.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!QW38!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee885bcc-202a-4264-a687-6c430afbb228_1400x490.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!QW38!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee885bcc-202a-4264-a687-6c430afbb228_1400x490.png 424w, /__u/substackcdn.com/image/fetch/$s_!QW38!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee885bcc-202a-4264-a687-6c430afbb228_1400x490.png 848w, /__u/substackcdn.com/image/fetch/$s_!QW38!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee885bcc-202a-4264-a687-6c430afbb228_1400x490.png 1272w, /__u/substackcdn.com/image/fetch/$s_!QW38!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee885bcc-202a-4264-a687-6c430afbb228_1400x490.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!QW38!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee885bcc-202a-4264-a687-6c430afbb228_1400x490.png" width="1400" height="490" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ee885bcc-202a-4264-a687-6c430afbb228_1400x490.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:490,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:133061,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/189671784?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee885bcc-202a-4264-a687-6c430afbb228_1400x490.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!QW38!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee885bcc-202a-4264-a687-6c430afbb228_1400x490.png 424w, /__u/substackcdn.com/image/fetch/$s_!QW38!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee885bcc-202a-4264-a687-6c430afbb228_1400x490.png 848w, /__u/substackcdn.com/image/fetch/$s_!QW38!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee885bcc-202a-4264-a687-6c430afbb228_1400x490.png 1272w, /__u/substackcdn.com/image/fetch/$s_!QW38!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee885bcc-202a-4264-a687-6c430afbb228_1400x490.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Slot props per component, such as name and default content</figcaption></figure></div><div><hr></div><h3><strong>Slot layout</strong></h3><p>I recommend avoiding setting visual styles of slots like color, corners, and strokes. However, it&#8217;s practical to set layout properties like direction, resizing and item spacing and work out with development how those do or don&#8217;t impact code implementation.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!TzE1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabf720eb-fb94-4674-b287-e809654e7aee_1400x576.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!TzE1!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabf720eb-fb94-4674-b287-e809654e7aee_1400x576.png 424w, /__u/substackcdn.com/image/fetch/$s_!TzE1!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabf720eb-fb94-4674-b287-e809654e7aee_1400x576.png 848w, /__u/substackcdn.com/image/fetch/$s_!TzE1!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabf720eb-fb94-4674-b287-e809654e7aee_1400x576.png 1272w, /__u/substackcdn.com/image/fetch/$s_!TzE1!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabf720eb-fb94-4674-b287-e809654e7aee_1400x576.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!TzE1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabf720eb-fb94-4674-b287-e809654e7aee_1400x576.png" width="1400" height="576" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/abf720eb-fb94-4674-b287-e809654e7aee_1400x576.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:576,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:163674,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/189671784?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabf720eb-fb94-4674-b287-e809654e7aee_1400x576.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!TzE1!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabf720eb-fb94-4674-b287-e809654e7aee_1400x576.png 424w, /__u/substackcdn.com/image/fetch/$s_!TzE1!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabf720eb-fb94-4674-b287-e809654e7aee_1400x576.png 848w, /__u/substackcdn.com/image/fetch/$s_!TzE1!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabf720eb-fb94-4674-b287-e809654e7aee_1400x576.png 1272w, /__u/substackcdn.com/image/fetch/$s_!TzE1!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fabf720eb-fb94-4674-b287-e809654e7aee_1400x576.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Slot layout per component, such as item spacing and resizing</figcaption></figure></div><p><strong>Prohibit padding on the slot layer</strong>. A component should not control the inset of its slot. If internal <code>padding</code> is required, nest the slot within a containing frame and apply padding there.</p><p><strong>Empty slot sizing.</strong> In cases like <code>Card</code> and <code>Modal</code>, slots could be empty by default. Empty slots will retain a customized fixed height and width if needed. Discuss if and how to set the slot&#8217;s default height or width, likely to a typical expected size.</p><div><hr></div><h3><strong>Refactored props and subcomponents</strong></h3><p>The transition to composable native slots forces a look at every component, both for its own internals as well as its relationships with other components. This leads to refactoring, and I expect slots to result in a <a href="/__u/nathanacurtis.substack.com/p/configuration-collapse">configuration collapse</a> described in a recent, separate post. Composition, not configuration, becomes the preferred approach to solve many problems.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!zetA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34bc5dfb-9477-4f39-b451-a92650008dad_1400x1354.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!zetA!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34bc5dfb-9477-4f39-b451-a92650008dad_1400x1354.png 424w, /__u/substackcdn.com/image/fetch/$s_!zetA!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34bc5dfb-9477-4f39-b451-a92650008dad_1400x1354.png 848w, /__u/substackcdn.com/image/fetch/$s_!zetA!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34bc5dfb-9477-4f39-b451-a92650008dad_1400x1354.png 1272w, /__u/substackcdn.com/image/fetch/$s_!zetA!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34bc5dfb-9477-4f39-b451-a92650008dad_1400x1354.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!zetA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34bc5dfb-9477-4f39-b451-a92650008dad_1400x1354.png" width="1400" height="1354" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/34bc5dfb-9477-4f39-b451-a92650008dad_1400x1354.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1354,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:250530,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/189671784?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34bc5dfb-9477-4f39-b451-a92650008dad_1400x1354.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!zetA!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34bc5dfb-9477-4f39-b451-a92650008dad_1400x1354.png 424w, /__u/substackcdn.com/image/fetch/$s_!zetA!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34bc5dfb-9477-4f39-b451-a92650008dad_1400x1354.png 848w, /__u/substackcdn.com/image/fetch/$s_!zetA!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34bc5dfb-9477-4f39-b451-a92650008dad_1400x1354.png 1272w, /__u/substackcdn.com/image/fetch/$s_!zetA!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34bc5dfb-9477-4f39-b451-a92650008dad_1400x1354.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Decisions to keep or remove existing Figma component props</figcaption></figure></div><div><hr></div><h3><strong>Relating design assets and code architecture</strong></h3><p>In addition, consider a method to distinguish props that are &#8220;Figma helpers&#8221; that may not belong on a composable component&#8217;s code API.</p><p>For example, a <code>Custom</code> (false|true) prop that activates the slot for composability, and the bound label, description and visibility props presented to designers by default as the more common configurable case. This separates the bound label, description, and visibility props&#8212;presented for the common configurable case&#8212;from the asset&#8217;s <code>Custom</code> appearances, which define its true, composable API.</p><p>In the spreadsheet, I distinguish these using the *. In our tooling, that&#8217;s transformed when converting Figma assets to specification data.</p><div><hr></div><h2><strong>Implementation</strong></h2><p>Equipped with implementation patterns and confident decisions, it&#8217;s time to plan and convert a library, from low- to high-order components, one at a time.</p><p>Notable characteristics of my implementation plan included:</p><ul><li><p>One branch per component.</p></li><li><p>Convert components of the same pattern (such as <a href="https://docs.google.com/spreadsheets/d/1creGsbaqWyYbMa8jH6DFKv6DlbWlkQebUB7LPsH7kok/edit?usp=sharing">groups with repeating items</a>) simultaneously as a batch. That way, you can  implement, review, and adjust across branches as decisions evolve.</p></li><li><p>Leave more deeply nested component structures for later, like <code>Alert</code> (with its e, <code>Text</code> and <code>Actions</code>) and <code>Action List</code> (with its <code>Item</code>, <code>Start Visual</code>, <code>Text</code>, and <code>End Visual</code>). This offers space to sit with the more complicated architecture for a bit as people adapt to the easier stuff.</p></li><li><p>Test slots using ready-made examples built beside the component assets. Early on, they are more test cases than published examples, even if they should represent acceptable cases by the time you publish.</p></li><li><p>Pilot and get feedback on many things before publishing all the things.</p></li></ul><p>Equipped with a plan, the conversion is a structured, component-by-component process of applying new conventions to a library that&#8217;s robust, tested, and ready for adoption.</p>]]></content:encoded></item><item><title><![CDATA[Configuration Collapse]]></title><description><![CDATA[As Figma Slots Push Composability, Be Ready to Drop Props]]></description><link>https://nathanacurtis.substack.com/p/configuration-collapse</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/configuration-collapse</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Fri, 27 Feb 2026 12:48:23 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qwtU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafcbe9a0-cc54-4548-8906-4d7f5ff2c10a_2800x1575.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!qwtU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafcbe9a0-cc54-4548-8906-4d7f5ff2c10a_2800x1575.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!qwtU!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafcbe9a0-cc54-4548-8906-4d7f5ff2c10a_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!qwtU!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafcbe9a0-cc54-4548-8906-4d7f5ff2c10a_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!qwtU!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafcbe9a0-cc54-4548-8906-4d7f5ff2c10a_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!qwtU!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafcbe9a0-cc54-4548-8906-4d7f5ff2c10a_2800x1575.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!qwtU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafcbe9a0-cc54-4548-8906-4d7f5ff2c10a_2800x1575.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/afcbe9a0-cc54-4548-8906-4d7f5ff2c10a_2800x1575.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:126603,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/189354553?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafcbe9a0-cc54-4548-8906-4d7f5ff2c10a_2800x1575.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!qwtU!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafcbe9a0-cc54-4548-8906-4d7f5ff2c10a_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!qwtU!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafcbe9a0-cc54-4548-8906-4d7f5ff2c10a_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!qwtU!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafcbe9a0-cc54-4548-8906-4d7f5ff2c10a_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!qwtU!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fafcbe9a0-cc54-4548-8906-4d7f5ff2c10a_2800x1575.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Glance at the Props panel of a mature Figma component, and you risk encountering a scrollbar of shame. Countless props fine tuning element visibility (like <code>showIcon</code>) and layout (horizontal or vertical <code>direction</code>). Each solves for a real yet specific case, added with the best of intentions.</p><p>Yet together, those &#8220;helpful&#8221; and enabling props sprawl into a paradox of configurable choice. When component variant counts explode or a simple change breaks an inherited style, it&#8217;s not because the design system is flawed&#8212;it&#8217;s because it&#8217;s using the wrong tool. The system further burdens itself to document, test, and maintain more features, locking it in a box of its own making.</p><p>A single, rigid component need not solve all things for all people.</p><p>Figma&#8217;s native slots are coming for your configurable props, and will tear many of them down. System power should come from not switches and variants, but by allowing for creative, unconstrained composition. This will demand a bold act: a configuration collapse to drop props that make components fragile.</p><p>This article explores this shift by moving our prop-first mindset to purer composability, with examples of the <code>Pill</code>, <code>Alert</code> and <code>Card</code>.</p><h2><strong>A Leaner Component Core</strong></h2><p>Shifting towards composability must leave the component&#8217;s identity untouched, retaining only behavioral and foundational visual props&#8212;such as <code>state</code>, <code>appearance</code>, and <code>size</code>&#8212;as the component&#8217;s essential, top-level API.</p><p>Yet many other props types and subcomponents are at risk, like:</p><ul><li><p><strong>Layout</strong> props for <code>padding</code>, <code>direction</code>, and <code>resizing</code> are removed.</p></li><li><p><strong>Visibility</strong> props (Figma BOOLEAN props like <code>showIcon</code>, <code>hideDescription</code>, <code>actionsVisible</code>) declined severely in favor of controlling element presence and visibility via slot composition.</p></li><li><p><strong>Visual hack</strong> props declined, particularly those impacting single visual choices (e.g., color, corner radius, or border) of a nested layer.</p></li><li><p><strong>Subcomponents</strong> for varying layout and element structure were eliminated entirely (see the <code>Alert</code> &gt; <code>Body</code> &gt; <code>Text</code> example below).</p></li><li><p><strong>Configuration shifts</strong> removed complex props (<code>actionsVisible</code>, <code>actionsCount</code>) in favor of a dedicated, simpler subcomponent that&#8217;s slotted into the main component with potential constraints.</p></li></ul><p>Decoupled <strong>visual styling of composed children</strong> (e.g., the text color of a <code>Button Label</code> or a <code>Card Title</code>) is an undesirable but necessary trade-off. These relationships have efficient, effective controls in code, but become the composer&#8217;s responsibility in Figma. Use strong, variant-specific defaults and rich examples to mitigate this challenge.</p><p>The immediate effect is <strong>leaner component APIs</strong>. In the long-term, teams and systems across the enterprise can better extend, build around, and build within core components without conflict and delay.</p><h2><strong>Why Now? AI-Ready Components</strong></h2><p>Design systems have been built for composability for some time. Systems have been putting the right props at the right levels of the right components. Putting things together feels right&#8230; in code. But not in design tools. And certainly not in design tools increasingly manipulated by AI.</p><p><strong>Because Figma can compose in components now</strong><br>So the easy answer is: because designers couldn&#8217;t do this before with Figma. Native slots &#8211; or more abstractly, composition within a component asset &#8211; was too difficult and clunky to replicate, so Figma&#8217;s architecture was different.</p><p>I think Figma prioritizing building slots in 2025 is neither because slot utility instance swapping sucks (it has for years) nor that slots just happened to be next on the roadmap. I speculate that slots are a priority because machines now compose interfaces and Figma needs customer&#8217;s assets ready for the challenge.</p><p><strong>Component composition is grammar</strong><br>In a prop-heavy system, element relationships are implicit and bound to prop combinations that are arbitrary and often quite uncommon. With composition, relationships become explicit: a <code>Pill</code> is composed of an <code>Icon</code> and text <code>Label</code> inside it, each with important yet contextual configurations of their own. This creates structure that AI can read, understand, and generate.</p><p><strong>Favor predictable patterns over hyper-configuration</strong><br>Also, a reduced configurable shape improves predictability. Figma boolean and layout variant props feel arbitrary and don&#8217;t cover all possible needs anyway. Instead, systems should supply AI with training data that records relationships in other ways, such as ready-made examples augmented with guidance. Models could perform better with fewer yet higher-confidence patterns rather than spinning on copious, hyper-specific configuration states.</p><p><strong>Layer semantics over flexible building blocks</strong><br>Figma&#8217;s slot composition also opens up opportunities to build purpose-driven components (like a <code>ProductCard</code> with opinionated structure and layouts) by wrapping a composable <code>Card</code> container starting point. This more effectively separates concerns, affords extensibility, and improves autonomy.</p><p>The takeaway shouldn&#8217;t be to &#8220;Drop all the props.&#8221; Instead, it&#8217;s about finding the right balance. It&#8217;s still essential to offer the right configurable choices at the right level without necessarily rigidly controlling what&#8217;s inside.</p><div class="pullquote"><p>Make the common configurable, make the uncommon composable</p></div><p>Moreso, it&#8217;s about tearing away the structural noise from our configurable surface. Now&#8217;s the time to put compositional choices in the hands of the composer, scaffolded with starting points and guided by rich examples and context</p><h2><strong>Examples</strong></h2><h3><strong>Start and End Visuals</strong></h3><p>Many more atomic components like <code>Pill</code>, <code>Badge</code>, <code>Chip</code>, <code>Tab</code>, <code>Link</code>, and <code>Button</code> have <code>Start</code> and/or <code>End</code> visuals on either side of a label. In the past, to control for a set of expected visual types (like an <code>Icon</code>, <code>Mark</code>, <code>Image</code> or <code>Avatar</code>), we&#8217;d use a component or subcomponent variant prop.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!G1BP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b852e20-a20c-4f9e-8665-a963f9600b20_1400x702.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!G1BP!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b852e20-a20c-4f9e-8665-a963f9600b20_1400x702.png 424w, /__u/substackcdn.com/image/fetch/$s_!G1BP!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b852e20-a20c-4f9e-8665-a963f9600b20_1400x702.png 848w, /__u/substackcdn.com/image/fetch/$s_!G1BP!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b852e20-a20c-4f9e-8665-a963f9600b20_1400x702.png 1272w, /__u/substackcdn.com/image/fetch/$s_!G1BP!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b852e20-a20c-4f9e-8665-a963f9600b20_1400x702.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!G1BP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b852e20-a20c-4f9e-8665-a963f9600b20_1400x702.png" width="1400" height="702" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9b852e20-a20c-4f9e-8665-a963f9600b20_1400x702.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:702,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!G1BP!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b852e20-a20c-4f9e-8665-a963f9600b20_1400x702.png 424w, /__u/substackcdn.com/image/fetch/$s_!G1BP!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b852e20-a20c-4f9e-8665-a963f9600b20_1400x702.png 848w, /__u/substackcdn.com/image/fetch/$s_!G1BP!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b852e20-a20c-4f9e-8665-a963f9600b20_1400x702.png 1272w, /__u/substackcdn.com/image/fetch/$s_!G1BP!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b852e20-a20c-4f9e-8665-a963f9600b20_1400x702.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Pill layer structure before and after slot migration</figcaption></figure></div><p>With native slots, favor flexibility and ease over control. Nesting text and paired visuals (either hidden or visible by default) in a <code>children</code> slot.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!2Qiq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb27dd0f0-2c81-4c61-a2f9-01af98796453_1400x1110.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!2Qiq!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb27dd0f0-2c81-4c61-a2f9-01af98796453_1400x1110.png 424w, /__u/substackcdn.com/image/fetch/$s_!2Qiq!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb27dd0f0-2c81-4c61-a2f9-01af98796453_1400x1110.png 848w, /__u/substackcdn.com/image/fetch/$s_!2Qiq!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb27dd0f0-2c81-4c61-a2f9-01af98796453_1400x1110.png 1272w, /__u/substackcdn.com/image/fetch/$s_!2Qiq!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb27dd0f0-2c81-4c61-a2f9-01af98796453_1400x1110.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!2Qiq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb27dd0f0-2c81-4c61-a2f9-01af98796453_1400x1110.png" width="1400" height="1110" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b27dd0f0-2c81-4c61-a2f9-01af98796453_1400x1110.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1110,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!2Qiq!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb27dd0f0-2c81-4c61-a2f9-01af98796453_1400x1110.png 424w, /__u/substackcdn.com/image/fetch/$s_!2Qiq!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb27dd0f0-2c81-4c61-a2f9-01af98796453_1400x1110.png 848w, /__u/substackcdn.com/image/fetch/$s_!2Qiq!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb27dd0f0-2c81-4c61-a2f9-01af98796453_1400x1110.png 1272w, /__u/substackcdn.com/image/fetch/$s_!2Qiq!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb27dd0f0-2c81-4c61-a2f9-01af98796453_1400x1110.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Pill configuration before and after slot migration</figcaption></figure></div><p>This resulted in a near complete collapse of some component&#8217;s props, including:</p><ul><li><p>All visibility props (<code>Start Visual Visible</code>, <code>End Visual Visible</code>)</p></li><li><p>Type variant props</p></li><li><p><code>Padding</code> variants that controlled spacing between a label and visual, omitted in favor of a composer implementing that choice.</p></li></ul><p><code>Icon</code> is a predominant default visual. Certainly, adding it as a slot &#8220;Preferred Value&#8221; is a start. However, inserting it results in a likely <code>Icon</code> configuration mismatch. Alternatively, it could be included by slot, whether shown or hidden by default.  That way, the <code>Icon</code> can be configured to match the parent state, such as <code>Pill</code> <code>selected</code>&#8216;s impact on <code>Icon</code>&#8216;s <code>appearance</code>.</p><p>The need to control was rare but did arise, such as <code>Button / Start Visual</code>. This strongly typed subcomponent reinforced expected use, even if it could be omitted and a different element included just in case.</p><h3><strong>Body, Text and Actions Layout</strong></h3><p>As component structure becomes more complicated, varying layouts and included elements become more common. For example, an <code>Alert</code> component may include a <code>Title</code> or <code>Description</code> or both as well as arrange those horizontally or vertically as well as their combination horizontally or vertically with <code>Actions</code>. Sometimes, the entire <code>Alert</code>&#8217;s <code>Body</code> may need to be customized.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!zNKN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F027307d6-cf1c-4c72-9cc1-7ed9deb30452_1400x946.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!zNKN!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F027307d6-cf1c-4c72-9cc1-7ed9deb30452_1400x946.png 424w, /__u/substackcdn.com/image/fetch/$s_!zNKN!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F027307d6-cf1c-4c72-9cc1-7ed9deb30452_1400x946.png 848w, /__u/substackcdn.com/image/fetch/$s_!zNKN!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F027307d6-cf1c-4c72-9cc1-7ed9deb30452_1400x946.png 1272w, /__u/substackcdn.com/image/fetch/$s_!zNKN!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F027307d6-cf1c-4c72-9cc1-7ed9deb30452_1400x946.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!zNKN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F027307d6-cf1c-4c72-9cc1-7ed9deb30452_1400x946.png" width="1400" height="946" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/027307d6-cf1c-4c72-9cc1-7ed9deb30452_1400x946.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:946,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!zNKN!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F027307d6-cf1c-4c72-9cc1-7ed9deb30452_1400x946.png 424w, /__u/substackcdn.com/image/fetch/$s_!zNKN!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F027307d6-cf1c-4c72-9cc1-7ed9deb30452_1400x946.png 848w, /__u/substackcdn.com/image/fetch/$s_!zNKN!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F027307d6-cf1c-4c72-9cc1-7ed9deb30452_1400x946.png 1272w, /__u/substackcdn.com/image/fetch/$s_!zNKN!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F027307d6-cf1c-4c72-9cc1-7ed9deb30452_1400x946.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Alert component with all elements arranged in varied layouts</figcaption></figure></div><p>This can be achieved with subcomponents, each with variants controlling layout directions (at multiple levels) and element visibility. &#8220;Most&#8221; layouts become configurable.  Yet the overwhelmingly most common layout is all elements vertical, and three-level deep subcomponents always felt quite brittle.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Dqod!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae8185a-6e89-4ba6-8426-dc9b5cab7172_1400x958.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Dqod!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae8185a-6e89-4ba6-8426-dc9b5cab7172_1400x958.png 424w, /__u/substackcdn.com/image/fetch/$s_!Dqod!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae8185a-6e89-4ba6-8426-dc9b5cab7172_1400x958.png 848w, /__u/substackcdn.com/image/fetch/$s_!Dqod!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae8185a-6e89-4ba6-8426-dc9b5cab7172_1400x958.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Dqod!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae8185a-6e89-4ba6-8426-dc9b5cab7172_1400x958.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Dqod!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae8185a-6e89-4ba6-8426-dc9b5cab7172_1400x958.png" width="1400" height="958" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7ae8185a-6e89-4ba6-8426-dc9b5cab7172_1400x958.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:958,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Dqod!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae8185a-6e89-4ba6-8426-dc9b5cab7172_1400x958.png 424w, /__u/substackcdn.com/image/fetch/$s_!Dqod!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae8185a-6e89-4ba6-8426-dc9b5cab7172_1400x958.png 848w, /__u/substackcdn.com/image/fetch/$s_!Dqod!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae8185a-6e89-4ba6-8426-dc9b5cab7172_1400x958.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Dqod!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7ae8185a-6e89-4ba6-8426-dc9b5cab7172_1400x958.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Alert layer structure before and after slot migration</figcaption></figure></div><p>Alternatively the elements &#8211; both text elements like <code>Title</code> and <code>Description</code> as well as frame containers &#8211; could be included in a slot. This scaffolds a starting point with everything you need, enables rapid layout refactoring using the frames equipped with autolayout, removes the need for <code>Body</code> and <code>Text</code> subcomponents altogether. Anchoring on the predominant layout felt liberating.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!zOq0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f59c4e8-66f5-4cd5-a1c7-6aa7e32ac4d2_1400x1322.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!zOq0!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f59c4e8-66f5-4cd5-a1c7-6aa7e32ac4d2_1400x1322.png 424w, /__u/substackcdn.com/image/fetch/$s_!zOq0!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f59c4e8-66f5-4cd5-a1c7-6aa7e32ac4d2_1400x1322.png 848w, /__u/substackcdn.com/image/fetch/$s_!zOq0!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f59c4e8-66f5-4cd5-a1c7-6aa7e32ac4d2_1400x1322.png 1272w, /__u/substackcdn.com/image/fetch/$s_!zOq0!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f59c4e8-66f5-4cd5-a1c7-6aa7e32ac4d2_1400x1322.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!zOq0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f59c4e8-66f5-4cd5-a1c7-6aa7e32ac4d2_1400x1322.png" width="1400" height="1322" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7f59c4e8-66f5-4cd5-a1c7-6aa7e32ac4d2_1400x1322.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1322,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!zOq0!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f59c4e8-66f5-4cd5-a1c7-6aa7e32ac4d2_1400x1322.png 424w, /__u/substackcdn.com/image/fetch/$s_!zOq0!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f59c4e8-66f5-4cd5-a1c7-6aa7e32ac4d2_1400x1322.png 848w, /__u/substackcdn.com/image/fetch/$s_!zOq0!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f59c4e8-66f5-4cd5-a1c7-6aa7e32ac4d2_1400x1322.png 1272w, /__u/substackcdn.com/image/fetch/$s_!zOq0!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f59c4e8-66f5-4cd5-a1c7-6aa7e32ac4d2_1400x1322.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Alert configuration before and after slot migration</figcaption></figure></div><p>As a result, subcomponents and their layout, text and visibility props vanished. Instead, the component asset was coupled with a few ready made examples of the alternative layouts. Designers have everything they need to achieve the outcome they want as quickly as before, yet with far more flexibility.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!epBw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae0e5c1e-004c-434c-b15e-495a951d2e4c_1600x1179.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!epBw!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae0e5c1e-004c-434c-b15e-495a951d2e4c_1600x1179.png 424w, /__u/substackcdn.com/image/fetch/$s_!epBw!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae0e5c1e-004c-434c-b15e-495a951d2e4c_1600x1179.png 848w, /__u/substackcdn.com/image/fetch/$s_!epBw!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae0e5c1e-004c-434c-b15e-495a951d2e4c_1600x1179.png 1272w, /__u/substackcdn.com/image/fetch/$s_!epBw!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae0e5c1e-004c-434c-b15e-495a951d2e4c_1600x1179.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!epBw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae0e5c1e-004c-434c-b15e-495a951d2e4c_1600x1179.png" width="1456" height="1073" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ae0e5c1e-004c-434c-b15e-495a951d2e4c_1600x1179.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1073,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!epBw!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae0e5c1e-004c-434c-b15e-495a951d2e4c_1600x1179.png 424w, /__u/substackcdn.com/image/fetch/$s_!epBw!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae0e5c1e-004c-434c-b15e-495a951d2e4c_1600x1179.png 848w, /__u/substackcdn.com/image/fetch/$s_!epBw!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae0e5c1e-004c-434c-b15e-495a951d2e4c_1600x1179.png 1272w, /__u/substackcdn.com/image/fetch/$s_!epBw!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae0e5c1e-004c-434c-b15e-495a951d2e4c_1600x1179.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Alert component assets beside the ready-made examples</figcaption></figure></div><h3><strong>Card</strong></h3><p>Early <code>Card</code> experimentation focused on common structures &#8211; <code>Visual</code>, content layouts, <code>Actions</code>. Depending on the design system, that could result in useful, composable subcomponents that recombine in a few predictable ways.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!9yHY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0895454c-bede-47b1-b37d-5d0bd374d3f1_1400x832.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!9yHY!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0895454c-bede-47b1-b37d-5d0bd374d3f1_1400x832.png 424w, /__u/substackcdn.com/image/fetch/$s_!9yHY!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0895454c-bede-47b1-b37d-5d0bd374d3f1_1400x832.png 848w, /__u/substackcdn.com/image/fetch/$s_!9yHY!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0895454c-bede-47b1-b37d-5d0bd374d3f1_1400x832.png 1272w, /__u/substackcdn.com/image/fetch/$s_!9yHY!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0895454c-bede-47b1-b37d-5d0bd374d3f1_1400x832.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!9yHY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0895454c-bede-47b1-b37d-5d0bd374d3f1_1400x832.png" width="1400" height="832" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0895454c-bede-47b1-b37d-5d0bd374d3f1_1400x832.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:832,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!9yHY!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0895454c-bede-47b1-b37d-5d0bd374d3f1_1400x832.png 424w, /__u/substackcdn.com/image/fetch/$s_!9yHY!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0895454c-bede-47b1-b37d-5d0bd374d3f1_1400x832.png 848w, /__u/substackcdn.com/image/fetch/$s_!9yHY!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0895454c-bede-47b1-b37d-5d0bd374d3f1_1400x832.png 1272w, /__u/substackcdn.com/image/fetch/$s_!9yHY!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0895454c-bede-47b1-b37d-5d0bd374d3f1_1400x832.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Not this particular system. The system served divergent experiences spanning 50 brands. There simply was no predominant default, or even common limited collection. Instead, the system would likely require a deep collection of diverse ready-made examples. As a result, for the core library at least, it made sense to hollow out the <code>Card</code> to an unopinionated container.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!NGNf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07dd9dc-93c0-436c-870d-446cd6308ce2_1400x1054.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!NGNf!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07dd9dc-93c0-436c-870d-446cd6308ce2_1400x1054.png 424w, /__u/substackcdn.com/image/fetch/$s_!NGNf!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07dd9dc-93c0-436c-870d-446cd6308ce2_1400x1054.png 848w, /__u/substackcdn.com/image/fetch/$s_!NGNf!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07dd9dc-93c0-436c-870d-446cd6308ce2_1400x1054.png 1272w, /__u/substackcdn.com/image/fetch/$s_!NGNf!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07dd9dc-93c0-436c-870d-446cd6308ce2_1400x1054.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!NGNf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07dd9dc-93c0-436c-870d-446cd6308ce2_1400x1054.png" width="1400" height="1054" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a07dd9dc-93c0-436c-870d-446cd6308ce2_1400x1054.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1054,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!NGNf!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07dd9dc-93c0-436c-870d-446cd6308ce2_1400x1054.png 424w, /__u/substackcdn.com/image/fetch/$s_!NGNf!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07dd9dc-93c0-436c-870d-446cd6308ce2_1400x1054.png 848w, /__u/substackcdn.com/image/fetch/$s_!NGNf!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07dd9dc-93c0-436c-870d-446cd6308ce2_1400x1054.png 1272w, /__u/substackcdn.com/image/fetch/$s_!NGNf!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa07dd9dc-93c0-436c-870d-446cd6308ce2_1400x1054.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>With a hollowed out container component, that meant the core library deliberately offered no configurable subparts. There&#8217;s justification for a composable <code>Card / Visual</code> , but the core team might rather focus on offering an Image component that you can overlay custom content instead. The <code>Card / Actions</code> subcomponent would echo the pattern established by <code>Alert</code>, but actions too were too diverse to normalize. Why bother? Just compose what you need.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!t5u4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c30fda6-91d4-40af-801b-93b4f563c935_1364x1600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!t5u4!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c30fda6-91d4-40af-801b-93b4f563c935_1364x1600.png 424w, /__u/substackcdn.com/image/fetch/$s_!t5u4!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c30fda6-91d4-40af-801b-93b4f563c935_1364x1600.png 848w, /__u/substackcdn.com/image/fetch/$s_!t5u4!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c30fda6-91d4-40af-801b-93b4f563c935_1364x1600.png 1272w, /__u/substackcdn.com/image/fetch/$s_!t5u4!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c30fda6-91d4-40af-801b-93b4f563c935_1364x1600.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!t5u4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c30fda6-91d4-40af-801b-93b4f563c935_1364x1600.png" width="1364" height="1600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3c30fda6-91d4-40af-801b-93b4f563c935_1364x1600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1600,&quot;width&quot;:1364,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!t5u4!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c30fda6-91d4-40af-801b-93b4f563c935_1364x1600.png 424w, /__u/substackcdn.com/image/fetch/$s_!t5u4!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c30fda6-91d4-40af-801b-93b4f563c935_1364x1600.png 848w, /__u/substackcdn.com/image/fetch/$s_!t5u4!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c30fda6-91d4-40af-801b-93b4f563c935_1364x1600.png 1272w, /__u/substackcdn.com/image/fetch/$s_!t5u4!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3c30fda6-91d4-40af-801b-93b4f563c935_1364x1600.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The core <code>Card</code>&#8217;s unopinionated container is a strategic choice. Less is more. It acts as a maximally flexible foundation without imposing constraints, enabling other teams to build purpose-driven extensions.</p><p>A separate team has already begun. They&#8217;ve initiated a separate library, signaling a rich array of even more hyper-specific card content subcomponents and zones, layouts and visual expression. The design system will then weave those inspirations in among the broader collection of ready-made examples to guide everyone.</p><p>There&#8217;s no one shape that&#8217;s perfect for everyone. I&#8217;m making different judgments for different design systems as I go to get to the goodness-of-fit that works for each case. Onward!</p>]]></content:encoded></item><item><title><![CDATA[Figma Slots for Repeating Items]]></title><description><![CDATA[How to convert one of your library's most common patterns]]></description><link>https://nathanacurtis.substack.com/p/figma-slots-for-repeating-items</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/figma-slots-for-repeating-items</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Fri, 23 Jan 2026 18:21:23 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!88Nu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88d1991-27fe-421c-93fe-89c387afedf0_2800x1575.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!88Nu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88d1991-27fe-421c-93fe-89c387afedf0_2800x1575.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!88Nu!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88d1991-27fe-421c-93fe-89c387afedf0_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!88Nu!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88d1991-27fe-421c-93fe-89c387afedf0_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!88Nu!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88d1991-27fe-421c-93fe-89c387afedf0_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!88Nu!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88d1991-27fe-421c-93fe-89c387afedf0_2800x1575.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!88Nu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88d1991-27fe-421c-93fe-89c387afedf0_2800x1575.png" width="1456" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e88d1991-27fe-421c-93fe-89c387afedf0_2800x1575.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:85304,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/185557988?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88d1991-27fe-421c-93fe-89c387afedf0_2800x1575.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!88Nu!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88d1991-27fe-421c-93fe-89c387afedf0_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!88Nu!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88d1991-27fe-421c-93fe-89c387afedf0_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!88Nu!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88d1991-27fe-421c-93fe-89c387afedf0_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!88Nu!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe88d1991-27fe-421c-93fe-89c387afedf0_2800x1575.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>As I talk with design system teams about Figma&#8217;s native slots rolling out for early evaluations, conversations invariably start with how a migration will replace <code>Slot utility</code> instances with native slots. I&#8217;m pretty quick to point out that &#8220;You may not even be using a slot utility for you most common kind of native slot. Have you thought about repeating items?&#8221;</p><p>This post illustrates many examples of repeating items within a core component library and why it&#8217;s been difficult to date to compose them effectively. The solution is Figma&#8217;s new native slots, with a more careful architecture of naming, default content, and more granular specs.</p><h2><strong>Background</strong></h2><p>Many, many UI components serve as a container for repeating items. This is most common when a component&#8217;s purpose is as group containing items, like:</p><ul><li><p><code>checkbox</code> in <code>checkboxGroup</code></p></li><li><p><code>radioButton</code> in <code>radioButtonGroup</code></p></li><li><p><code>avatar</code> in <code>avatarGroup</code></p></li><li><p><code>button</code> in <code>buttonGroup</code></p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!aRjX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f97aad-9c47-4a77-a18b-5cc2ba2265ee_1400x508.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!aRjX!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f97aad-9c47-4a77-a18b-5cc2ba2265ee_1400x508.png 424w, /__u/substackcdn.com/image/fetch/$s_!aRjX!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f97aad-9c47-4a77-a18b-5cc2ba2265ee_1400x508.png 848w, /__u/substackcdn.com/image/fetch/$s_!aRjX!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f97aad-9c47-4a77-a18b-5cc2ba2265ee_1400x508.png 1272w, /__u/substackcdn.com/image/fetch/$s_!aRjX!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f97aad-9c47-4a77-a18b-5cc2ba2265ee_1400x508.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!aRjX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f97aad-9c47-4a77-a18b-5cc2ba2265ee_1400x508.png" width="1400" height="508" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/98f97aad-9c47-4a77-a18b-5cc2ba2265ee_1400x508.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:508,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:48617,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/185557988?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f97aad-9c47-4a77-a18b-5cc2ba2265ee_1400x508.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!aRjX!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f97aad-9c47-4a77-a18b-5cc2ba2265ee_1400x508.png 424w, /__u/substackcdn.com/image/fetch/$s_!aRjX!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f97aad-9c47-4a77-a18b-5cc2ba2265ee_1400x508.png 848w, /__u/substackcdn.com/image/fetch/$s_!aRjX!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f97aad-9c47-4a77-a18b-5cc2ba2265ee_1400x508.png 1272w, /__u/substackcdn.com/image/fetch/$s_!aRjX!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98f97aad-9c47-4a77-a18b-5cc2ba2265ee_1400x508.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Checkbox and Radio button items in group component slots</figcaption></figure></div><p>Many components are groups implicitly even if not named that way:</p><ul><li><p><code>tab</code> in <code>tabs</code></p></li><li><p><code>breadcrumb</code> in <code>breadcrumbs</code></p></li><li><p><code>actionListItem</code> in <code>actionList</code></p></li><li><p><code>listItems</code> in a <code>list</code></p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!BXwc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99c6633-7781-46b9-aa93-08f21fbf434e_1400x396.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!BXwc!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99c6633-7781-46b9-aa93-08f21fbf434e_1400x396.png 424w, /__u/substackcdn.com/image/fetch/$s_!BXwc!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99c6633-7781-46b9-aa93-08f21fbf434e_1400x396.png 848w, /__u/substackcdn.com/image/fetch/$s_!BXwc!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99c6633-7781-46b9-aa93-08f21fbf434e_1400x396.png 1272w, /__u/substackcdn.com/image/fetch/$s_!BXwc!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99c6633-7781-46b9-aa93-08f21fbf434e_1400x396.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!BXwc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99c6633-7781-46b9-aa93-08f21fbf434e_1400x396.png" width="1400" height="396" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c99c6633-7781-46b9-aa93-08f21fbf434e_1400x396.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:396,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:24523,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/185557988?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99c6633-7781-46b9-aa93-08f21fbf434e_1400x396.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!BXwc!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99c6633-7781-46b9-aa93-08f21fbf434e_1400x396.png 424w, /__u/substackcdn.com/image/fetch/$s_!BXwc!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99c6633-7781-46b9-aa93-08f21fbf434e_1400x396.png 848w, /__u/substackcdn.com/image/fetch/$s_!BXwc!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99c6633-7781-46b9-aa93-08f21fbf434e_1400x396.png 1272w, /__u/substackcdn.com/image/fetch/$s_!BXwc!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc99c6633-7781-46b9-aa93-08f21fbf434e_1400x396.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Tabs and Breadcrumbs as repeating items without being named a &#8220;group&#8221; or &#8220;list&#8221;</figcaption></figure></div><p>Repeating items also exist in a component area like <code>actions</code> in an <code>alert</code>, <code>toolbar</code> or <code>dialog</code>. Suffice it to say, a repeating item pattern is pervasive across a component library of any scale. As systems migrate Figma assets to native slots, don&#8217;t be surprised when you find that repeating items are the most common composable pattern in a library.</p><h2><strong>Anti-Patterns</strong></h2><p>Unfortunately, that&#8217;s never been easy to enable in Figma component assets. This led to workarounds like instance swapping, hidden layers, and &#8220;count&#8221; props.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!eKFk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aaf9832-b3b6-4fc6-b69b-9e769043d760_1400x508.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!eKFk!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aaf9832-b3b6-4fc6-b69b-9e769043d760_1400x508.png 424w, /__u/substackcdn.com/image/fetch/$s_!eKFk!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aaf9832-b3b6-4fc6-b69b-9e769043d760_1400x508.png 848w, /__u/substackcdn.com/image/fetch/$s_!eKFk!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aaf9832-b3b6-4fc6-b69b-9e769043d760_1400x508.png 1272w, /__u/substackcdn.com/image/fetch/$s_!eKFk!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aaf9832-b3b6-4fc6-b69b-9e769043d760_1400x508.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!eKFk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aaf9832-b3b6-4fc6-b69b-9e769043d760_1400x508.png" width="1400" height="508" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2aaf9832-b3b6-4fc6-b69b-9e769043d760_1400x508.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:508,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:29636,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/185557988?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aaf9832-b3b6-4fc6-b69b-9e769043d760_1400x508.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!eKFk!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aaf9832-b3b6-4fc6-b69b-9e769043d760_1400x508.png 424w, /__u/substackcdn.com/image/fetch/$s_!eKFk!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aaf9832-b3b6-4fc6-b69b-9e769043d760_1400x508.png 848w, /__u/substackcdn.com/image/fetch/$s_!eKFk!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aaf9832-b3b6-4fc6-b69b-9e769043d760_1400x508.png 1272w, /__u/substackcdn.com/image/fetch/$s_!eKFk!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2aaf9832-b3b6-4fc6-b69b-9e769043d760_1400x508.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figma &#8220;slot utility&#8221; meant to be swapped out</figcaption></figure></div><p><strong>Instance Swapping: </strong>Some systems implement repeating items as an instance swap, even creating a row-based convention of instance swaps-within-instance swaps within which repeating items were placed. No thanks.</p><ul><li><p>Users find instance swapping ergonomically annoying</p></li><li><p>Users had to create a separate component asset to swap in an instance</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!UdkR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f829e38-859c-49f3-a114-1f1809cf8b11_1400x672.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!UdkR!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f829e38-859c-49f3-a114-1f1809cf8b11_1400x672.png 424w, /__u/substackcdn.com/image/fetch/$s_!UdkR!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f829e38-859c-49f3-a114-1f1809cf8b11_1400x672.png 848w, /__u/substackcdn.com/image/fetch/$s_!UdkR!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f829e38-859c-49f3-a114-1f1809cf8b11_1400x672.png 1272w, /__u/substackcdn.com/image/fetch/$s_!UdkR!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f829e38-859c-49f3-a114-1f1809cf8b11_1400x672.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!UdkR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f829e38-859c-49f3-a114-1f1809cf8b11_1400x672.png" width="1400" height="672" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8f829e38-859c-49f3-a114-1f1809cf8b11_1400x672.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:672,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:63702,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/185557988?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f829e38-859c-49f3-a114-1f1809cf8b11_1400x672.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!UdkR!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f829e38-859c-49f3-a114-1f1809cf8b11_1400x672.png 424w, /__u/substackcdn.com/image/fetch/$s_!UdkR!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f829e38-859c-49f3-a114-1f1809cf8b11_1400x672.png 848w, /__u/substackcdn.com/image/fetch/$s_!UdkR!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f829e38-859c-49f3-a114-1f1809cf8b11_1400x672.png 1272w, /__u/substackcdn.com/image/fetch/$s_!UdkR!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f829e38-859c-49f3-a114-1f1809cf8b11_1400x672.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figma instance with 3 &#8211; and ONLY 3 - hidden item instances</figcaption></figure></div><p><strong>Hidden Nested Instances: </strong>Systems also use hidden layers for extra items, with quantities based on implicit conventions (such as showing &#8216;x&#8217; layers and hiding &#8216;y&#8217; layers). Negative outcomes include:</p><ul><li><p>Users drill deep into component layers to find and manipulate items</p></li><li><p>Overridden instance layer visibility and other nested configurations, an antipattern</p></li><li><p>Items cannot be reordered</p></li><li><p>Additional items cannot be added</p></li><li><p>Degraded file performance due many hidden and often complicated layer hierarchies per instance</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!fn_E!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f725a05-f476-41eb-ac6f-cdd77b2f5ad2_1400x672.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!fn_E!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f725a05-f476-41eb-ac6f-cdd77b2f5ad2_1400x672.png 424w, /__u/substackcdn.com/image/fetch/$s_!fn_E!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f725a05-f476-41eb-ac6f-cdd77b2f5ad2_1400x672.png 848w, /__u/substackcdn.com/image/fetch/$s_!fn_E!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f725a05-f476-41eb-ac6f-cdd77b2f5ad2_1400x672.png 1272w, /__u/substackcdn.com/image/fetch/$s_!fn_E!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f725a05-f476-41eb-ac6f-cdd77b2f5ad2_1400x672.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!fn_E!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f725a05-f476-41eb-ac6f-cdd77b2f5ad2_1400x672.png" width="1400" height="672" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5f725a05-f476-41eb-ac6f-cdd77b2f5ad2_1400x672.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:672,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:56812,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/185557988?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f725a05-f476-41eb-ac6f-cdd77b2f5ad2_1400x672.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!fn_E!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f725a05-f476-41eb-ac6f-cdd77b2f5ad2_1400x672.png 424w, /__u/substackcdn.com/image/fetch/$s_!fn_E!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f725a05-f476-41eb-ac6f-cdd77b2f5ad2_1400x672.png 848w, /__u/substackcdn.com/image/fetch/$s_!fn_E!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f725a05-f476-41eb-ac6f-cdd77b2f5ad2_1400x672.png 1272w, /__u/substackcdn.com/image/fetch/$s_!fn_E!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f725a05-f476-41eb-ac6f-cdd77b2f5ad2_1400x672.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figma component asset with a property to control item quantity</figcaption></figure></div><p><strong>Quantity Props:</strong> Systems add props like Count to control item quantity. For example, systems may implement an enum Count prop to display 1, 2 or 3 actions in an Alert.</p><p>This is composition, not configuration. Avoid it given negative outcomes of:</p><ul><li><p><strong>Variant explosion</strong> in component sets</p></li><li><p><strong>Handoff friction</strong> in handoff to ignore props not a part of the &#8220;official API&#8221;</p></li><li><p><strong>Item configuration</strong> conflation into props of a higher-order asset</p></li></ul><p>All of these approaches are hacks to make up for Figma&#8217;s historical lack of component asset composability.</p><h2><strong>Solution</strong></h2><p>Use Figma native slots to compose repeating items within a component asset and populate the slot&#8217;s default content with a reasonable and consistent number of items.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!EE3a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205024b6-f2b8-4119-85aa-0ced9a89127f_1400x424.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!EE3a!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205024b6-f2b8-4119-85aa-0ced9a89127f_1400x424.png 424w, /__u/substackcdn.com/image/fetch/$s_!EE3a!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205024b6-f2b8-4119-85aa-0ced9a89127f_1400x424.png 848w, /__u/substackcdn.com/image/fetch/$s_!EE3a!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205024b6-f2b8-4119-85aa-0ced9a89127f_1400x424.png 1272w, /__u/substackcdn.com/image/fetch/$s_!EE3a!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205024b6-f2b8-4119-85aa-0ced9a89127f_1400x424.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!EE3a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205024b6-f2b8-4119-85aa-0ced9a89127f_1400x424.png" width="1400" height="424" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/205024b6-f2b8-4119-85aa-0ced9a89127f_1400x424.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:424,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:83770,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/185557988?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205024b6-f2b8-4119-85aa-0ced9a89127f_1400x424.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!EE3a!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205024b6-f2b8-4119-85aa-0ced9a89127f_1400x424.png 424w, /__u/substackcdn.com/image/fetch/$s_!EE3a!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205024b6-f2b8-4119-85aa-0ced9a89127f_1400x424.png 848w, /__u/substackcdn.com/image/fetch/$s_!EE3a!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205024b6-f2b8-4119-85aa-0ced9a89127f_1400x424.png 1272w, /__u/substackcdn.com/image/fetch/$s_!EE3a!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205024b6-f2b8-4119-85aa-0ced9a89127f_1400x424.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Figma <code>Checkbox Group</code> instance with an <code>items</code> slot</figcaption></figure></div><p>For example, include an <code>items</code> slot in a <code>checkboxGroup</code> with three <code>checkbox</code> instances by default. It&#8217;s easy for the user to add, remove, reorder and even quick drag to create a longer list of items.</p><h3><strong>Pros</strong></h3><ul><li><p><strong>Improved Composability</strong>: Slots solve the primary problem: a clean container-child relationship to easily add, remove, and reorder items.</p></li><li><p><strong>Low Asset Complexity</strong>: This eliminates the need for workarounds like &#8220;hidden layers&#8221; and &#8220;count props,&#8221; which improves file performance and reduces implicit conventions.</p></li><li><p><strong>Clear API</strong>: An items slot is an explicit, native way to define the types and constraints of customizable children.</p></li></ul><h3><strong>Cons</strong></h3><ul><li><p><strong>Open, Uncontrolled Children</strong>: Figma slots are inherently open. They&#8217;ll take anything, no matter what you designate as &#8220;preferred.&#8221; Therefore, systems must trust users and implement methods to verify design and code.</p></li><li><p><strong>Risk of Empty Slots</strong>: The user can remove all default items, causing the slot to appear empty.</p></li><li><p><strong>More Complicated Definition</strong>: Systems must define a more granular slot architecture including naming, constraints and guidance.</p></li></ul><p>You could also assert it requires a learning curve. I wouldn&#8217;t agree. All the previous methods were both error prone and harder to use. The simplicity of starting with a composable area with items you need drastically saves time and is directly the interaction users prefer.</p><h2><strong>Architecture</strong></h2><p>When adding native slots to library components for repeating patterns, be mindful of details like naming the prop and layer, default content, minimum and maximum quantity, and permitted values.</p><h3><strong>Naming</strong></h3><p>In Figma, slots are both a property type (<code>SLOT</code>) and layer type (<code>SlotNode</code>). The names of each are revealed in the Props and Layers panels, respectively. Choosing a conventional name for both improves user understanding and expectations when composing repeating items across a library.</p><p><strong>Favor </strong><code>items</code><strong> (purposeful) over </strong><code>children</code><strong> generic)</strong>. During our refactor to native slots, we narrowed down to considering <code>items</code> versus <code>children</code>, where <code>children</code> had already been chosen generic component slots with no default content. We chose <code>items</code> to carry a narrower purpose that expects specific types of children.</p><p><strong>Distinguish </strong><code>items</code><strong> and </strong><code>children</code>. In addition, components with items often have additional elements not included in the slot, such as an <code>avatarGroup</code>&#8217;s end count or a <code>checkboxGroup</code>&#8217;s header and error message. This, too, distinguishes the repeating items case from corresponding to &#8220;all of a component&#8217;s <code>children</code>.&#8221;</p><pre><code>components:
  checkboxGroup:
    elements:
      items:
      header:
      description:
      validation:
    default:
      layout:
        - root
          - headerArea
            - header
            - description
          - items
          - error
            - errorIcon
            - errorMessage</code></pre><h3><strong>Default items</strong></h3><p>Generally, three items seems the reasonable convention for most item sets, since three:</p><ul><li><p>Affords that it&#8217;s an indeterminate list more strongly than two or one</p></li><li><p>Enables distinguishing a <code>selected</code> item (often the first item) separately from other items in components like <code>tabs</code> and <code>radioButtonGroup</code>.</p></li></ul><p>However, there are cases where two (such as <code>actions</code> in an <code>alert</code>) or other counts make more sense. We&#8217;ll document when to diverge from the convention.</p><p>Additionally, it&#8217;s important to not confuse default slot data with ready-made examples. Sure, a <code>checkboxGroup</code> can have many, many items, and you can depict that in your system&#8217;s set of examples. However, that&#8217;d prove a very hostile default relative to the far more frequent cases of a few items.</p><h3><strong>Minimum and maximum item quantity</strong></h3><p>Unlike generic slots which can be empty, slots for repeating items generally require one or more items. As a result, we&#8217;ll define such slots as <code>minItems:1</code>.</p><p>Occasionally, an <code>items</code> slot may govern a maximum number of items. For example, an Avatar group may include up to four Avatar components, after which a count to the right of the last item.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!axqH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24aab6f1-202f-421a-8cee-5e3035cf0a39_1400x424.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!axqH!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24aab6f1-202f-421a-8cee-5e3035cf0a39_1400x424.png 424w, /__u/substackcdn.com/image/fetch/$s_!axqH!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24aab6f1-202f-421a-8cee-5e3035cf0a39_1400x424.png 848w, /__u/substackcdn.com/image/fetch/$s_!axqH!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24aab6f1-202f-421a-8cee-5e3035cf0a39_1400x424.png 1272w, /__u/substackcdn.com/image/fetch/$s_!axqH!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24aab6f1-202f-421a-8cee-5e3035cf0a39_1400x424.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!axqH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24aab6f1-202f-421a-8cee-5e3035cf0a39_1400x424.png" width="1400" height="424" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/24aab6f1-202f-421a-8cee-5e3035cf0a39_1400x424.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:424,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:281423,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/185557988?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24aab6f1-202f-421a-8cee-5e3035cf0a39_1400x424.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!axqH!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24aab6f1-202f-421a-8cee-5e3035cf0a39_1400x424.png 424w, /__u/substackcdn.com/image/fetch/$s_!axqH!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24aab6f1-202f-421a-8cee-5e3035cf0a39_1400x424.png 848w, /__u/substackcdn.com/image/fetch/$s_!axqH!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24aab6f1-202f-421a-8cee-5e3035cf0a39_1400x424.png 1272w, /__u/substackcdn.com/image/fetch/$s_!axqH!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24aab6f1-202f-421a-8cee-5e3035cf0a39_1400x424.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><code>avatarGroup</code> instance with a slot</figcaption></figure></div><p>If a system chose to include this hard constraint, the <code>avatarGroup</code> would define an <code>items</code> slot as:</p><pre><code>components:
  avatarGroup:
    props:
      items:
        type: slot
        anyOf: avatar
        minItems: 1
        maxItems: 4</code></pre><h3><strong>Permitted vs preferred values</strong></h3><p>Figma&#8217;s slot preferred values match the experience for instance swapping. Undoubtedly, slot properties should associate the single item type (like <code>checkbox</code> within <code>checkboxGroup</code>) as preferred values.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!uXW7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F622156a6-1d6b-46d1-9aaa-4a0487817a2b_1400x606.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!uXW7!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F622156a6-1d6b-46d1-9aaa-4a0487817a2b_1400x606.png 424w, /__u/substackcdn.com/image/fetch/$s_!uXW7!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F622156a6-1d6b-46d1-9aaa-4a0487817a2b_1400x606.png 848w, /__u/substackcdn.com/image/fetch/$s_!uXW7!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F622156a6-1d6b-46d1-9aaa-4a0487817a2b_1400x606.png 1272w, /__u/substackcdn.com/image/fetch/$s_!uXW7!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F622156a6-1d6b-46d1-9aaa-4a0487817a2b_1400x606.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!uXW7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F622156a6-1d6b-46d1-9aaa-4a0487817a2b_1400x606.png" width="1400" height="606" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/622156a6-1d6b-46d1-9aaa-4a0487817a2b_1400x606.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:606,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:266844,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/185557988?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F622156a6-1d6b-46d1-9aaa-4a0487817a2b_1400x606.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!uXW7!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F622156a6-1d6b-46d1-9aaa-4a0487817a2b_1400x606.png 424w, /__u/substackcdn.com/image/fetch/$s_!uXW7!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F622156a6-1d6b-46d1-9aaa-4a0487817a2b_1400x606.png 848w, /__u/substackcdn.com/image/fetch/$s_!uXW7!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F622156a6-1d6b-46d1-9aaa-4a0487817a2b_1400x606.png 1272w, /__u/substackcdn.com/image/fetch/$s_!uXW7!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F622156a6-1d6b-46d1-9aaa-4a0487817a2b_1400x606.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><code>avatarGroup</code> with <code>avatar</code> defined as a preferred value</figcaption></figure></div><p>Nevertheless, Figma&#8217;s slots are open to accept any child and cannot be formally governed. This relationship is stricter. In specification data, this is represented by a list <code>anyOf</code> items, like:</p><pre><code>components:
  checkboxGroup:
    props:
      items:
        type: slot
        anyOf: checkbox
        minItems: 1</code></pre><p>We&#8217;ll use <a href="/__u/nathanacurtis.substack.com/p/code-only-props-in-figma">code only props</a> to identify what items are permitted, minimums and maximums so as to handoff the intent via <a href="/__u/nathanacurtis.substack.com/p/components-as-data-2be178777f21">component data</a> downstream to collaborators and machines.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!HmCp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0442a83a-e627-4796-b3bb-142cc3a18efd_1400x688.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!HmCp!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0442a83a-e627-4796-b3bb-142cc3a18efd_1400x688.png 424w, /__u/substackcdn.com/image/fetch/$s_!HmCp!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0442a83a-e627-4796-b3bb-142cc3a18efd_1400x688.png 848w, /__u/substackcdn.com/image/fetch/$s_!HmCp!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0442a83a-e627-4796-b3bb-142cc3a18efd_1400x688.png 1272w, /__u/substackcdn.com/image/fetch/$s_!HmCp!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0442a83a-e627-4796-b3bb-142cc3a18efd_1400x688.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!HmCp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0442a83a-e627-4796-b3bb-142cc3a18efd_1400x688.png" width="1400" height="688" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0442a83a-e627-4796-b3bb-142cc3a18efd_1400x688.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:688,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:40038,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/185557988?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0442a83a-e627-4796-b3bb-142cc3a18efd_1400x688.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!HmCp!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0442a83a-e627-4796-b3bb-142cc3a18efd_1400x688.png 424w, /__u/substackcdn.com/image/fetch/$s_!HmCp!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0442a83a-e627-4796-b3bb-142cc3a18efd_1400x688.png 848w, /__u/substackcdn.com/image/fetch/$s_!HmCp!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0442a83a-e627-4796-b3bb-142cc3a18efd_1400x688.png 1272w, /__u/substackcdn.com/image/fetch/$s_!HmCp!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0442a83a-e627-4796-b3bb-142cc3a18efd_1400x688.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">checkboxGroup with additional &#8220;code only&#8221; props containing slot specification data</figcaption></figure></div><div><hr></div><p>Figma&#8217;s native slots are the new primitive that shifts the burden of complexity from the designer's canvas back to the system&#8217;s architecture. By providing an explicit, consistent API for repeating items, systems can move post brittle hacks and offer a cleaner canvas, a simpler property panel, and a more flexible library for everyone.</p>]]></content:encoded></item><item><title><![CDATA["Code Only" Props in Figma]]></title><description><![CDATA[Expanding component API shape in design assets]]></description><link>https://nathanacurtis.substack.com/p/code-only-props-in-figma</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/code-only-props-in-figma</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Fri, 16 Jan 2026 23:13:01 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!LHMk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34c704f4-4d51-4e7b-8a55-7df7e607a3d7_2800x1575.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!LHMk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34c704f4-4d51-4e7b-8a55-7df7e607a3d7_2800x1575.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!LHMk!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34c704f4-4d51-4e7b-8a55-7df7e607a3d7_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!LHMk!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34c704f4-4d51-4e7b-8a55-7df7e607a3d7_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!LHMk!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34c704f4-4d51-4e7b-8a55-7df7e607a3d7_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!LHMk!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34c704f4-4d51-4e7b-8a55-7df7e607a3d7_2800x1575.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!LHMk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34c704f4-4d51-4e7b-8a55-7df7e607a3d7_2800x1575.png" width="728" height="409.5" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/34c704f4-4d51-4e7b-8a55-7df7e607a3d7_2800x1575.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:4712276,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/184818889?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34c704f4-4d51-4e7b-8a55-7df7e607a3d7_2800x1575.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!LHMk!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34c704f4-4d51-4e7b-8a55-7df7e607a3d7_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!LHMk!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34c704f4-4d51-4e7b-8a55-7df7e607a3d7_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!LHMk!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34c704f4-4d51-4e7b-8a55-7df7e607a3d7_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!LHMk!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34c704f4-4d51-4e7b-8a55-7df7e607a3d7_2800x1575.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I&#8217;m among those that steward cohesive component API. In designing systems, it&#8217;s our job to define and communicate accessibility, behavior and non-visual logic just as much as style and layout.</p><p>As we define components, we&#8217;ll face intricate questions that shape how components work. Figma hasn&#8217;t yet been the place to express all those answers. Yet, what if&#8230; we started shaping more of that via props to Figma assets?</p><p>This post details a technique for adding &#8220;code only props&#8221; to Figma components. It covers how these props better connect system designers with their users and system developer counterparts, how to build them into Figma, and ends with examples from simple to controversial to gloriously yet dizzyingly complicated.</p><div><hr></div><h2>Challenges</h2><p>My work often focuses on a core component library that is built into Figma assets, transformed into <a href="/__u/nathanacurtis.substack.com/p/components-as-data-2be178777f21">spec data</a> and is implemented across iOS, Android, and the web. </p><p>Each component&#8217;s property shape can be complicated. Figma provides for many prop types: text (primarily for text characters), variant, boolean (for visibility), instance swap and soon slot too. Yet, Figma prop types are nowhere near comprehensive and bias heavily towards visual outcomes rather than broader concerns.</p><p>This challenges system designers, who want to:</p><ol><li><p>Specify non-visual accessibility and other configurations as a part of defining a system component</p></li><li><p>Maximize API they can shape and deliver into deterministic, automated processes</p></li><li><p>Expose non-visual props that product designers can use to express an intent</p></li><li><p>Clarify relationships of visual and non-visual props</p></li><li><p>Improve how Figma synchronizes with code libraries and other assets</p></li></ol><div><hr></div><h2>Solution</h2><p>We began to add Figma <code>TEXT</code> and props and <code>VARIANT</code> props of nested instances that correspond to additional props, housed in a practically hidden &#8220;Code only props&#8221; layer.</p><h3>Step 1. Code-only props layer</h3><p>Add  a Code only props layer as a child of the component&#8217;s root layer, positioned at <code>(0,0)</code> with width and height of <code>0.01</code> and clipping contents.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!tIAC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7623fd-8430-428c-ae3f-ccffc25ab44b_1400x448.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!tIAC!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7623fd-8430-428c-ae3f-ccffc25ab44b_1400x448.png 424w, /__u/substackcdn.com/image/fetch/$s_!tIAC!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7623fd-8430-428c-ae3f-ccffc25ab44b_1400x448.png 848w, /__u/substackcdn.com/image/fetch/$s_!tIAC!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7623fd-8430-428c-ae3f-ccffc25ab44b_1400x448.png 1272w, /__u/substackcdn.com/image/fetch/$s_!tIAC!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7623fd-8430-428c-ae3f-ccffc25ab44b_1400x448.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!tIAC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7623fd-8430-428c-ae3f-ccffc25ab44b_1400x448.png" width="1400" height="448" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7f7623fd-8430-428c-ae3f-ccffc25ab44b_1400x448.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:448,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!tIAC!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7623fd-8430-428c-ae3f-ccffc25ab44b_1400x448.png 424w, /__u/substackcdn.com/image/fetch/$s_!tIAC!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7623fd-8430-428c-ae3f-ccffc25ab44b_1400x448.png 848w, /__u/substackcdn.com/image/fetch/$s_!tIAC!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7623fd-8430-428c-ae3f-ccffc25ab44b_1400x448.png 1272w, /__u/substackcdn.com/image/fetch/$s_!tIAC!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7f7623fd-8430-428c-ae3f-ccffc25ab44b_1400x448.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Code only props layer with practically no size and clipping its contents</figcaption></figure></div><p>This virtually hidden layer contains semantically-relevant layers bound to component props that are nonetheless hidden from the visual experience.</p><h3>Step 2: Nest a layer per prop</h3><p>Add text and nested instance layers corresponding to each prop. </p><p>For example, interactive components like button, link, checkbox and breadcrumbs can include an <code>Accessibility label</code> prop. This property often maps to an internal label like <code>aria-label</code> or an associated <code>&lt;label&gt;</code> tag.</p><p>A system designer could bind an <code>Accessibility label</code> property to an  <code>Accessibility label</code> text layer within the code only props frame.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!KQ1K!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F036cace1-b3ef-4780-8eb3-ece190460ead_1400x592.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!KQ1K!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F036cace1-b3ef-4780-8eb3-ece190460ead_1400x592.png 424w, /__u/substackcdn.com/image/fetch/$s_!KQ1K!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F036cace1-b3ef-4780-8eb3-ece190460ead_1400x592.png 848w, /__u/substackcdn.com/image/fetch/$s_!KQ1K!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F036cace1-b3ef-4780-8eb3-ece190460ead_1400x592.png 1272w, /__u/substackcdn.com/image/fetch/$s_!KQ1K!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F036cace1-b3ef-4780-8eb3-ece190460ead_1400x592.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!KQ1K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F036cace1-b3ef-4780-8eb3-ece190460ead_1400x592.png" width="1400" height="592" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/036cace1-b3ef-4780-8eb3-ece190460ead_1400x592.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:592,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!KQ1K!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F036cace1-b3ef-4780-8eb3-ece190460ead_1400x592.png 424w, /__u/substackcdn.com/image/fetch/$s_!KQ1K!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F036cace1-b3ef-4780-8eb3-ece190460ead_1400x592.png 848w, /__u/substackcdn.com/image/fetch/$s_!KQ1K!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F036cace1-b3ef-4780-8eb3-ece190460ead_1400x592.png 1272w, /__u/substackcdn.com/image/fetch/$s_!KQ1K!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F036cace1-b3ef-4780-8eb3-ece190460ead_1400x592.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">A nested accessibility label text layer bound to text prop</figcaption></figure></div><p>A product designer will then see the prop in the Props panel.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Fc_l!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589c9c61-2452-4a82-afa4-93e3b8d61ae8_1400x690.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Fc_l!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589c9c61-2452-4a82-afa4-93e3b8d61ae8_1400x690.png 424w, /__u/substackcdn.com/image/fetch/$s_!Fc_l!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589c9c61-2452-4a82-afa4-93e3b8d61ae8_1400x690.png 848w, /__u/substackcdn.com/image/fetch/$s_!Fc_l!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589c9c61-2452-4a82-afa4-93e3b8d61ae8_1400x690.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Fc_l!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589c9c61-2452-4a82-afa4-93e3b8d61ae8_1400x690.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Fc_l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589c9c61-2452-4a82-afa4-93e3b8d61ae8_1400x690.png" width="1400" height="690" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/589c9c61-2452-4a82-afa4-93e3b8d61ae8_1400x690.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:690,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Fc_l!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589c9c61-2452-4a82-afa4-93e3b8d61ae8_1400x690.png 424w, /__u/substackcdn.com/image/fetch/$s_!Fc_l!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589c9c61-2452-4a82-afa4-93e3b8d61ae8_1400x690.png 848w, /__u/substackcdn.com/image/fetch/$s_!Fc_l!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589c9c61-2452-4a82-afa4-93e3b8d61ae8_1400x690.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Fc_l!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F589c9c61-2452-4a82-afa4-93e3b8d61ae8_1400x690.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">An accessibility label prop visible in the props panel</figcaption></figure></div><p>In general, the text layer is left visible or hidden (thus suppressing the field from view) depending on whether it&#8217;s relevant to a product designer.</p><h3>Step 3: Integrate into handoff and automations</h3><p>Handoffs and tools (like <a href="/__u/nathanacurtis.substack.com/p/components-as-data-2be178777f21">generating specification data</a> from assets via tools like my <a href="/__u/nathanacurtis.substack.com/p/analysis-of-variants-9e440c30b93e">Anova plugin</a>) pick up the prop, adding <code>accessibilityLabel</code> to the versioned contract centrally leveraged to implement and maintain a component across platforms.</p><pre><code>components:
  {component name}:
    props:
      ...
      accessibilityLabel:
        type: string</code></pre><p>As Figma data is transformed, tools can:</p><ul><li><p>Infer types based on default values, such as a string (<code>Label</code>), number (<code>0</code>) or enumerated list (such as <code>h1|h2|h3|h4|&#8230;</code>), although be careful with that</p></li><li><p>Omit the Figma structure irrelevant to generated code, since the code only props layer and its children are metadata, not formal component layout</p></li><li><p>Add and bind these layers when generating Figma assets from spec data</p></li></ul><h3>Tradeoffs</h3><p>Sure, props like <code>accessibilityLabel</code>, <code>headingRole</code>, and <code>maxRows</code> are less important to designers exploring design concepts. Tradeoffs include:</p><ul><li><p>&#9989; Improves visibility of component props to product designers</p></li><li><p>&#9989; Enables system designers to shape more of the component API</p></li><li><p>&#10060; Complicates Figma assets </p></li><li><p>&#10060; Adds friction when defining component due to unclear boundaries on which props to include and how to name them (in my opinion, this is <em>productive</em> friction)</p></li></ul><div><hr></div><h2>Additional Examples</h2><h3>Image <code>src</code> and <code>altText</code></h3><p>If building for one platform or even a content management system, it may or may not be valuable for a product designer to specify an <code>altText</code> or <code>src</code> but it could still be relevant for a system designer to convey one or both expected props to a system developer or a pipeline.</p><p>To accomplish this, a system designer add both text layers, bind each to a component prop, and hide those irrelevant to product designer activities by hiding the text layer(s).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!ocDu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4684b2-fb0b-42d6-a1a0-da91bef7ad30_1400x688.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!ocDu!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4684b2-fb0b-42d6-a1a0-da91bef7ad30_1400x688.png 424w, /__u/substackcdn.com/image/fetch/$s_!ocDu!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4684b2-fb0b-42d6-a1a0-da91bef7ad30_1400x688.png 848w, /__u/substackcdn.com/image/fetch/$s_!ocDu!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4684b2-fb0b-42d6-a1a0-da91bef7ad30_1400x688.png 1272w, /__u/substackcdn.com/image/fetch/$s_!ocDu!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4684b2-fb0b-42d6-a1a0-da91bef7ad30_1400x688.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!ocDu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4684b2-fb0b-42d6-a1a0-da91bef7ad30_1400x688.png" width="1400" height="688" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cc4684b2-fb0b-42d6-a1a0-da91bef7ad30_1400x688.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:688,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!ocDu!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4684b2-fb0b-42d6-a1a0-da91bef7ad30_1400x688.png 424w, /__u/substackcdn.com/image/fetch/$s_!ocDu!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4684b2-fb0b-42d6-a1a0-da91bef7ad30_1400x688.png 848w, /__u/substackcdn.com/image/fetch/$s_!ocDu!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4684b2-fb0b-42d6-a1a0-da91bef7ad30_1400x688.png 1272w, /__u/substackcdn.com/image/fetch/$s_!ocDu!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcc4684b2-fb0b-42d6-a1a0-da91bef7ad30_1400x688.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Two text layers bound to component props, one layer hidden to suppress it&#8217;s display in the Props panel</figcaption></figure></div><p>The product designer would then only see the props they need to, such as only the <code>altText</code> prop.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!p1_6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbe3f4f2-a3ab-4f89-a718-f0243949cd37_1400x690.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!p1_6!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbe3f4f2-a3ab-4f89-a718-f0243949cd37_1400x690.png 424w, /__u/substackcdn.com/image/fetch/$s_!p1_6!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbe3f4f2-a3ab-4f89-a718-f0243949cd37_1400x690.png 848w, /__u/substackcdn.com/image/fetch/$s_!p1_6!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbe3f4f2-a3ab-4f89-a718-f0243949cd37_1400x690.png 1272w, /__u/substackcdn.com/image/fetch/$s_!p1_6!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbe3f4f2-a3ab-4f89-a718-f0243949cd37_1400x690.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!p1_6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbe3f4f2-a3ab-4f89-a718-f0243949cd37_1400x690.png" width="1400" height="690" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dbe3f4f2-a3ab-4f89-a718-f0243949cd37_1400x690.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:690,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!p1_6!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbe3f4f2-a3ab-4f89-a718-f0243949cd37_1400x690.png 424w, /__u/substackcdn.com/image/fetch/$s_!p1_6!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbe3f4f2-a3ab-4f89-a718-f0243949cd37_1400x690.png 848w, /__u/substackcdn.com/image/fetch/$s_!p1_6!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbe3f4f2-a3ab-4f89-a718-f0243949cd37_1400x690.png 1272w, /__u/substackcdn.com/image/fetch/$s_!p1_6!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdbe3f4f2-a3ab-4f89-a718-f0243949cd37_1400x690.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Props panel exposing only the <code>altText</code> prop</figcaption></figure></div><p>Spec data would predictably encode both props:</p><pre><code>components:
  image:
    props:
      ...
      src:
        type: string
      altText:
        type: string</code></pre><p>Now, there are reasons we&#8217;d avoid these props in many systems, such as (1) not needing to because they are default HTML attributes or (2) it&#8217;s platform specific, running counter to the broader goal of orchestration across platforms. Nevertheless, the example reflects the flexibility of exposing and hiding props.</p><h3>Heading Semantic Tag and Level</h3><p>For a prop used to set which HTML tag is rendered in the DOM, the Heading component Figma asset could include a nested instance of an <code>as</code> component with variants for <code>h1|h2|h3|&#8230;</code> and so on. While it feels odd to create such utility assets in Figma, it&#8217;s actually simple and quick.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!mBzh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5580e04c-311b-4e62-9f0a-fbba813ee55a_1400x688.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!mBzh!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5580e04c-311b-4e62-9f0a-fbba813ee55a_1400x688.png 424w, /__u/substackcdn.com/image/fetch/$s_!mBzh!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5580e04c-311b-4e62-9f0a-fbba813ee55a_1400x688.png 848w, /__u/substackcdn.com/image/fetch/$s_!mBzh!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5580e04c-311b-4e62-9f0a-fbba813ee55a_1400x688.png 1272w, /__u/substackcdn.com/image/fetch/$s_!mBzh!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5580e04c-311b-4e62-9f0a-fbba813ee55a_1400x688.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!mBzh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5580e04c-311b-4e62-9f0a-fbba813ee55a_1400x688.png" width="1400" height="688" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5580e04c-311b-4e62-9f0a-fbba813ee55a_1400x688.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:688,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!mBzh!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5580e04c-311b-4e62-9f0a-fbba813ee55a_1400x688.png 424w, /__u/substackcdn.com/image/fetch/$s_!mBzh!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5580e04c-311b-4e62-9f0a-fbba813ee55a_1400x688.png 848w, /__u/substackcdn.com/image/fetch/$s_!mBzh!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5580e04c-311b-4e62-9f0a-fbba813ee55a_1400x688.png 1272w, /__u/substackcdn.com/image/fetch/$s_!mBzh!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5580e04c-311b-4e62-9f0a-fbba813ee55a_1400x688.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Two props for <code>As</code> and <code>Level</code>, both hidden from the product designer</figcaption></figure></div><p>The instance with one variant prop then gets transformed into spec data alongside related props like <code>level</code>:</p><pre><code>components:
  heading:
    props:
      ...
      as:
        type: string
        enum:
          - h1
          - h2
          - h3
          - h4
        default: h1
        nullable: false
      level:
        enum:
          - 1
          - 2
          - 3
          - 4
          - 5
        default: 1
        nullable: false</code></pre><p>In code, this would be used as:</p><pre><code>&lt;Heading as=&#8221;h3&#8221; level=&#8221;2&#8221;&gt;My Title&lt;/Heading&gt;</code></pre><p>For teams working across platforms, they&#8217;d need to decide whether or not specification data captures platform-specific props like these and whether or not those sync with Figma assets. That said, decades of experience suggests that conversations of separating concerns of <code>as</code> (structure) and <code>level</code> (presentation) aren&#8217;t dead yet..</p><h3>Slot Properties</h3><p>As we migrate to native slots in Figma, we&#8217;re adding additional props to describe slot configurations like <code>anyOf</code> (permitted children), <code>minItems</code> and <code>maxItems</code>.</p><p>For the Checkbox Group, we&#8217;d expect at least one child and they&#8217;d only ever be a Checkbox. Therefore, we build our asset to include:</p><ul><li><p>The <code>items</code> slot prop</p></li><li><p>The <code>items anyOf</code> that includes a comma separated list of component names (in this case, set to simply <code>Checkbox</code>)</p></li><li><p>The <code>items minItems</code> prop, here set to <code>1</code></p></li></ul><p>Both props are hidden from view for the product designer.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!TIbw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffe50015-958b-434e-b8ba-76b0f53bcc7d_1400x688.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!TIbw!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffe50015-958b-434e-b8ba-76b0f53bcc7d_1400x688.png 424w, /__u/substackcdn.com/image/fetch/$s_!TIbw!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffe50015-958b-434e-b8ba-76b0f53bcc7d_1400x688.png 848w, /__u/substackcdn.com/image/fetch/$s_!TIbw!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffe50015-958b-434e-b8ba-76b0f53bcc7d_1400x688.png 1272w, /__u/substackcdn.com/image/fetch/$s_!TIbw!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffe50015-958b-434e-b8ba-76b0f53bcc7d_1400x688.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!TIbw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffe50015-958b-434e-b8ba-76b0f53bcc7d_1400x688.png" width="1400" height="688" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ffe50015-958b-434e-b8ba-76b0f53bcc7d_1400x688.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:688,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!TIbw!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffe50015-958b-434e-b8ba-76b0f53bcc7d_1400x688.png 424w, /__u/substackcdn.com/image/fetch/$s_!TIbw!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffe50015-958b-434e-b8ba-76b0f53bcc7d_1400x688.png 848w, /__u/substackcdn.com/image/fetch/$s_!TIbw!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffe50015-958b-434e-b8ba-76b0f53bcc7d_1400x688.png 1272w, /__u/substackcdn.com/image/fetch/$s_!TIbw!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffe50015-958b-434e-b8ba-76b0f53bcc7d_1400x688.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Slot-specific configuration props</figcaption></figure></div><p>This corresponds to spec data of the shape:</p><pre><code><code>components:
  checkboxGroup:
    props:
      ...
      items:
        type: array
        anyOf: 
          - checkbox
        minItems: 1</code></code></pre><p>We considered other options in Figma. The emerging <code>slot</code> prop type may include a <code>description</code> field. However, a description is a rich text, less stable and unstructured target for automated tools. If we were to leverage it, we&#8217;d use it for guidance, not specs. The already supported <code>.preferredValues</code> field is much closer in intent, but we chose to not overload it with what&#8217;s permitted values. More on that another time.</p><h3>Text Area</h3><p>In more complicated components, a system designer must consider what may become a dizzying array of logical relationships. </p><p>Textarea could include configurations like minimum value length, maximum value length, showing or hiding a max character count and whether that includes current character count. Not all these props reveal themselves visibly to the user.</p><p>For example, a <code>minLength</code> property could be enforced through a component behavior but not within a Figma asset. <code>minLength</code> could also be related to &#8211; but doesn&#8217;t trigger &#8211; a <code>validation</code> represented by Figma variant with an error message. As a result, <code>minLength</code> is a viable code only prop.</p><p>Textarea height might be bound by a <code>minRows</code> count (such as <code>2</code> by default) and a <code>maxRows</code> count (possibly <code>undefined</code> by default). In Figma, product designers simulate that by resizing and fixing asset height to fit their use case. Yet, system designers could imbue this intent via code only props.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!WK8J!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc965c857-7988-492d-bee7-d37a9c326b75_1400x2032.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!WK8J!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc965c857-7988-492d-bee7-d37a9c326b75_1400x2032.png 424w, /__u/substackcdn.com/image/fetch/$s_!WK8J!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc965c857-7988-492d-bee7-d37a9c326b75_1400x2032.png 848w, /__u/substackcdn.com/image/fetch/$s_!WK8J!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc965c857-7988-492d-bee7-d37a9c326b75_1400x2032.png 1272w, /__u/substackcdn.com/image/fetch/$s_!WK8J!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc965c857-7988-492d-bee7-d37a9c326b75_1400x2032.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!WK8J!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc965c857-7988-492d-bee7-d37a9c326b75_1400x2032.png" width="1400" height="2032" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c965c857-7988-492d-bee7-d37a9c326b75_1400x2032.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2032,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!WK8J!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc965c857-7988-492d-bee7-d37a9c326b75_1400x2032.png 424w, /__u/substackcdn.com/image/fetch/$s_!WK8J!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc965c857-7988-492d-bee7-d37a9c326b75_1400x2032.png 848w, /__u/substackcdn.com/image/fetch/$s_!WK8J!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc965c857-7988-492d-bee7-d37a9c326b75_1400x2032.png 1272w, /__u/substackcdn.com/image/fetch/$s_!WK8J!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc965c857-7988-492d-bee7-d37a9c326b75_1400x2032.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Textarea props, including many code only props</figcaption></figure></div><p>These logical relationships result many text and boolean. All are built into the asset, enable logical relationships to show and hide relevant layers, and convey to spec data. Yeah, this one&#8217;s a doozy. Yet by the end of this modeling exercise, we&#8217;d learned much more about the component&#8217;s intricate behaviors.</p><div><hr></div><p>Using &#8220;Code-Only Props&#8221; in Figma&#8212;it&#8217;s a bit of a technical trick using hidden layers to sneak data through&#8212;lets Figma be an origin of truth defining a component. It&#8217;s behind-the-scenes stuff, for sure. System designers should handle complicated requirements without making the product designer&#8217;s prop panel a mess.</p>]]></content:encoded></item><item><title><![CDATA[Slots in Design Systems]]></title><description><![CDATA[Improving flexibility through custom composition inside components]]></description><link>https://nathanacurtis.substack.com/p/slots-in-design-systems</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/slots-in-design-systems</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Fri, 07 Nov 2025 20:30:15 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!8TPC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e13113c-648f-478b-bf41-546f1f126e2a_2800x1575.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!8TPC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e13113c-648f-478b-bf41-546f1f126e2a_2800x1575.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!8TPC!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e13113c-648f-478b-bf41-546f1f126e2a_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!8TPC!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e13113c-648f-478b-bf41-546f1f126e2a_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!8TPC!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e13113c-648f-478b-bf41-546f1f126e2a_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!8TPC!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e13113c-648f-478b-bf41-546f1f126e2a_2800x1575.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!8TPC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e13113c-648f-478b-bf41-546f1f126e2a_2800x1575.png" width="728" height="409.5" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6e13113c-648f-478b-bf41-546f1f126e2a_2800x1575.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:819,&quot;width&quot;:1456,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:63731,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/178182227?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e13113c-648f-478b-bf41-546f1f126e2a_2800x1575.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!8TPC!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e13113c-648f-478b-bf41-546f1f126e2a_2800x1575.png 424w, /__u/substackcdn.com/image/fetch/$s_!8TPC!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e13113c-648f-478b-bf41-546f1f126e2a_2800x1575.png 848w, /__u/substackcdn.com/image/fetch/$s_!8TPC!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e13113c-648f-478b-bf41-546f1f126e2a_2800x1575.png 1272w, /__u/substackcdn.com/image/fetch/$s_!8TPC!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e13113c-648f-478b-bf41-546f1f126e2a_2800x1575.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>No system solves every problem we&#8217;ll ever face. Nor should we want it to. Instead, a well-architected system balances what&#8217;s fixed and what&#8217;s open, where you are constrained by guardrails and where you can &#8211; and should &#8211; innovate.</p><p>Insert slots.</p><p>Slots define the areas in a component to vary content and structure, adapt layout, and improvise new ideas. Adding flexible, customizable areas to components move systems away from rigid, frustrating boundaries designers and developers struggle with today. Emerging native support of slots in Figma should usher in a next generation of component libraries, enabling more customization we crave without sacrificing control and consistency systems promise.</p><p>This post introduces the concept of slots in UI components. First, we&#8217;ll define slots and demonstrate the many forms slots take across common, familiar components. From there, we&#8217;ll dive into considerations of slot types, properties, subcomponent parts, and ready-made examples we&#8217;ll curate. Ultimately, slots present an array of new architectural challenges we&#8217;ll face and resolve in the year(s) ahead.</p><h2><strong>Getting Started</strong></h2><p>A slot is a designated place inside a component where custom content can be inserted&#8212;an intentional opening in a component&#8217;s hierarchy to allow custom variation. </p><p>In Figma, a slot are presented as a layer bordered in pink that acts a frame inside a component instance. Inside that boundary, you compose whatever you want. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!utiz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb56e94e6-8ed1-4abb-bd46-8736b9b068bd_2800x762.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!utiz!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb56e94e6-8ed1-4abb-bd46-8736b9b068bd_2800x762.png 424w, /__u/substackcdn.com/image/fetch/$s_!utiz!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb56e94e6-8ed1-4abb-bd46-8736b9b068bd_2800x762.png 848w, /__u/substackcdn.com/image/fetch/$s_!utiz!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb56e94e6-8ed1-4abb-bd46-8736b9b068bd_2800x762.png 1272w, /__u/substackcdn.com/image/fetch/$s_!utiz!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb56e94e6-8ed1-4abb-bd46-8736b9b068bd_2800x762.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!utiz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb56e94e6-8ed1-4abb-bd46-8736b9b068bd_2800x762.png" width="1456" height="396" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b56e94e6-8ed1-4abb-bd46-8736b9b068bd_2800x762.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:396,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:52886,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/178182227?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb56e94e6-8ed1-4abb-bd46-8736b9b068bd_2800x762.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!utiz!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb56e94e6-8ed1-4abb-bd46-8736b9b068bd_2800x762.png 424w, /__u/substackcdn.com/image/fetch/$s_!utiz!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb56e94e6-8ed1-4abb-bd46-8736b9b068bd_2800x762.png 848w, /__u/substackcdn.com/image/fetch/$s_!utiz!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb56e94e6-8ed1-4abb-bd46-8736b9b068bd_2800x762.png 1272w, /__u/substackcdn.com/image/fetch/$s_!utiz!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb56e94e6-8ed1-4abb-bd46-8736b9b068bd_2800x762.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In code, slots present as mechanisms like children (what&#8217;s included within the component&#8217;s tags) and tags and props like <code>footer</code> in the example below. Different platforms (like iOS and Android) and frameworks (like React, Web Components and Vue) use different syntax to accomplish the same goals.</p><pre><code><code>&lt;Card footer={&lt;Button variant="primary"&gt;Buy now&lt;/Button&gt;}&gt;
  &lt;h2&gt;Product name&lt;/h2&gt;
  &lt;p&gt;Product description&lt;/p&gt;
&lt;/Card&gt;</code></code></pre><p>Slots make components composable and adaptable, providing a predictable way to customize content while preserving control of the component&#8217;s surrounding layout, styling, and behavior. Common needs can remain configurable, yet uncommon challenges can then be solved through composition.</p><p>Yet, slots blur component boundaries. Without slots, what&#8217;s inside a component is encapsulated, unyielding beyond what you configure using props. With slots, what&#8217;s inside can include a customized design. Teams become empowered to shape what they need, and systems continue to constrain what stays consistent.</p><p>Slots also improve alignment of design structure to how code works. Component hierarchies in React, Web Components, and native libraries are likely already quite composable. Adding component slots in design tools isn&#8217;t just a boon for creativity, it improves clarity and alignment during handoff and implementation, too.</p><h2><strong>Usage</strong></h2><p>Slots can impact more components across an ecosystem than one might expect. Sure, slots apply to moderately sized components that need customization. However, they can also apply to smaller &#8220;core&#8221; components as well as layout up through layers of composition including the page.</p><h3>General slots</h3><p>Slots are most recognizable and expected in components like Modal and Card for which users already expect to compose content and structure inside. These are examples of general slots for the component&#8217;s main body, and typically corresponds the component code&#8217;s <code>children</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!ExDT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c14547-d855-460a-9d43-539bb2dfa5a7_2800x1152.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!ExDT!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c14547-d855-460a-9d43-539bb2dfa5a7_2800x1152.png 424w, /__u/substackcdn.com/image/fetch/$s_!ExDT!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c14547-d855-460a-9d43-539bb2dfa5a7_2800x1152.png 848w, /__u/substackcdn.com/image/fetch/$s_!ExDT!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c14547-d855-460a-9d43-539bb2dfa5a7_2800x1152.png 1272w, /__u/substackcdn.com/image/fetch/$s_!ExDT!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c14547-d855-460a-9d43-539bb2dfa5a7_2800x1152.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!ExDT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c14547-d855-460a-9d43-539bb2dfa5a7_2800x1152.png" width="1456" height="599" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/81c14547-d855-460a-9d43-539bb2dfa5a7_2800x1152.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:599,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:272093,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/178182227?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c14547-d855-460a-9d43-539bb2dfa5a7_2800x1152.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!ExDT!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c14547-d855-460a-9d43-539bb2dfa5a7_2800x1152.png 424w, /__u/substackcdn.com/image/fetch/$s_!ExDT!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c14547-d855-460a-9d43-539bb2dfa5a7_2800x1152.png 848w, /__u/substackcdn.com/image/fetch/$s_!ExDT!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c14547-d855-460a-9d43-539bb2dfa5a7_2800x1152.png 1272w, /__u/substackcdn.com/image/fetch/$s_!ExDT!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F81c14547-d855-460a-9d43-539bb2dfa5a7_2800x1152.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Modal and Card components with a slot for body content</figcaption></figure></div><div><hr></div><h3>Named slots</h3><p>Components name slots for multiple composable areas. For example, subtle shifts in content, styling, interactivity and layout abound in each area of a <code>Row</code> component seen stacked in feeds. Supporting each unique display as a configuration isn&#8217;t just impractical, it&#8217;s avoidable brittleness.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!TIfU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19d49737-1366-4f9f-a21c-30fcf6a32574_2800x1780.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!TIfU!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19d49737-1366-4f9f-a21c-30fcf6a32574_2800x1780.png 424w, /__u/substackcdn.com/image/fetch/$s_!TIfU!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19d49737-1366-4f9f-a21c-30fcf6a32574_2800x1780.png 848w, /__u/substackcdn.com/image/fetch/$s_!TIfU!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19d49737-1366-4f9f-a21c-30fcf6a32574_2800x1780.png 1272w, /__u/substackcdn.com/image/fetch/$s_!TIfU!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19d49737-1366-4f9f-a21c-30fcf6a32574_2800x1780.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!TIfU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19d49737-1366-4f9f-a21c-30fcf6a32574_2800x1780.png" width="1456" height="926" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/19d49737-1366-4f9f-a21c-30fcf6a32574_2800x1780.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:926,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:861128,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/178182227?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19d49737-1366-4f9f-a21c-30fcf6a32574_2800x1780.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!TIfU!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19d49737-1366-4f9f-a21c-30fcf6a32574_2800x1780.png 424w, /__u/substackcdn.com/image/fetch/$s_!TIfU!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19d49737-1366-4f9f-a21c-30fcf6a32574_2800x1780.png 848w, /__u/substackcdn.com/image/fetch/$s_!TIfU!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19d49737-1366-4f9f-a21c-30fcf6a32574_2800x1780.png 1272w, /__u/substackcdn.com/image/fetch/$s_!TIfU!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F19d49737-1366-4f9f-a21c-30fcf6a32574_2800x1780.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Row component with significant, subtle variation across all areas</figcaption></figure></div><p>Instead, the <code>Row</code> warrants named slots. This three-part layout could enable customizing independent areas: the <code>leading visual</code> on the left, the text in the middle (possibly as the general slot), and the trailing <code>actions</code> on the right.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!aHS-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb465f5-acf6-4415-ab4e-c64c38d08f26_2800x608.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!aHS-!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb465f5-acf6-4415-ab4e-c64c38d08f26_2800x608.png 424w, /__u/substackcdn.com/image/fetch/$s_!aHS-!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb465f5-acf6-4415-ab4e-c64c38d08f26_2800x608.png 848w, /__u/substackcdn.com/image/fetch/$s_!aHS-!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb465f5-acf6-4415-ab4e-c64c38d08f26_2800x608.png 1272w, /__u/substackcdn.com/image/fetch/$s_!aHS-!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb465f5-acf6-4415-ab4e-c64c38d08f26_2800x608.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!aHS-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb465f5-acf6-4415-ab4e-c64c38d08f26_2800x608.png" width="1456" height="316" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ddb465f5-acf6-4415-ab4e-c64c38d08f26_2800x608.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:316,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:44527,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/178182227?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb465f5-acf6-4415-ab4e-c64c38d08f26_2800x608.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!aHS-!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb465f5-acf6-4415-ab4e-c64c38d08f26_2800x608.png 424w, /__u/substackcdn.com/image/fetch/$s_!aHS-!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb465f5-acf6-4415-ab4e-c64c38d08f26_2800x608.png 848w, /__u/substackcdn.com/image/fetch/$s_!aHS-!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb465f5-acf6-4415-ab4e-c64c38d08f26_2800x608.png 1272w, /__u/substackcdn.com/image/fetch/$s_!aHS-!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fddb465f5-acf6-4415-ab4e-c64c38d08f26_2800x608.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Row component with slots for leading visual, trailing actions and the default content between</figcaption></figure></div><div><hr></div><h3>Slots for groups of repeating items </h3><p>Slots also improve our ability to encode nested yet flexible relationships. These are evident in group/item components like <code>Checkbox Group</code>, <code>Tabs</code>, <code>Breadcrumbs</code> and even <code>Buttons</code>. In each case, slots provide the space for an indeterminate quantity of a single, predictable type of children.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!ax0C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0c45777-0355-4f0e-aa5f-2f52e9628bcf_2800x712.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!ax0C!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0c45777-0355-4f0e-aa5f-2f52e9628bcf_2800x712.png 424w, /__u/substackcdn.com/image/fetch/$s_!ax0C!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0c45777-0355-4f0e-aa5f-2f52e9628bcf_2800x712.png 848w, /__u/substackcdn.com/image/fetch/$s_!ax0C!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0c45777-0355-4f0e-aa5f-2f52e9628bcf_2800x712.png 1272w, /__u/substackcdn.com/image/fetch/$s_!ax0C!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0c45777-0355-4f0e-aa5f-2f52e9628bcf_2800x712.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!ax0C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0c45777-0355-4f0e-aa5f-2f52e9628bcf_2800x712.png" width="1456" height="370" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e0c45777-0355-4f0e-aa5f-2f52e9628bcf_2800x712.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:370,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:92462,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/178182227?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0c45777-0355-4f0e-aa5f-2f52e9628bcf_2800x712.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!ax0C!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0c45777-0355-4f0e-aa5f-2f52e9628bcf_2800x712.png 424w, /__u/substackcdn.com/image/fetch/$s_!ax0C!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0c45777-0355-4f0e-aa5f-2f52e9628bcf_2800x712.png 848w, /__u/substackcdn.com/image/fetch/$s_!ax0C!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0c45777-0355-4f0e-aa5f-2f52e9628bcf_2800x712.png 1272w, /__u/substackcdn.com/image/fetch/$s_!ax0C!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0c45777-0355-4f0e-aa5f-2f52e9628bcf_2800x712.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><h3>Nested slots</h3><p>Nested slot relationships can span more than two levels. An Action List group could nest specific Headers and Items, and even Group those items each with a Group Header too. Each item could warrant slots for their leading and trailing visuals. Slots are everywhere, serving levels of nested composition.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!1uqj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d7335e6-3891-4430-b108-3fe5254c4c22_2800x956.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!1uqj!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d7335e6-3891-4430-b108-3fe5254c4c22_2800x956.png 424w, /__u/substackcdn.com/image/fetch/$s_!1uqj!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d7335e6-3891-4430-b108-3fe5254c4c22_2800x956.png 848w, /__u/substackcdn.com/image/fetch/$s_!1uqj!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d7335e6-3891-4430-b108-3fe5254c4c22_2800x956.png 1272w, /__u/substackcdn.com/image/fetch/$s_!1uqj!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d7335e6-3891-4430-b108-3fe5254c4c22_2800x956.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!1uqj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d7335e6-3891-4430-b108-3fe5254c4c22_2800x956.png" width="1456" height="497" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9d7335e6-3891-4430-b108-3fe5254c4c22_2800x956.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:497,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:103615,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/178182227?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d7335e6-3891-4430-b108-3fe5254c4c22_2800x956.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!1uqj!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d7335e6-3891-4430-b108-3fe5254c4c22_2800x956.png 424w, /__u/substackcdn.com/image/fetch/$s_!1uqj!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d7335e6-3891-4430-b108-3fe5254c4c22_2800x956.png 848w, /__u/substackcdn.com/image/fetch/$s_!1uqj!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d7335e6-3891-4430-b108-3fe5254c4c22_2800x956.png 1272w, /__u/substackcdn.com/image/fetch/$s_!1uqj!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9d7335e6-3891-4430-b108-3fe5254c4c22_2800x956.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Action List with a slot with two Groups, each with a slot containing three Items</figcaption></figure></div><div><hr></div><h3>Slots for higher-order layout</h3><p>Slots can apply conceptually upward through layers of reusable components to compose an entire page. You could nest a <code>Checkbox Group</code> in an <code>Accordion</code> slot. You could stack <code>Accordion</code>s in the left column slot of a reusable <code>Page row</code> layout component. You could assemble multiple <code>Page Row</code>s in a reusable <code>Product Category</code> layout pattern. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!_U7z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5cf8e4-b688-4f91-93fb-ebab564db255_7600x5656.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!_U7z!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5cf8e4-b688-4f91-93fb-ebab564db255_7600x5656.png 424w, /__u/substackcdn.com/image/fetch/$s_!_U7z!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5cf8e4-b688-4f91-93fb-ebab564db255_7600x5656.png 848w, /__u/substackcdn.com/image/fetch/$s_!_U7z!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5cf8e4-b688-4f91-93fb-ebab564db255_7600x5656.png 1272w, /__u/substackcdn.com/image/fetch/$s_!_U7z!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5cf8e4-b688-4f91-93fb-ebab564db255_7600x5656.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!_U7z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5cf8e4-b688-4f91-93fb-ebab564db255_7600x5656.png" width="1456" height="1084" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8b5cf8e4-b688-4f91-93fb-ebab564db255_7600x5656.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1084,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3797772,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/178182227?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5cf8e4-b688-4f91-93fb-ebab564db255_7600x5656.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!_U7z!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5cf8e4-b688-4f91-93fb-ebab564db255_7600x5656.png 424w, /__u/substackcdn.com/image/fetch/$s_!_U7z!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5cf8e4-b688-4f91-93fb-ebab564db255_7600x5656.png 848w, /__u/substackcdn.com/image/fetch/$s_!_U7z!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5cf8e4-b688-4f91-93fb-ebab564db255_7600x5656.png 1272w, /__u/substackcdn.com/image/fetch/$s_!_U7z!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b5cf8e4-b688-4f91-93fb-ebab564db255_7600x5656.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Nested layers of reusable components, from low-level Accordions with Checkbox Groups to higher-order page rows and layout patterns nested in a page template</figcaption></figure></div><p>That layout hat pattern, or layout component, or increasingly smaller and customized layouts and components could be included in the <code>Body</code> slot of a <code>Page</code> component. Components with slots from the Page down afford an opportunity to position layout rules, structure, and visual styling at many reusable, independently managed levels.</p><p>Time to say goodbye to countless designers detaching instances and putting in tremendous solo efforts to scaffold, build and maintain higher-order layout. </p><div><hr></div><h2><strong>Architecture</strong></h2><h3><strong>Properties</strong></h3><p>Architecting slots in a UI component includes specifying properties like:</p><ul><li><p><strong>Name</strong>, for both general &#8220;<code>default</code>&#8221; slots flowing <code>children</code> as well as specific, named slots in areas like <code>header</code>, <code>footer</code>, <code>actions</code> or <code>leading visual</code>s</p></li><li><p><strong>Description</strong>, whether guidance displayed to component users and/or spec data formalizing other properties</p></li><li><p><strong>Default value</strong> that can be a single nested instance or a deep, complicated composition to serve as a starting point and possible fallback</p></li><li><p><strong>Preferred</strong> or <strong>permitted children</strong> by both type and quantity, such as only Checkbox Items in a Checkbox Group&#8217;s slot but any quantity you need</p></li><li><p><strong>Layout</strong>, such as how slot contents arrange themselves in direction, item spacing and padding relative to the containing component</p></li></ul><div><hr></div><h3><strong>Subcomponent Parts</strong></h3><p>An increase in component slots and custom compositions within them could lead to a decrease in the need for configurable properties and a rise of more modular yet simpler <a href="/__u/nathanacurtis.substack.com/p/subcomponents-753ce9f6600a">subcomponents</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!SsYy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2a1333b-d468-485b-9899-d38b5f3729ed_3004x1066.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!SsYy!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2a1333b-d468-485b-9899-d38b5f3729ed_3004x1066.png 424w, /__u/substackcdn.com/image/fetch/$s_!SsYy!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2a1333b-d468-485b-9899-d38b5f3729ed_3004x1066.png 848w, /__u/substackcdn.com/image/fetch/$s_!SsYy!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2a1333b-d468-485b-9899-d38b5f3729ed_3004x1066.png 1272w, /__u/substackcdn.com/image/fetch/$s_!SsYy!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2a1333b-d468-485b-9899-d38b5f3729ed_3004x1066.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!SsYy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2a1333b-d468-485b-9899-d38b5f3729ed_3004x1066.png" width="1456" height="517" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d2a1333b-d468-485b-9899-d38b5f3729ed_3004x1066.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:517,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:572769,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/178182227?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2a1333b-d468-485b-9899-d38b5f3729ed_3004x1066.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!SsYy!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2a1333b-d468-485b-9899-d38b5f3729ed_3004x1066.png 424w, /__u/substackcdn.com/image/fetch/$s_!SsYy!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2a1333b-d468-485b-9899-d38b5f3729ed_3004x1066.png 848w, /__u/substackcdn.com/image/fetch/$s_!SsYy!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2a1333b-d468-485b-9899-d38b5f3729ed_3004x1066.png 1272w, /__u/substackcdn.com/image/fetch/$s_!SsYy!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd2a1333b-d468-485b-9899-d38b5f3729ed_3004x1066.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Breaking down larger components into subcomponent parts is challenging. What level(s) are better as smaller modules? At which level does each remaining configuration belong? What happens when bigger things still need to control the smaller things inside? </p><p>A Card may have reusable Title Lockup and card-specific Reviews module. It&#8217;ll be up the component user to arrange these flexible, smaller parts instead of configuring so many properties that resulted in the brittle supercomponents pursued in the past.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Nq0I!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee2c8d4-4443-4aad-9a89-5e3bd51b0cf8_2800x594.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Nq0I!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee2c8d4-4443-4aad-9a89-5e3bd51b0cf8_2800x594.png 424w, /__u/substackcdn.com/image/fetch/$s_!Nq0I!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee2c8d4-4443-4aad-9a89-5e3bd51b0cf8_2800x594.png 848w, /__u/substackcdn.com/image/fetch/$s_!Nq0I!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee2c8d4-4443-4aad-9a89-5e3bd51b0cf8_2800x594.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Nq0I!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee2c8d4-4443-4aad-9a89-5e3bd51b0cf8_2800x594.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Nq0I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee2c8d4-4443-4aad-9a89-5e3bd51b0cf8_2800x594.png" width="1456" height="309" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8ee2c8d4-4443-4aad-9a89-5e3bd51b0cf8_2800x594.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:309,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:89785,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/178182227?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee2c8d4-4443-4aad-9a89-5e3bd51b0cf8_2800x594.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Nq0I!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee2c8d4-4443-4aad-9a89-5e3bd51b0cf8_2800x594.png 424w, /__u/substackcdn.com/image/fetch/$s_!Nq0I!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee2c8d4-4443-4aad-9a89-5e3bd51b0cf8_2800x594.png 848w, /__u/substackcdn.com/image/fetch/$s_!Nq0I!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee2c8d4-4443-4aad-9a89-5e3bd51b0cf8_2800x594.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Nq0I!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8ee2c8d4-4443-4aad-9a89-5e3bd51b0cf8_2800x594.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>For a Product Card, this could mean any array of typical nested instances used in particular ways (like how to communicate discounts using a Badge) as well as primitives with conventional visual styling (like an original price, struck through).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!m7Ng!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4a57181-38a9-447f-a02a-fe6dd9631723_2800x982.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!m7Ng!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4a57181-38a9-447f-a02a-fe6dd9631723_2800x982.png 424w, /__u/substackcdn.com/image/fetch/$s_!m7Ng!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4a57181-38a9-447f-a02a-fe6dd9631723_2800x982.png 848w, /__u/substackcdn.com/image/fetch/$s_!m7Ng!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4a57181-38a9-447f-a02a-fe6dd9631723_2800x982.png 1272w, /__u/substackcdn.com/image/fetch/$s_!m7Ng!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4a57181-38a9-447f-a02a-fe6dd9631723_2800x982.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!m7Ng!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4a57181-38a9-447f-a02a-fe6dd9631723_2800x982.png" width="1456" height="511" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a4a57181-38a9-447f-a02a-fe6dd9631723_2800x982.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:511,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:131249,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://nathanacurtis.substack.com/i/178182227?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4a57181-38a9-447f-a02a-fe6dd9631723_2800x982.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!m7Ng!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4a57181-38a9-447f-a02a-fe6dd9631723_2800x982.png 424w, /__u/substackcdn.com/image/fetch/$s_!m7Ng!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4a57181-38a9-447f-a02a-fe6dd9631723_2800x982.png 848w, /__u/substackcdn.com/image/fetch/$s_!m7Ng!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4a57181-38a9-447f-a02a-fe6dd9631723_2800x982.png 1272w, /__u/substackcdn.com/image/fetch/$s_!m7Ng!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa4a57181-38a9-447f-a02a-fe6dd9631723_2800x982.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Nested instances and styled primitives used consistently for specific intents</figcaption></figure></div><div><hr></div><h3><strong>Ready-Made Examples</strong></h3><p>Equally challenging is how to equip designers and developers to put pieces together faster. With greater composition comes the need for more examples. Not just pictures, but the actual parts in ready-made examples that both express what&#8217;s possible and easily get you most of the way there.</p><p>Systems must manage examples as an additional output to enable efficiency and experimentation. Ready-made examples are neither guidance docs nor component assets; instead, these scaffolded starting points represent a distinct deliverable of both designers and developers.</p><div><hr></div><h3><strong>Key Challenges</strong></h3><p>Slots architected well and used effectively will improve flexibility, empower designers, and significantly accelerate efficiency. Slots done wrong carry consequences: undermined consistency, avoidable work, component fragmentation, design and code debt. Thoughtful design systems must carefully add slots so as to not break the promise of a consistent, high-quality and efficiently produced experience.</p><p>Adding slots throughout a catalog raises questions per component like:</p><ul><li><p><strong>Depth</strong>: How low should a slot go in the component&#8217;s hierarchy of layers/nodes?</p></li><li><p><strong>Quantity</strong>: How many slots should a component have? Just a single general slot, or many named slots, or&#8230; both?</p></li><li><p><strong>Code Alignment</strong>: How strictly should slot depth, quantity and naming match between Figma and code libraries in web, iOS and Android?</p></li><li><p><strong>Layout</strong>: How difficult will designers find it to create intricate layout <em>inside</em> slots and hand off those details to developers?</p></li><li><p><strong>Styling</strong>: How much do you style a slot and what goes inside it by wrapping it, directly setting properties of it, and/or providing inherited theming into it?</p></li><li><p><strong>Permissiveness</strong>: How constrained should slots be in what and how much they include? Can they open up gradually over time without breaking how it works?</p></li></ul><div><hr></div><p>Slots will ask more of today&#8217;s designers and developers.</p><p>Over the past decade, design systems accelerated more designers with less interface design skills to create better experiences more quickly. This enablement is in no small part due to the expansion of consistent, well crafted libraries of configurable components. Insert a component, configure its properties, arranged in a broader view to solve a problem.</p><p>Today, system users need more than props. They demand control and flexibility. That the predominant design tool of the moment &#8211; Figma &#8211; will natively support slots will push our systems towards that flexibility towards composition inside components. Ready, set, go!</p>]]></content:encoded></item><item><title><![CDATA[Analysis of Variants]]></title><description><![CDATA[Generating component data that design systems teams need]]></description><link>https://nathanacurtis.substack.com/p/analysis-of-variants-9e440c30b93e</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/analysis-of-variants-9e440c30b93e</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Tue, 07 Oct 2025 12:43:43 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ef48a966-e6bd-487c-91ba-1b44865e5d62_1920x960.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!s9SA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb1a02a3-911b-4e14-b277-6d3360fad891_1920x960.png" data-component-name="Image2ToDOM"><div class="image2-inset image2-full-screen"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!s9SA!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb1a02a3-911b-4e14-b277-6d3360fad891_1920x960.png 424w, /__u/substackcdn.com/image/fetch/$s_!s9SA!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb1a02a3-911b-4e14-b277-6d3360fad891_1920x960.png 848w, /__u/substackcdn.com/image/fetch/$s_!s9SA!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb1a02a3-911b-4e14-b277-6d3360fad891_1920x960.png 1272w, /__u/substackcdn.com/image/fetch/$s_!s9SA!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb1a02a3-911b-4e14-b277-6d3360fad891_1920x960.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!s9SA!,w_5760,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb1a02a3-911b-4e14-b277-6d3360fad891_1920x960.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fb1a02a3-911b-4e14-b277-6d3360fad891_1920x960.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;full&quot;,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-fullscreen" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!s9SA!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb1a02a3-911b-4e14-b277-6d3360fad891_1920x960.png 424w, /__u/substackcdn.com/image/fetch/$s_!s9SA!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb1a02a3-911b-4e14-b277-6d3360fad891_1920x960.png 848w, /__u/substackcdn.com/image/fetch/$s_!s9SA!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb1a02a3-911b-4e14-b277-6d3360fad891_1920x960.png 1272w, /__u/substackcdn.com/image/fetch/$s_!s9SA!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb1a02a3-911b-4e14-b277-6d3360fad891_1920x960.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>For years, we&#8217;ve toiled to maximize design system quality through collaboration from design through handoff to production. Today, our processes are boosted with AI, with component design intent hopping back and forth between codebases, LLM chats and design tools.</p><p>Through this period, our systems must improve how we get design intent out of (and back into) design tools as a part of a system&#8217;s broader pipeline. Not just efficiently, but precisely. Not just to vibe, but to record and version. Not just for us, but them (cough cough, AI) too.</p><p>If we are to use <a href="https://medium.com/@nathanacurtis/components-as-data-2be178777f21">components as data</a>, <em>how </em>do we do it without losing or degrading it as data shifts back and forth across our tools? We need a model to describe components, and tools to transform and move that description.</p><p>The <a href="https://www.figma.com/community/plugin/1549454283615386215/anova">Anova plugin</a>, recently released in the Figma community, could be a part of that process. Built as a second generation the <a href="https://www.figma.com/community/plugin/1205622541257680763/specs">Specs plugin</a> engine, the plugin produces component data with a more refined and extensible model. This post describes the plugin&#8217;s intent to output <strong>components as data</strong>, the <strong>data model</strong> it follows, and key <strong>principles</strong> that drove it&#8217;s conception and shape.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!aQ-G!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca304483-e4f0-4f54-b5e0-6c6c99a0691f_1939x854.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!aQ-G!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca304483-e4f0-4f54-b5e0-6c6c99a0691f_1939x854.png 424w, /__u/substackcdn.com/image/fetch/$s_!aQ-G!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca304483-e4f0-4f54-b5e0-6c6c99a0691f_1939x854.png 848w, /__u/substackcdn.com/image/fetch/$s_!aQ-G!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca304483-e4f0-4f54-b5e0-6c6c99a0691f_1939x854.png 1272w, /__u/substackcdn.com/image/fetch/$s_!aQ-G!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca304483-e4f0-4f54-b5e0-6c6c99a0691f_1939x854.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!aQ-G!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca304483-e4f0-4f54-b5e0-6c6c99a0691f_1939x854.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ca304483-e4f0-4f54-b5e0-6c6c99a0691f_1939x854.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!aQ-G!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca304483-e4f0-4f54-b5e0-6c6c99a0691f_1939x854.png 424w, /__u/substackcdn.com/image/fetch/$s_!aQ-G!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca304483-e4f0-4f54-b5e0-6c6c99a0691f_1939x854.png 848w, /__u/substackcdn.com/image/fetch/$s_!aQ-G!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca304483-e4f0-4f54-b5e0-6c6c99a0691f_1939x854.png 1272w, /__u/substackcdn.com/image/fetch/$s_!aQ-G!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca304483-e4f0-4f54-b5e0-6c6c99a0691f_1939x854.png 1456w" sizes="100vw"></picture><div></div></div></a></figure></div><h3>About the Anova&nbsp;plugin</h3><p>The Anova plugin creates a component specification in data form. In particular, the plugin conducts an &#8220;analysis of variants&#8221; to audit component composition, visual styling, and prop configurations across all variants.</p><p>The plugin name alludes to traditional statistical analysis of variance, and is a hat tip to my college education. Yet the plugin isn&#8217;t actually doing statistical analysis. Instead, it crawls a Figma asset to produce a result that&#8217;s deterministic, repeatable, succinct and comprehensive. This output unlocks myriad opportunities for design system pros, as described in <a href="https://medium.com/@nathanacurtis/components-as-data-2be178777f21">Components as Data</a>:</p><ol><li><p>Leverage component definitions in AI LLMs</p></li><li><p>Version component definitions over time</p></li><li><p>Analyze components across a catalog</p></li><li><p>Inspect component precision and quality</p></li><li><p>Handoff design to development</p></li><li><p>Generate documentation</p></li><li><p>Automate precise Figma asset generation (aka, the &#8220;round trip&#8221;)</p></li></ol><h3>Modeling the&nbsp;data</h3><p>The Anova plugin&#8217;s engine is a more polished and better built second generation of the <a href="https://www.figma.com/community/plugin/1205622541257680763/specs">Specs plugin</a>, which launched in 2023 and has output similar if less refined data for over a year.</p><p>The model of the plugin&#8217;s data output conforms to an <a href="https://github.com/DirectedEdges/anova/blob/main/anova.schema.json">available JSON schema</a> and can be formatted as YAML or JSON. The data includes things you expect from a spec: an anatomy of elements, props and an analysis of how structure, styles and configurations shift by variant. It also hints at things you wouldn&#8217;t expect too, like a summary of invalid variants combinations.</p><h4>Anatomy</h4><p>The <code>anatomy</code> data includes a straightforward list of elements by type as well as growing metadata (such as component dependencies).</p><pre><code>anatomy:
  root:
    type: container
  label:
    type: text
  icon:
    type: instance
    instanceOf: DS Icon</code></pre><h4>Props</h4><p>The <code>props</code> section summarizes properties including type, enums, defaults and other relevant prop information.</p><pre><code>props:
  label:
    type: string
    default: "{Label}"
  appearance:
    type: string
    default: critical
    enum:
      - critical
      - warning
      - success
      - info
  size:
    type: string
    default: large
    enum:
      - small
      - medium
      - large</code></pre><h4>Variant-by-variant analysis</h4><p>The plugin evaluates a Figma asset a variant at a time. The plugin starts wih the <code>default</code> variant, identifying each <code>element</code> of the <code>anatomy</code> that is present from the <code>root</code> component layer down through the layer hierarchy to assess layer <code>styles</code>, layout structure and other properties.</p><pre><code>default:
  elements:
    root:
      styles:
        fills: DS Color/Alert/Basic/Background filled
        cornerRadius: DS Shape/Border radius/Pill
        itemSpacing: DS Space/Item spacing/0_5x
        paddingLeft: DS Space/Padding/0_5x
        paddingRight: DS Space/Padding/0_5x
        paddingTop: DS Space/Padding/0_25x
        paddingBottom: DS Space/Padding/0_25x
    label:
      styles:
        fills: DS Color/Text/Primary
        textStyleId: Body/Large
      propReferences:
        characters:
          $ref: "#/props/Label"</code></pre><p>From that established <code>default</code>, successive variants are evaluated, compared to other variants serving as baselines, and reduced into a succinct spec across all variants.</p><pre><code>variants:
  - configuration:
      size: small
    elements:
      root:
        styles:
          itemSpacing: DS Space/Item spacing/0_25x
          paddingLeft: DS Space/Padding/0_25x
          paddingRight: DS Space/Padding/0_25x
          paddingTop: DS Space/Padding/0_125x
          paddingBottom: DS Space/Padding/0_125x
      label:
        styles:
          textStyleId: Body/Small
  - configuration:
      appearance: success
    elements:
      root:
        styles:
          fills: DS Color/Alert/Success/Element
      label:
        styles:
          fills: DS Color/Text/Primary Inverse</code></pre><p>From the resulting <code>variants</code> data, you can layers <code>styles</code> and other data based on one or more matched <code>configurations</code> in a manner very similar to CSS&#8217; cascade.</p><p>For example, if this component was configured as both <code>size:small</code> and <code>type:success</code>, then the data would layer in three matches (the <code>default</code> then matches for <code>size</code> and <code>type</code>) to resolve as:</p><pre><code>elements:
  root:
    styles:
      fills: DS Color/Alert/Success/Element
      cornerRadius: DS Shape/Border radius/Pill
      itemSpacing: DS Space/Item spacing/0_25x
      paddingLeft: DS Space/Padding/0_25x
      paddingRight: DS Space/Padding/0_25x
      paddingTop: DS Space/Padding/0_125x
      paddingBottom: DS Space/Padding/0_125x
  label:
    styles:
      fills: DS Color/Text/Primary Inverse
      textStyleId: Body/Small    </code></pre><h4>Invalid variant combinations</h4><p>The <code>invalidVariantCombinations</code> section summarizes prop combinations that are invalid based on the Figma asset. For example, an interactive component typically cannot be <code>disabled</code> and <code>hover</code> at the same time. Depending on how you&#8217;ve built your component in Figma, those combinations can be determined and summarized.</p><pre><code>invalidConfigurations:
  - disabled: true
    state: hover
  - disabled: true
    state: active
  - disabled: true
    focused: true</code></pre><h3>Principles</h3><p>Extensibility, interoperability, validation, and portability are table stakes for any data structure. On top of that, four more principles drove decisions: determinism, completeness, succinctness, and human-readability.</p><h4>&#9989; Deterministic instead of stochastic</h4><p><strong>The problem:</strong> Data extracted from Figma&#8217;s Dev Mode MCP Server is impressive, but isn&#8217;t designed to produce a durable spec unless your spec is a React and Tailwind implementation. The extracted data, transformed further via LLMs, yields unpredictable results: sometimes imprecise, often incomplete, and frustratingly different run to run.</p><p>For example, I&#8217;ve observed an LLM starting with an <code>Alert</code> component&#8217;s <code>appearance:success|critical|warning|info</code> property behaving unpredictably. Over repeated runs, it renamed options (<code>information</code>), added options (<code>neutral</code>), remove options (<code>warning</code>) and renamed the property itself (to <code>type</code> or <code>variant</code>)! A design system can&#8217;t rely on an unstable workflow for a canonical component description.</p><pre><code>props:
  appearance:
    type: string
    default: critical
    enum:
      - critical
      - warning
      - success
      - info</code></pre><p><strong>The plugin&#8217;s approach:</strong> The plugin extracts only the raw, intentional data directly from the asset. No guessing. No machine prediction. The same input yields the same output, every time. And each time, it&#8217;s easy to compare it to past versions to affirm and commit to the differences. You designed it to be <code>appearance:success|critical|warning|info</code>, so you get <code>appearance:success|critical|warning|info</code>.</p><h4>&#9989; Complete instead of&nbsp;partial</h4><p><strong>The problem:</strong> The data derived from <a href="https://www.figma.com/community/plugin/1205622541257680763/specs">Specs Figma plugin</a> ouptut is powerful. People upload screenshots of it to LLMs and it kinda works! However, it evaluates prop effects in isolation. It doesn&#8217;t inspect every variant in depth to find every potential effect on style and structure.</p><p>For example, it&#8217;s easier to document a component&#8217;s background color when <code>hover:true</code> or <code>selected:true</code>. How about when <em>both</em> are true? How about when both are true, and the component is also set to <code>appearance:info</code>? Did the component change more? These interactions are rare and harder to analyze, but they shouldn&#8217;t be missed by a shallow analysis.</p><pre><code>variants:
  - configuration:
      hover: true
    elements:
      root:
        styles:
          backgroundColor: (a color)
  - configuration:
      hover: true
      selected: true
    elements:
      root:
        styles:
          backgroundColor: (a second color)
  - configuration:
      hover: true
      selected: true
      appearance: info
    elements:
      root:
        styles:
          backgroundColor: (a third color)</code></pre><p><strong>The plugin&#8217;s approach:</strong> The plugin can inspect every variant in-depth and then reduce what&#8217;s accumulated into a set of matches that layer into a rendered style. Instead of disjointed snapshots relying on one prop, you get the entire picture no matter the (valid) prop combination.</p><h4>&#9989; Succinct instead of&nbsp;bloated</h4><p><strong>The problem: </strong>Figma provides access to a complete picture of component assets via its REST API. Unfortunately, its variant architecture is very bloated. To express a <code>disabled:true</code> state for a component like <code>Text Input</code>, could mean 24 more variants each with ~15 layers per variant each with ~40 properties.</p><p>Ask Figma&#8217;s REST API for component information, and you&#8217;ll get 14,400 additional properties in hierarchical data! 99.99% of that data tells you nothing new, but it needs to be processed and examined to make sure. All because a designer expressed a simple intent of &#8220;When disabled, set the root layer&#8217;s opacity to <code>0.36</code>.&#8221;</p><pre><code>variants:
  - configuration:
      disabled: true
    elements:
      root:
        styles:
          opacity: 0.36</code></pre><p><strong>The plugin&#8217;s approach:</strong> Instead of duplicating entire variants, it records only the difference: <em>what changes when disabled</em>. That&#8217;s compact, lossless, and easier to maintain.</p><h4>&#9989; Human-readable instead of gobbledygook</h4><p><strong>The problem:</strong> Even if you get deterministic and complete data, it&#8217;s usually encoded in ways that only a machine can love&#8202;&#8212;&#8202;long and noisy JSON dumps with no obvious hierarchy of what matters.</p><pre><code>title: {component name}
anatomy:
  {element name}:
     type: {type}
     instanceOf: {main component name}
  ...
props:
  {prop name}:
     type: {type}
     default: {default}
  ...
default:
  elements:
    {element name}:
       styles:
         {style name}: {value}
variants:
  - configuration:
      {prop name}: {value}
    elements:
      {element name}:
        styles:
          {style name}: {value}</code></pre><p><strong>The plugin&#8217;s approach:</strong> Outputs are structured so a human can scan them. Defaults come first. Overrides are grouped by condition. Names are consistent. Reading the data feels like reading a spec.</p><p>I&#8217;ll acknowledge right now that designers aren&#8217;t in love with reading a spec as data. It does require onboarding (a few good docs rich with examples seem to be enough). Yet, I&#8217;ve been pleasantly surprised at how quickly specs-as-data sprout up next to assets. It&#8217;s value becomes even clearer when Figma comments start showing up above the spec rather than asset to get things done.</p><p>Ideally, if Anova data proves valuable to the community, the plugin could go in many directions. At the forefront, I&#8217;d expect to integrate this new processing engine into the Specs plugin (or vice versa, overlaying the spec outputs onto Anova) in the future, consolidating the two.</p><p>I also can&#8217;t imagine this living long without strong, direct integration with other tools. This suggests that MCP server and/or Figma REST API integration could prove useful directions to pursue. Yet, for now, it&#8217;s certainly useful enough to share, get feedback, and grow.</p>]]></content:encoded></item><item><title><![CDATA[Components as Data]]></title><description><![CDATA[How to define components independent of platforms to scale a system&#8217;s impact]]></description><link>https://nathanacurtis.substack.com/p/components-as-data-2be178777f21</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/components-as-data-2be178777f21</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Tue, 23 Sep 2025 17:00:51 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/46e029b6-b910-4f02-aa9c-8a9a9025695f_2560x1440.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4>How to define components independent of platforms to scale a system&#8217;s&nbsp;impact</h4><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!XUV3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233b37d3-0de8-4c24-ba81-d337af63cc1a_2560x1440.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!XUV3!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233b37d3-0de8-4c24-ba81-d337af63cc1a_2560x1440.png 424w, /__u/substackcdn.com/image/fetch/$s_!XUV3!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233b37d3-0de8-4c24-ba81-d337af63cc1a_2560x1440.png 848w, /__u/substackcdn.com/image/fetch/$s_!XUV3!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233b37d3-0de8-4c24-ba81-d337af63cc1a_2560x1440.png 1272w, /__u/substackcdn.com/image/fetch/$s_!XUV3!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233b37d3-0de8-4c24-ba81-d337af63cc1a_2560x1440.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!XUV3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233b37d3-0de8-4c24-ba81-d337af63cc1a_2560x1440.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/233b37d3-0de8-4c24-ba81-d337af63cc1a_2560x1440.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!XUV3!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233b37d3-0de8-4c24-ba81-d337af63cc1a_2560x1440.png 424w, /__u/substackcdn.com/image/fetch/$s_!XUV3!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233b37d3-0de8-4c24-ba81-d337af63cc1a_2560x1440.png 848w, /__u/substackcdn.com/image/fetch/$s_!XUV3!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233b37d3-0de8-4c24-ba81-d337af63cc1a_2560x1440.png 1272w, /__u/substackcdn.com/image/fetch/$s_!XUV3!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F233b37d3-0de8-4c24-ba81-d337af63cc1a_2560x1440.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>Nearly a decade ago, I wrote of my passions stirred by crafting <a href="https://medium.com/eightshapes-llc/tokens-in-design-systems-25dd82d58421">tokens in design systems</a>. Those (sub?)atomic, minimal decisions were invigorating as we put structure to visual choices as data to spread across a system. The muse of that story? The <code>Pill</code> component.</p><p>This year, my team initiated a catalog-wide component-by-component refactor. This time, again, we started with the <code>Pill</code> component. It&#8217;s as if the <code>Pill</code> offers us a choice: see the truth of our explicit decisions, or stay in an illusion that manual handoffs and divergent tools carry our intentions into the work of others without failure. Ok, maybe that&#8217;s a bit heavy handed. Enough with the heady metaphors.</p><p>Throughout the project, my role is to architect how we record component decisions as structured data independent of any platform, including Figma. I&#8217;m responsible for ensuring consistent, scalable, and interoperable components that flow into and from Figma and a pipeline of generated, cross-platform code. It&#8217;s delightfully complicated. Tokens feels quaint by comparison.</p><p>This slot prop. That container element. Both are familiar and feel simple. Yet conveying visibility and children from one to the other, binding and unbinding references across an array of variants? That hits different. Chats evoke nullability. We&#8217;re overdosing on overloading. Figma&#8217;s threshold of what you can express and how you express it feels a barrier. Huh, hold up. What&#8217;s&nbsp;&#8230; nullability?</p><p>These days, I live much more in a text editor than a UI to plan, design, validate and deliver components as data with AI at my side. In this post, I provide a glimpse of components expressed as data and follow with why treating using data matters across a component&#8217;s life cycle in the era of AI.</p><h3>Defining Components in&nbsp;Data</h3><p>A component definition in data is a structured description of a UI component expressed in a neutral format (like YAML or JSON) instead of hard-coded in design tools or platform-specific code. Data breaks a component into parts like an anatomy of elements, props, styles, layout and how each varies when configurations change.</p><h4>Anatomy</h4><p>A component&#8217;s elements of various types (like <code>container</code>) organized into a hierarchy comprise its anatomy. Element concepts correspond to platform-specific constructs, such as a Figma <code>FRAME</code> layer or HTML <code>DIV</code>, <code>SPAN</code>, or <code>SECTION</code>.</p><pre><code>anatomy:
  root:
    type: container
  content:
    type: container
  leadingVisual:
    type: slot
  label:
    type: text</code></pre><h4>Props</h4><p>Props to configure a component&#8217;s behavior and appearance and can be various data types, such as booleans, strings, enums or slots.</p><pre><code>props:
  disabled:
    type: boolean
    default: false
  selected:
    type: boolean
    default: false
  state:
    type: string
    default: rest
    enum:
      - rest
      - hover
      - active
  leadingVisual:
    type: slot
    nullable: true
    oneOf:
      - icon
      - avatar
      - image
  label:
    type: string
    default: Label
  accessibilityLabel:
    type: string</code></pre><p>Within a seemingly simple prop list, subtleties complicate conversations for designers expressing ideas in Figma.</p><ul><li><p>Aren&#8217;t <code>disabled</code> and <code>selected</code> technically enumerated <code>VARIANT</code> props with enumerated values for <code>true</code> and <code>false</code>? <em>Yes.</em></p></li><li><p>Is <code>leadingVisual</code> an <code>INSTANCE_SWAP</code> prop, and don&#8217;t we need another <code>BOOLEAN</code> prop to control its visibility? <em>Yes (that&#8217;s how slots work today in Figma) and yes (the need for a <code>BOOLEAN</code> relates to the <code>nullable</code> property).</em></p></li><li><p>How do we even represent accessibility labels? <em>Expose a <code>TEXT</code> prop in the Props panel but not visually. There&#8217;s a trick for that.</em></p></li></ul><p>Those conversations highlight the act of translating a component definition to a platform, in this case Figma.</p><h4>Styles</h4><p>Styling is directly expressed in data in a human-readable way, too.</p><pre><code>default:
  elements:
    root:
      children:
        - content
      styles:
        height: foundations/size/8x
        backgroundColor: foundations/color/surface/primary
        borderColor: foundations/color/outline/primary
        borderWeight: foundations/size/0_25x
        verticalAlign: CENTER
        itemSpacing: 4
        paddingLeft: foundations/spacing/4x
        paddingRight: foundations/spacing/4x
        layoutDirection: HORIZONTAL
        layoutSizingHorizontal: HUG
        cornerRadius: foundations/shape/circle</code></pre><p>Here, a <code>root</code> element (in Figma parlance, the <code>COMPONENT</code> or <code>INSTANCE</code> layer) has a range of <code>default</code> styles that mix <strong>raw</strong> values (<code>4</code>, <code>HUG</code>) and <strong>token </strong>references (<code>foundations/size/8x</code>).</p><p>Yet, the element also omits presumed <strong>initial values </strong>(<code>paddingTop: 0</code>) and has <strong>implied values</strong> too (<code>layoutSizingVertical</code> must be <code>FIXED</code> because <code>height</code> is set). Even within styling alone, our team&#8217;s vocabulary must level up to describe concepts we&#8217;ve implicitly used before but never named.</p><h4>Variants</h4><p>Things get more interesting as prop configurations apply. In this simple example, a <code>Pill</code>'s <code>hover</code> state changing the <code>root</code>&#8217;s background color.</p><pre><code>variants:
  - configuration:
      state: hover
    elements:
      root:
        styles:
          backgroundColor: foundations/color/interactive/hover</code></pre><p>Yet, <code>variants</code> can get complicated quickly, with two or more <code>props</code> interacting in a <code>configuration</code> to impact many <code>element</code>s at a time.</p><h4>Broad, Detailed and yet Incomplete</h4><p>When put together, these models combine to form a fuller picture of a component, in a structure like:</p><pre><code>{component name}:
  anatomy:
    {element name}
    ...
  props:
    {property name}
    ...
  default:
    {element name}:
      styles:
        {style name}: {style value}
    ...
  variants:
    - configuration:
        {prop name}: {nondefault prop value}
        ...
      elements:
        {element name}:
          styles:
            {style name}: {style value}
     ...</code></pre><p>Simple components (<code>Divider</code> &#128064;) may only need 20&#8211;50 lines of data. On the other hand, sophisticated core component like <code>Alert</code>, <code>Text Input</code> or <code>Card</code> often require 500 lines or more.</p><p>Yet, even with over 1,000 lines of data, a picture could remain incomplete, lacking considerations like:</p><ul><li><p><strong>Binding</strong> configurations to an element&#8217;s values</p></li><li><p><strong>Motion</strong> and nontrivial <strong>Interaction</strong> that designers <em>could</em> express in Figma (using <a href="https://www.figma.com/plugin-docs/api/properties/nodes-reactions/"><code>reactions</code></a>) but rarely do.</p></li><li><p><strong>Accessibility </strong>that Figma lacks the ability to express in a structured way, although plugins help with that.</p></li><li><p><strong>Non-visual configurations</strong>, such as an <code>Alert</code>'s <code>autohide</code> duration or <code>TextArea</code>'s <code>maxRows</code> that a designer could decide for handoff.</p></li></ul><p>Varyingly, teams expand the shape of data to include more and more of these considerations through a combination of Figma capabilities, plugins and team-specific conventions. That said, teams continue to pair component data with a separate, unstructured document to &#8220;handoff&#8221; a complete component definition. For now, anyway.</p><h4>A component catalog</h4><p>Teams produce, store and version data for an entire component catalog in a database or (usually, in my experience) as a JSON or YAML file.</p><pre><code>components:
  alert:
    ...
  banner:
    ...
  breadcrumb:
    ...
  button:
    ...
  card:
    ...
  icon:
    ...
  iconButton:
    ...
  pill:
    ...
  tabs:
    ...
  textArea:
    ...
  textInput:
    ...</code></pre><p>A <code>core.yaml</code> file for a design system&#8217;s core components may include 30&#8211;50 components (and their <code>subcomponents</code>, too) and be 10,000s lines long. Want to store a component per file? Sure, tool it up that way. Want to separate concerns of component API from theming via tokens? Sure, as you will. You decide.</p><h3>The Impact of Components as&nbsp;Data</h3><p>Definining components in data form rather than passing unstructured artifacts between collaborators unlocks many opportunities across a component&#8217;s life cycle.</p><h4>Leverage components in&nbsp;LLMs</h4><p>AI is everywhere, and it favors structured data. So express components that way. An LLM can answer questions about how the component works, compare it to implementations, and propose improvements via prompts.</p><p>Sure, you could leverage Figma&#8217;s Dev Mode MCP Server. But beware: that&#8217;s a stochastic, incomplete, and imprecise component description biased towards one platform (like React) and framework (like Tailwind). More formally approaching component data makes component knowledge reusable, scalable, and consistently interpretable across contexts.</p><h4>Inspect component precision and&nbsp;quality</h4><p>With countless design decisions woven into our Figma assets, it can be hard to wire up every detail without errors. Data exposes errant design decisions, making components easier to audit.</p><pre><code>variants:
  - configuration:
      state: hover
    elements:
      root:
        styles:
          backgroundColor: #045bbc  ## Seriously? Token please!</code></pre><p>If I had a nickel for every time I detected a raw value in a stray variant when a token is needed (like the hover <code>backgroundColor</code> above), I&#8217;d be rich. Seeing components as data make inspection straightforward and precise, raising the quality of both design and code implementations.</p><h4>Generate components across code platforms</h4><p>Instead of hard-coded spec documents or screenshots, developers receive machine-readable definitions. These definitions of structure, styles, and prop behaviors can be used to scaffold code directly. This reduces or even eliminates back-and-forth to ensures product matches design intent.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!YX7_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08acdfb0-1869-4ba6-bc6f-1e4fe5ecabe3_800x331.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!YX7_!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08acdfb0-1869-4ba6-bc6f-1e4fe5ecabe3_800x331.png 424w, /__u/substackcdn.com/image/fetch/$s_!YX7_!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08acdfb0-1869-4ba6-bc6f-1e4fe5ecabe3_800x331.png 848w, /__u/substackcdn.com/image/fetch/$s_!YX7_!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08acdfb0-1869-4ba6-bc6f-1e4fe5ecabe3_800x331.png 1272w, /__u/substackcdn.com/image/fetch/$s_!YX7_!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08acdfb0-1869-4ba6-bc6f-1e4fe5ecabe3_800x331.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!YX7_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08acdfb0-1869-4ba6-bc6f-1e4fe5ecabe3_800x331.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/08acdfb0-1869-4ba6-bc6f-1e4fe5ecabe3_800x331.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!YX7_!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08acdfb0-1869-4ba6-bc6f-1e4fe5ecabe3_800x331.png 424w, /__u/substackcdn.com/image/fetch/$s_!YX7_!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08acdfb0-1869-4ba6-bc6f-1e4fe5ecabe3_800x331.png 848w, /__u/substackcdn.com/image/fetch/$s_!YX7_!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08acdfb0-1869-4ba6-bc6f-1e4fe5ecabe3_800x331.png 1272w, /__u/substackcdn.com/image/fetch/$s_!YX7_!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08acdfb0-1869-4ba6-bc6f-1e4fe5ecabe3_800x331.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Workflow translating Figma assets into data as machine-readable inputs to generate&nbsp;code</figcaption></figure></div><h4>Generate Figma assets,&nbsp;too</h4><p>And this isn&#8217;t just for code implementations. Teams generate Figma assets too. Soon to be gone are the tedious, manual hours to produce countless variants.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!75tL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4785399-3776-4b51-b5bf-ba7bded557a0_800x442.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!75tL!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4785399-3776-4b51-b5bf-ba7bded557a0_800x442.png 424w, /__u/substackcdn.com/image/fetch/$s_!75tL!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4785399-3776-4b51-b5bf-ba7bded557a0_800x442.png 848w, /__u/substackcdn.com/image/fetch/$s_!75tL!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4785399-3776-4b51-b5bf-ba7bded557a0_800x442.png 1272w, /__u/substackcdn.com/image/fetch/$s_!75tL!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4785399-3776-4b51-b5bf-ba7bded557a0_800x442.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!75tL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4785399-3776-4b51-b5bf-ba7bded557a0_800x442.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e4785399-3776-4b51-b5bf-ba7bded557a0_800x442.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!75tL!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4785399-3776-4b51-b5bf-ba7bded557a0_800x442.png 424w, /__u/substackcdn.com/image/fetch/$s_!75tL!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4785399-3776-4b51-b5bf-ba7bded557a0_800x442.png 848w, /__u/substackcdn.com/image/fetch/$s_!75tL!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4785399-3776-4b51-b5bf-ba7bded557a0_800x442.png 1272w, /__u/substackcdn.com/image/fetch/$s_!75tL!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4785399-3776-4b51-b5bf-ba7bded557a0_800x442.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Starting with data and treating Figma assets as output rather than&nbsp;input</figcaption></figure></div><p>Instead, Figma component assets can be automated from a component definition in data that I plan in an hour and iterate with teammates for another. While we may go back and forth between Figma and data to refine and experiment, designers are increasingly focusing on architecture more and pointing and clicking and dragging and setting values in the Figma UI less.</p><h4>Generate examples and documentation</h4><p>The same data can be used to automatically create component reference pages, usage guidelines, and visual previews. This removes the need for manually maintaining documentation that quickly falls out of sync. As components evolve, the documentation updates with them, staying consistent and trustworthy.</p><h4>Version component definitions over&nbsp;time</h4><p>Component definitions as structured data be tracked in version control systems like Git. This allows teams to see how components evolve, compare differences, and roll back if necessary. It creates a durable record of a component&#8217;s lifecycle, just like other source code.</p><h4>Analyze components across a&nbsp;catalog</h4><p>With many components defined in the same format, you can prompt AI to find patterns and gaps like:</p><blockquote><p>How and how often is the <em><code>foundations/color/surface/secondary</code></em> token used?<br>Are enumerated options for <em><code>state</code></em> handled consistently?<br>Are <em><code>accessibilityLabels</code></em> applied across all potential cases?</p></blockquote><p>This enables data-driven insights into a system&#8217;s health and coverage.</p><p>As an architect at heart, I&#8217;m so excited that my work has evolved into increasingly formal structures to describe UI components. This era of AI demands that we shift and evolve how design systems work. It&#8217;s difficult to imagine returning to a time when I architected components only in a visual tool like Figma. Instead, my mind races faster seeing those impassioned decisions as data, moving through the connections we create.</p>]]></content:encoded></item><item><title><![CDATA[Purposeful vs Aesthetic Naming]]></title><description><![CDATA[Favoring semantics isn&#8217;t always ideal, and blending both is worse]]></description><link>https://nathanacurtis.substack.com/p/purposeful-vs-aesthetic-naming-4390870ef463</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/purposeful-vs-aesthetic-naming-4390870ef463</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Mon, 23 Jun 2025 12:46:56 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/febd2300-d5df-442f-81ee-9395216fafaa_2560x1070.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4>Favoring semantics isn&#8217;t always ideal, and blending both is&nbsp;worse</h4><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!sIO2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3726023f-abb0-4cf4-a11c-7e67b80a9e83_2560x1070.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!sIO2!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3726023f-abb0-4cf4-a11c-7e67b80a9e83_2560x1070.png 424w, /__u/substackcdn.com/image/fetch/$s_!sIO2!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3726023f-abb0-4cf4-a11c-7e67b80a9e83_2560x1070.png 848w, /__u/substackcdn.com/image/fetch/$s_!sIO2!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3726023f-abb0-4cf4-a11c-7e67b80a9e83_2560x1070.png 1272w, /__u/substackcdn.com/image/fetch/$s_!sIO2!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3726023f-abb0-4cf4-a11c-7e67b80a9e83_2560x1070.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!sIO2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3726023f-abb0-4cf4-a11c-7e67b80a9e83_2560x1070.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3726023f-abb0-4cf4-a11c-7e67b80a9e83_2560x1070.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!sIO2!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3726023f-abb0-4cf4-a11c-7e67b80a9e83_2560x1070.png 424w, /__u/substackcdn.com/image/fetch/$s_!sIO2!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3726023f-abb0-4cf4-a11c-7e67b80a9e83_2560x1070.png 848w, /__u/substackcdn.com/image/fetch/$s_!sIO2!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3726023f-abb0-4cf4-a11c-7e67b80a9e83_2560x1070.png 1272w, /__u/substackcdn.com/image/fetch/$s_!sIO2!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3726023f-abb0-4cf4-a11c-7e67b80a9e83_2560x1070.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a><figcaption class="image-caption">What is orange,&nbsp;anyway?</figcaption></figure></div><p>Our design system effort was gaining momentum, and we&#8217;d reached a crossroads I&#8217;d seen coming a mile away.</p><p>&#8220;So, your main, most important <code>brand</code> color is <code>red</code>?&#8221; I asked.</p><p>&#8220;Yes,&#8221; the collaborator replied calmly.</p><p>&#8220;Then, what color will we use for <code>error</code>s?&#8221;</p><p>&#8220;<code>Red</code>,&#8221; they answered decisively.</p><p>&#8220;The <em>same</em> <code>red</code>?&#8221;</p><p>&#8220;Yes.&#8221;</p><p>&#8220;Got it. In mockups everywhere, I also see <em>that </em><code>red</code> used to distinguish a <code>sale</code> price. So, we communicate things are on <code>sale</code> with&nbsp;&#8230; <em>that </em><code>red</code> too?&#8221;</p><p>&#8220;Yes.&#8221;</p><p>&#8220;Ok, to be sure. Imagine I&#8217;m designing for a product that&#8217;s on sale, and the user configures an invalid quantity. In tight proximity, the UI will signal three things (<code>brand</code>, <code>sale</code>, <code>error</code>) all with the <em>same </em><code>red</code>?&#8221;</p><p>&#8220;Yes.&#8221;</p><p>This tension between visual aesthetics and purposeful intent appears throughout interface design&#8202;&#8212;&#8202;in tokens, composition, and, as this article explores, component props and options.</p><p>In this post, I&#8217;ll contrast <strong>purposeful vs aesthetic naming</strong> schemes for component properties, describe <strong>hybrid approaches</strong> that are best avoided, and conclude with <strong>related techniques</strong> that are sometimes brought to bear.</p><h3>Comparing purposeful and aesthetic naming</h3><p>Consider a <code>Badge</code> component that can appear in different colors&nbsp;: <code>red</code>, <code>green</code>, <code>blue</code>, <code>yellow</code>, <code>white</code>, and <code>gray</code>. How should this visual variation be controlled? Typically, you create a set of options based on either purpose or aesthetics.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!7S71!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1bf2a-34a7-4e3f-8343-4cf1a5049a32_800x204.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!7S71!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1bf2a-34a7-4e3f-8343-4cf1a5049a32_800x204.png 424w, /__u/substackcdn.com/image/fetch/$s_!7S71!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1bf2a-34a7-4e3f-8343-4cf1a5049a32_800x204.png 848w, /__u/substackcdn.com/image/fetch/$s_!7S71!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1bf2a-34a7-4e3f-8343-4cf1a5049a32_800x204.png 1272w, /__u/substackcdn.com/image/fetch/$s_!7S71!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1bf2a-34a7-4e3f-8343-4cf1a5049a32_800x204.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!7S71!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1bf2a-34a7-4e3f-8343-4cf1a5049a32_800x204.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/07a1bf2a-34a7-4e3f-8343-4cf1a5049a32_800x204.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!7S71!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1bf2a-34a7-4e3f-8343-4cf1a5049a32_800x204.png 424w, /__u/substackcdn.com/image/fetch/$s_!7S71!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1bf2a-34a7-4e3f-8343-4cf1a5049a32_800x204.png 848w, /__u/substackcdn.com/image/fetch/$s_!7S71!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1bf2a-34a7-4e3f-8343-4cf1a5049a32_800x204.png 1272w, /__u/substackcdn.com/image/fetch/$s_!7S71!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F07a1bf2a-34a7-4e3f-8343-4cf1a5049a32_800x204.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">A Badge component of various&nbsp;colors</figcaption></figure></div><h4>Purposeful options</h4><p>Purposeful props use specific, self-documenting values that convey narrow meaning and intent. For example, a <code>Badge</code> may be offer choices like <code>error</code>, <code>success</code>, <code>info</code>, <code>warning</code> and <code>new</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!gDPZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8db642b1-6cae-4c38-8967-d803fbad8de5_800x475.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!gDPZ!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8db642b1-6cae-4c38-8967-d803fbad8de5_800x475.png 424w, /__u/substackcdn.com/image/fetch/$s_!gDPZ!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8db642b1-6cae-4c38-8967-d803fbad8de5_800x475.png 848w, /__u/substackcdn.com/image/fetch/$s_!gDPZ!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8db642b1-6cae-4c38-8967-d803fbad8de5_800x475.png 1272w, /__u/substackcdn.com/image/fetch/$s_!gDPZ!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8db642b1-6cae-4c38-8967-d803fbad8de5_800x475.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!gDPZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8db642b1-6cae-4c38-8967-d803fbad8de5_800x475.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8db642b1-6cae-4c38-8967-d803fbad8de5_800x475.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!gDPZ!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8db642b1-6cae-4c38-8967-d803fbad8de5_800x475.png 424w, /__u/substackcdn.com/image/fetch/$s_!gDPZ!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8db642b1-6cae-4c38-8967-d803fbad8de5_800x475.png 848w, /__u/substackcdn.com/image/fetch/$s_!gDPZ!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8db642b1-6cae-4c38-8967-d803fbad8de5_800x475.png 1272w, /__u/substackcdn.com/image/fetch/$s_!gDPZ!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8db642b1-6cae-4c38-8967-d803fbad8de5_800x475.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Purposeful options</figcaption></figure></div><p>Purposeful naming focuses on <strong>what role a component serves</strong>, which approach offers several compelling advantages:</p><ol><li><p><strong>Self-documenting intent</strong>: When you see <code>severity="error"</code>, you immediately understand component purpose without needing to reference docs or examples. The prop tells a clear story of intent.</p></li><li><p><strong>Consistency across contexts</strong>: Purpose-driven props ensure that all &#8220;error&#8221; states look and behave consistently across components to create a more cohesive user experience.</p></li><li><p><strong>Durability across redesigns</strong>: Visual treatments change, but semantic meaning tends to remain stable. A component using <code>variant="warning"</code> will survive brand refreshes better than one tied to <code>color="yellow"</code>.</p></li><li><p><strong>Built-in accessibility</strong>: Purpose-driven naming naturally supports accessibility considerations, such as screen readers announcing information like &#8220;error status&#8221; rather than just &#8220;red badge.&#8221;</p></li></ol><h4>Aesthetic options</h4><p>Aesthetic-driven options use visual terms like color (<code>red</code>) or scale (<code>1X</code>,&nbsp;&#8230;) that lack semantic intent.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!8ORg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6cf41bc-5ae0-4495-b77a-7bda58360871_800x666.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!8ORg!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6cf41bc-5ae0-4495-b77a-7bda58360871_800x666.png 424w, /__u/substackcdn.com/image/fetch/$s_!8ORg!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6cf41bc-5ae0-4495-b77a-7bda58360871_800x666.png 848w, /__u/substackcdn.com/image/fetch/$s_!8ORg!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6cf41bc-5ae0-4495-b77a-7bda58360871_800x666.png 1272w, /__u/substackcdn.com/image/fetch/$s_!8ORg!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6cf41bc-5ae0-4495-b77a-7bda58360871_800x666.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!8ORg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6cf41bc-5ae0-4495-b77a-7bda58360871_800x666.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a6cf41bc-5ae0-4495-b77a-7bda58360871_800x666.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!8ORg!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6cf41bc-5ae0-4495-b77a-7bda58360871_800x666.png 424w, /__u/substackcdn.com/image/fetch/$s_!8ORg!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6cf41bc-5ae0-4495-b77a-7bda58360871_800x666.png 848w, /__u/substackcdn.com/image/fetch/$s_!8ORg!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6cf41bc-5ae0-4495-b77a-7bda58360871_800x666.png 1272w, /__u/substackcdn.com/image/fetch/$s_!8ORg!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa6cf41bc-5ae0-4495-b77a-7bda58360871_800x666.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Aesthetic options</figcaption></figure></div><p>Aesthetic naming isn&#8217;t wrong&#8202;&#8212;&#8202;it serves different needs and contexts like:</p><ol><li><p><strong>Visual control and flexibility</strong>: Designers may need flexible control over appearance that doesn&#8217;t map neatly to semantics. Sometimes you need a light gray divider, and forcing semantic meaning feels artificial.</p></li><li><p><strong>Decorative use</strong>: Some components serve purely visual roles where structural meaning is secondary, irrelevant or not yet defined.</p></li><li><p><strong>Migration and legacy support</strong>: When retrofitting design systems onto existing products, aesthetic props can ease the transition by matching appearances that already exist.</p></li><li><p><strong>Coverage over semantic gaps</strong>: Sometimes semantics simply don&#8217;t exist yet, or the use case is too specific to warrant a semantic abstraction.</p></li></ol><h4>Comparative examples across visual properties</h4><p>This choice of between purpose versus aesthetic structures arises often across components for characteristics beyond just <code>color</code>, such as varying:</p><ul><li><p><strong>Text input</strong>&#8217;s <code>border</code> weight to create more or less <code>minimal</code> look</p></li><li><p><strong>Card</strong>&#8217;s <code>shadow</code> strength to create a <code>raised</code> or <code>overlay</code> appearance</p></li><li><p><strong>Text</strong>&#8217;s <code>font </code>attributes to imply text role, hierarchy and structure</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!rEoj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a1ba9e5-6bc4-4631-94da-9195e040aff6_800x692.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!rEoj!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a1ba9e5-6bc4-4631-94da-9195e040aff6_800x692.png 424w, /__u/substackcdn.com/image/fetch/$s_!rEoj!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a1ba9e5-6bc4-4631-94da-9195e040aff6_800x692.png 848w, /__u/substackcdn.com/image/fetch/$s_!rEoj!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a1ba9e5-6bc4-4631-94da-9195e040aff6_800x692.png 1272w, /__u/substackcdn.com/image/fetch/$s_!rEoj!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a1ba9e5-6bc4-4631-94da-9195e040aff6_800x692.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!rEoj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a1ba9e5-6bc4-4631-94da-9195e040aff6_800x692.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5a1ba9e5-6bc4-4631-94da-9195e040aff6_800x692.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!rEoj!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a1ba9e5-6bc4-4631-94da-9195e040aff6_800x692.png 424w, /__u/substackcdn.com/image/fetch/$s_!rEoj!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a1ba9e5-6bc4-4631-94da-9195e040aff6_800x692.png 848w, /__u/substackcdn.com/image/fetch/$s_!rEoj!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a1ba9e5-6bc4-4631-94da-9195e040aff6_800x692.png 1272w, /__u/substackcdn.com/image/fetch/$s_!rEoj!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5a1ba9e5-6bc4-4631-94da-9195e040aff6_800x692.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Component property examples comparing purposeful vs aesthetic options</figcaption></figure></div><p>In addition, the choice may vary by component, and that&#8217;s ok. For example, a <code>Badge</code> component is more atomic and require more visual variety (orange! purple!) and flexible use. This suggests that an aesthetic naming system is preferred. On the other hand, an <code>Alert</code> component is more composed, has more limited options, and the need to use it flexibly is far more limited. As a result, <code>Alert</code>s almost always leverage purposeful variant names.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!wW4C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61d8f72-a20c-454f-90a1-5cda8c26f57a_800x388.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!wW4C!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61d8f72-a20c-454f-90a1-5cda8c26f57a_800x388.png 424w, /__u/substackcdn.com/image/fetch/$s_!wW4C!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61d8f72-a20c-454f-90a1-5cda8c26f57a_800x388.png 848w, /__u/substackcdn.com/image/fetch/$s_!wW4C!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61d8f72-a20c-454f-90a1-5cda8c26f57a_800x388.png 1272w, /__u/substackcdn.com/image/fetch/$s_!wW4C!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61d8f72-a20c-454f-90a1-5cda8c26f57a_800x388.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!wW4C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61d8f72-a20c-454f-90a1-5cda8c26f57a_800x388.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c61d8f72-a20c-454f-90a1-5cda8c26f57a_800x388.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!wW4C!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61d8f72-a20c-454f-90a1-5cda8c26f57a_800x388.png 424w, /__u/substackcdn.com/image/fetch/$s_!wW4C!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61d8f72-a20c-454f-90a1-5cda8c26f57a_800x388.png 848w, /__u/substackcdn.com/image/fetch/$s_!wW4C!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61d8f72-a20c-454f-90a1-5cda8c26f57a_800x388.png 1272w, /__u/substackcdn.com/image/fetch/$s_!wW4C!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61d8f72-a20c-454f-90a1-5cda8c26f57a_800x388.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Different components may result in different schemes</figcaption></figure></div><h3>Blending approaches</h3><p>When teams encounter the limitations of pure purpose or pure aesthetics, they sometimes stray towards blending both approaches into a single component property. Two common but problematic patterns&#8202;&#8212;&#8202;<strong>Purpose-first </strong>and <strong>Hybrid</strong>&#8202;&#8212;&#8202;are generally best avoided.</p><h4>Purpose-first</h4><p>Purpose-first options follow purposeful options (<code>error</code>, <code>success</code>, <code>warning</code>) with aesthetic fallbacks (<code>white</code>, <code>black</code>, <code>light-gray</code>) for cases lacking clear semantic meaning.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!IQdx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f538edf-3832-4d7a-934c-4ae562d0fa75_800x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!IQdx!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f538edf-3832-4d7a-934c-4ae562d0fa75_800x720.png 424w, /__u/substackcdn.com/image/fetch/$s_!IQdx!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f538edf-3832-4d7a-934c-4ae562d0fa75_800x720.png 848w, /__u/substackcdn.com/image/fetch/$s_!IQdx!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f538edf-3832-4d7a-934c-4ae562d0fa75_800x720.png 1272w, /__u/substackcdn.com/image/fetch/$s_!IQdx!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f538edf-3832-4d7a-934c-4ae562d0fa75_800x720.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!IQdx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f538edf-3832-4d7a-934c-4ae562d0fa75_800x720.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4f538edf-3832-4d7a-934c-4ae562d0fa75_800x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!IQdx!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f538edf-3832-4d7a-934c-4ae562d0fa75_800x720.png 424w, /__u/substackcdn.com/image/fetch/$s_!IQdx!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f538edf-3832-4d7a-934c-4ae562d0fa75_800x720.png 848w, /__u/substackcdn.com/image/fetch/$s_!IQdx!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f538edf-3832-4d7a-934c-4ae562d0fa75_800x720.png 1272w, /__u/substackcdn.com/image/fetch/$s_!IQdx!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f538edf-3832-4d7a-934c-4ae562d0fa75_800x720.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Purpose-first options</figcaption></figure></div><p><strong>Benefits:</strong></p><ul><li><p>Guides decision-making with clear hierarchy</p></li><li><p>Covers gaps where semantics don&#8217;t apply</p></li><li><p>Easier to document than forcing semantics everywhere</p></li></ul><p><strong>Drawbacks:</strong></p><ul><li><p>Increases cognitive load with mixed mental models</p></li><li><p>Creates ambiguous boundaries between &#8220;purposeful&#8221; and &#8220;aesthetic&#8221;</p></li><li><p>Unclear extensibility as new options are needed</p></li></ul><p>Consider purpose-first enumerations with particular caution, generally avoiding them if possible.</p><h4>A hybrid&nbsp;trap</h4><p>The most problematic approach combines <strong>all</strong> purposeful and aesthetic options into one massive enum: <code>variant="error" | "success" | "red" | "green" | "white" | "black" | "light-gray" | "dark-gray"</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!tplO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8317c5d-7f9b-45db-827a-19528fd48ee3_800x876.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!tplO!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8317c5d-7f9b-45db-827a-19528fd48ee3_800x876.png 424w, /__u/substackcdn.com/image/fetch/$s_!tplO!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8317c5d-7f9b-45db-827a-19528fd48ee3_800x876.png 848w, /__u/substackcdn.com/image/fetch/$s_!tplO!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8317c5d-7f9b-45db-827a-19528fd48ee3_800x876.png 1272w, /__u/substackcdn.com/image/fetch/$s_!tplO!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8317c5d-7f9b-45db-827a-19528fd48ee3_800x876.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!tplO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8317c5d-7f9b-45db-827a-19528fd48ee3_800x876.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a8317c5d-7f9b-45db-827a-19528fd48ee3_800x876.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!tplO!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8317c5d-7f9b-45db-827a-19528fd48ee3_800x876.png 424w, /__u/substackcdn.com/image/fetch/$s_!tplO!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8317c5d-7f9b-45db-827a-19528fd48ee3_800x876.png 848w, /__u/substackcdn.com/image/fetch/$s_!tplO!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8317c5d-7f9b-45db-827a-19528fd48ee3_800x876.png 1272w, /__u/substackcdn.com/image/fetch/$s_!tplO!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa8317c5d-7f9b-45db-827a-19528fd48ee3_800x876.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Hybrid enumerated options, where both Error and Red options result in the same visual&nbsp;outcome</figcaption></figure></div><p>This leads to:</p><ul><li><p><strong>Cognitive paralysis</strong> from too many similar options</p></li><li><p><strong>Maintenance debt</strong> as the option list grows unwieldy</p></li><li><p><strong>Fragmented consistency</strong> that use different values for the same case</p></li><li><p><strong>Accessibility confusion</strong> when semantic and aesthetic values conflict</p></li></ul><p>A system that tries to be both flexible and meaningful may sound ideal&#8202;&#8212;&#8202;but in practice, it&#8217;s not. Don&#8217;t go there.</p><h3>Additional techniques</h3><p>When confronting the tradeoffs of purposeful and aesthetic naming, teams also often debate the merits of escape hatches, migration-oriented deprecation, and separating the two into multiple properties.</p><h4>Escape hatches</h4><p><strong>Escape hatches</strong> provide semantic options as the primary interface, supplemented by style override props for edge cases. For example, offering an interface to customize the styling of relevant properties.</p><pre><code>interface BadgeProps {
  variant: 'error' | 'success' | 'warning' | 'info';
  customStyles?: {
    backgroundColor?: string;
    textColor?: string;
  };
}</code></pre><p>This isn&#8217;t for the faint of heart (that is, design system professionals wanting firm control to limit uncontrollable designs). The model of exposing such overrides varies by team, whether it&#8217;s documented for everyone or a &#8220;back door&#8221; few know about. Regardless, escape hatches are a technique design systems apply make the common configurable and yet the uncommon visually composable.</p><h4>Migration-oriented deprecation</h4><p>When migrating from one system generation to another, <strong>deprecation</strong> can introduce semantic options while sustaining aesthetic ones with the intention to phase them out later.</p><pre><code>interface BadgeProps {
  variant: 'error' | 'success' | 'warning' | 'info';
  /** @deprecated Use severity prop instead */
  color?: 'red' | 'green' | 'yellow' | 'blue';
}</code></pre><p>Exercise this with caution. The migration is eased for sure, but there&#8217;s dangling properties spread throughout production code. It&#8217;s just kicking the can down the road&#8202;&#8212;&#8202;and eventually, you&#8217;ll have to clean up the mess.</p><h4>Multiple properties</h4><p>That said, never create competing props that could conflict, such as severity and color that require you to identify which takes precedence. In this case, it&#8217;d probably be color, which results in an interface where you can specify <code>variant</code> of <code>success</code> and a <code>purple</code> color, and&nbsp;&#8230; <code>purple</code> wins?</p><pre><code>// DON'T DO THIS
interface BadgeProps {
  variant?: 'error' | 'success';
  color?: 'red' | 'green';  // What if both are specified?
}</code></pre><p>Separating the <em>same concern</em> into multiple props is a terrible idea. Not only do the properties interact, but the component&#8217;s property shape is muddled. Don&#8217;t bother, please.</p><p>In general, I favor purpose over aesthetics because design systems use meaning to result in more consistent, accessible, and maintainable experiences. However, that principle doesn&#8217;t always mean purposeful is better, and I&#8217;ve worked with teams that justifiably used aesthetic naming schemes for some components. Don&#8217;t force artificial semantic meaning where none exists&#8202;&#8212;&#8202;sometimes a gray divider is just a gray divider or&#8230; just a divider.</p><p>Aesthetic props offer short-term flexibility, but often lead to long-term debt. Semantic investments, by contrast, tend to pay off as systems grow. Whatever approach you choose, be consistent. The best component API is one that guides users toward good decisions while remaining flexible enough to handle legitimate edge cases.</p>]]></content:encoded></item><item><title><![CDATA[The Sorry State of States]]></title><description><![CDATA[Today&#8217;s Figma assets show design could align better with code]]></description><link>https://nathanacurtis.substack.com/p/the-sorry-state-of-states-89dd4668737e</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/the-sorry-state-of-states-89dd4668737e</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Tue, 03 Dec 2024 19:00:17 GMT</pubDate><enclosure url="https://cdn-images-1.medium.com/max/2560/1*PWZH4UmVTFnGz7vWBh18zQ.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4>Today&#8217;s Figma assets show design could align better with&nbsp;code</h4><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/2560/1*PWZH4UmVTFnGz7vWBh18zQ.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/2560/1*PWZH4UmVTFnGz7vWBh18zQ.png 424w, https://cdn-images-1.medium.com/max/2560/1*PWZH4UmVTFnGz7vWBh18zQ.png 848w, https://cdn-images-1.medium.com/max/2560/1*PWZH4UmVTFnGz7vWBh18zQ.png 1272w, https://cdn-images-1.medium.com/max/2560/1*PWZH4UmVTFnGz7vWBh18zQ.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/2560/1*PWZH4UmVTFnGz7vWBh18zQ.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/2560/1*PWZH4UmVTFnGz7vWBh18zQ.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/2560/1*PWZH4UmVTFnGz7vWBh18zQ.png 424w, https://cdn-images-1.medium.com/max/2560/1*PWZH4UmVTFnGz7vWBh18zQ.png 848w, https://cdn-images-1.medium.com/max/2560/1*PWZH4UmVTFnGz7vWBh18zQ.png 1272w, https://cdn-images-1.medium.com/max/2560/1*PWZH4UmVTFnGz7vWBh18zQ.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>A few years back, I wrote <a href="https://medium.com/eightshapes-llc/crafting-ui-component-api-together-81946d140371">Crafting component API together</a>. Figma had become and remains the hegemonic design tool, and its capabilities for shaping components with a useful and usable API continue to strengthen. Libraries have taken deeper hold.</p><p>Yet, even the best system designers are missing opportunities to mimic how code actually works. No clearer is this than in the sorry state of the <code>state</code> prop of many interactive elements like text input, text area, dropdown, checkbox and radio button.</p><p>This post explores how design systems architect <code>states</code> in Figma assets inconsistent with how code works. The text input offers lessons about how to model props, from <strong>partial sets</strong> of option combinations and <strong>interdependent props</strong> to <strong>booleans versus enumerated</strong> options and just how far we should go&#8202;&#8212;&#8202;or not go&#8202;&#8212;&#8202;to purely model Figma assets.</p><h3>The State of States&nbsp;Today</h3><p>States is a generic term that designers and developers apply to a wide swath of situations. <a href="http://in/ericwbailey">Eric Bailey</a>&#8217;s lengthy list of <a href="https://ericwbailey.design/published/all-the-user-facing-states/">all the user facing states</a> highlights this well. There&#8217;s 38 in all, from <code>rest</code>, <code>hover</code> and <code>active</code> through <code>disabled</code>, <code>readonly</code>, <code>selected</code>, <code>deselected</code> to less common considerations like <code>loading</code>, <code>ghost origin</code>, and <code>dirty</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*kaOZS9Zi-oPM-MVh80C9cA.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*kaOZS9Zi-oPM-MVh80C9cA.png 424w, https://cdn-images-1.medium.com/max/800/1*kaOZS9Zi-oPM-MVh80C9cA.png 848w, https://cdn-images-1.medium.com/max/800/1*kaOZS9Zi-oPM-MVh80C9cA.png 1272w, https://cdn-images-1.medium.com/max/800/1*kaOZS9Zi-oPM-MVh80C9cA.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*kaOZS9Zi-oPM-MVh80C9cA.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*kaOZS9Zi-oPM-MVh80C9cA.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/800/1*kaOZS9Zi-oPM-MVh80C9cA.png 424w, https://cdn-images-1.medium.com/max/800/1*kaOZS9Zi-oPM-MVh80C9cA.png 848w, https://cdn-images-1.medium.com/max/800/1*kaOZS9Zi-oPM-MVh80C9cA.png 1272w, https://cdn-images-1.medium.com/max/800/1*kaOZS9Zi-oPM-MVh80C9cA.png 1456w" sizes="100vw"></picture><div></div></div></a><figcaption class="image-caption">Excerpt of example states from Eric Bailey&#8217;s <a href="https://ericwbailey.design/published/all-the-user-facing-states/">All the user-facing states</a></figcaption></figure></div><p>Curious Chrome inspectors could select a text input, right click to select Inspect, and find a bevy of element states (<code>:active</code>,&nbsp;<code>:hover</code>,&nbsp;<code>:focus</code>,&nbsp;&#8230; ) including a robust set of HTML <a href="https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation">form validation</a> hooks (<code>:disabled</code>,&nbsp;<code>:valid</code>,&nbsp;<code>:invalid</code>,&nbsp;&#8230; ) that front end developers can take advantage of with CSS combinations.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*O_WvqIJHvQGrwzc65kWyNw.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*O_WvqIJHvQGrwzc65kWyNw.png 424w, https://cdn-images-1.medium.com/max/800/1*O_WvqIJHvQGrwzc65kWyNw.png 848w, https://cdn-images-1.medium.com/max/800/1*O_WvqIJHvQGrwzc65kWyNw.png 1272w, https://cdn-images-1.medium.com/max/800/1*O_WvqIJHvQGrwzc65kWyNw.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*O_WvqIJHvQGrwzc65kWyNw.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*O_WvqIJHvQGrwzc65kWyNw.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/800/1*O_WvqIJHvQGrwzc65kWyNw.png 424w, https://cdn-images-1.medium.com/max/800/1*O_WvqIJHvQGrwzc65kWyNw.png 848w, https://cdn-images-1.medium.com/max/800/1*O_WvqIJHvQGrwzc65kWyNw.png 1272w, https://cdn-images-1.medium.com/max/800/1*O_WvqIJHvQGrwzc65kWyNw.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Chrome inspector&#8217;s states of a text input, including specific element&nbsp;states</figcaption></figure></div><p>Trouble is, the term states is exceedingly generic. All possible states aren&#8217;t alternatives. Instead, available states are a mishmash of interdependent concerns often with logical relationships and used in combination.</p><p>Yet when used in design critiques discussions, design specification section headers, and particularly in Figma asset properties: <code>state</code> becomes a glorious catch-all of insufficiently modeled ideas.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*98isutcS69qd0O4-5k36Sw.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*98isutcS69qd0O4-5k36Sw.png 424w, https://cdn-images-1.medium.com/max/1200/1*98isutcS69qd0O4-5k36Sw.png 848w, https://cdn-images-1.medium.com/max/1200/1*98isutcS69qd0O4-5k36Sw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*98isutcS69qd0O4-5k36Sw.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*98isutcS69qd0O4-5k36Sw.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*98isutcS69qd0O4-5k36Sw.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Visual designs of rest, hover and focus states of a text input&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Visual designs of rest, hover and focus states of a text input" title="Visual designs of rest, hover and focus states of a text input" srcset="https://cdn-images-1.medium.com/max/1200/1*98isutcS69qd0O4-5k36Sw.png 424w, https://cdn-images-1.medium.com/max/1200/1*98isutcS69qd0O4-5k36Sw.png 848w, https://cdn-images-1.medium.com/max/1200/1*98isutcS69qd0O4-5k36Sw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*98isutcS69qd0O4-5k36Sw.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>For a text input, of course we&#8217;ll show <code>hover</code> and <code>active</code>. Given that, we&#8217;ll pause and ponder whether to call the first one <code>base</code> (don&#8217;t), <code>default</code> (that&#8217;s ok), <code>enabled</code> or <code>initial</code> (better) or <code>rest</code> (best?). Nah, let&#8217;s go with <code>resting</code> I guess. Our impulse is to move on.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*CNNd7X86RLFTSljVn28tVA.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*CNNd7X86RLFTSljVn28tVA.png 424w, https://cdn-images-1.medium.com/max/1200/1*CNNd7X86RLFTSljVn28tVA.png 848w, https://cdn-images-1.medium.com/max/1200/1*CNNd7X86RLFTSljVn28tVA.png 1272w, https://cdn-images-1.medium.com/max/1200/1*CNNd7X86RLFTSljVn28tVA.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*CNNd7X86RLFTSljVn28tVA.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*CNNd7X86RLFTSljVn28tVA.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Visual designs of disabled, error and success states of a text input&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Visual designs of disabled, error and success states of a text input" title="Visual designs of disabled, error and success states of a text input" srcset="https://cdn-images-1.medium.com/max/1200/1*CNNd7X86RLFTSljVn28tVA.png 424w, https://cdn-images-1.medium.com/max/1200/1*CNNd7X86RLFTSljVn28tVA.png 848w, https://cdn-images-1.medium.com/max/1200/1*CNNd7X86RLFTSljVn28tVA.png 1272w, https://cdn-images-1.medium.com/max/1200/1*CNNd7X86RLFTSljVn28tVA.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Then complications arise. What about <code>disabled</code>? Of course, that&#8217;s needed. And <code>readonly</code>? Oh, I&#8217;d not thought of that. Obviously <code>error</code> state is a must. The <code>states</code> set grows gradually, stabilizing when we&#8217;re satisfied we&#8217;ve captured enough. Designers can be forgiven for not solving for every single &#8220;Eric Bailey State.&#8221; I never have. That list is crazy long!</p><h4>States Today in Figma&nbsp;Assets</h4><p>I examined the <code>Text input</code> / <code>Input</code> / etc Figma components published on the Figma community made by the following design systems:</p><ul><li><p><a href="https://www.figma.com/community/file/1035203688168086460/material-3-design-kit">Material 3 Design Kit</a></p></li><li><p><a href="https://www.figma.com/community/file/912837788133317724/material-ui-for-figma-and-mui-x">Material UI for Figma (and MUI X)</a></p></li><li><p>Salesforce <a href="https://www.figma.com/community/file/854593583696357016/components-for-web-lightning-design-system-v1">Components for Web | Lightning Design System v1</a></p></li><li><p>Github <a href="https://www.figma.com/community/file/854767373644076713/primer-web">Primer Web</a></p></li><li><p>IBM <a href="https://www.figma.com/community/file/1157761560874207208/v11-carbon-design-system">Carbon Design System</a></p></li><li><p>Atlassian <a href="https://www.figma.com/community/file/1182078880306369227/ads-components">ADS Components</a></p></li><li><p>Oracle <a href="https://www.figma.com/community/file/1425260295705487251/rds-toolkit-24c">Redwood</a></p></li><li><p>Newskit <a href="https://www.figma.com/community/file/1225806088244139801/newskit-component-library-and-theme-v5-0">Component Library</a></p></li><li><p>Shopify <a href="https://www.figma.com/community/file/1293611962331823010/polaris-components">Polaris Components</a></p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*JTO-FfRp8J9UE0SBs-E-5g.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*JTO-FfRp8J9UE0SBs-E-5g.png 424w, https://cdn-images-1.medium.com/max/1200/1*JTO-FfRp8J9UE0SBs-E-5g.png 848w, https://cdn-images-1.medium.com/max/1200/1*JTO-FfRp8J9UE0SBs-E-5g.png 1272w, https://cdn-images-1.medium.com/max/1200/1*JTO-FfRp8J9UE0SBs-E-5g.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*JTO-FfRp8J9UE0SBs-E-5g.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*JTO-FfRp8J9UE0SBs-E-5g.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*JTO-FfRp8J9UE0SBs-E-5g.png 424w, https://cdn-images-1.medium.com/max/1200/1*JTO-FfRp8J9UE0SBs-E-5g.png 848w, https://cdn-images-1.medium.com/max/1200/1*JTO-FfRp8J9UE0SBs-E-5g.png 1272w, https://cdn-images-1.medium.com/max/1200/1*JTO-FfRp8J9UE0SBs-E-5g.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Text input Figma components from Atlassian, Github and Shopify, normalized and simplified to include only properties relevant for states to enable comparison</figcaption></figure></div><p><code>state</code> property patterns matched what I observe in teams I consult with:</p><ul><li><p><strong>Hover</strong>: Six of ten support a <code>state</code>:<code>hover</code> (or <code>state</code>:<code>hovered</code>) option.</p></li><li><p><strong>Active</strong>: Two support a <code>state</code>:<code>active</code> option.</p></li><li><p><strong>Focus</strong>: Eight of ten support <code>state</code>:<code>focus</code> and none offered <code>focus</code> as a separate boolean property.</p></li><li><p><strong>Disabled</strong>: Nine of ten support <code>state</code>:<code>disabled</code> and only one (Atlassian) distinguished <code>isDisabled</code> as a separate boolean property.</p></li><li><p><strong>Read only</strong>: Six of ten support <code>state</code>:<code>readonly</code>, while none offered <code>readonly</code> as a boolean property.</p></li><li><p><strong>Error</strong> and <strong>Success</strong>: Eight of ten support an <code>state</code>:<code>error</code> (or similarly named validation) option, while one (Atlassian) offered <code>error</code> as a separate boolean property.</p></li></ul><p>Components occasionally included other <code>state</code> options like <code>warning</code>, <code>skeleton</code>, and <code>typing</code>. One even included <code>filled</code>, which drifts towards the adjacent state challenge of <code>value</code> and <code>placeholder</code> properties not covered here.</p><p>No Figma assets supported plausible state combinations like <code>readonly</code> + <code>focus</code> or <code>hover</code> + <code>error</code>.</p><h4>States Today in Code Libraries</h4><p>A similar review of <code>Text input</code> component code from those libraries yields a different prevailing model.</p><ul><li><p><strong>Hover</strong> and <strong>Active</strong>: Most code libraries implement these implicitly as states that respond to user interaction.</p></li><li><p><strong>Disabled </strong>and<strong> Read only</strong>: Nearly every code library implements these props, enough to consider both props as conventional.</p></li><li><p><strong>Error </strong>and <strong>Success</strong>: Many code libraries implement an <code>error</code> (or <code>inInvalid</code>, <code>hasError</code> or similar) boolean prop to present an error display. GitHub Primer expands from a binary to enumerated <code>validationStatus</code> prop to distinguish <code>error</code> from <code>success</code>. Some code libraries implement an <code>error</code> prop for error text.</p></li></ul><p>Shopify Polaris&#8217; React component implement <a href="https://www.typescriptlang.org/docs/handbook/interfaces.html">Typescript interfaces</a> for <code>disabled</code> and <code>readonly</code> suggesting that an intentional convention across components. This library also implements a forceable <code>focused</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*ksYSRaBl6r5Y9gq3iFuiVw.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*ksYSRaBl6r5Y9gq3iFuiVw.png 424w, https://cdn-images-1.medium.com/max/1200/1*ksYSRaBl6r5Y9gq3iFuiVw.png 848w, https://cdn-images-1.medium.com/max/1200/1*ksYSRaBl6r5Y9gq3iFuiVw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*ksYSRaBl6r5Y9gq3iFuiVw.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*ksYSRaBl6r5Y9gq3iFuiVw.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*ksYSRaBl6r5Y9gq3iFuiVw.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*ksYSRaBl6r5Y9gq3iFuiVw.png 424w, https://cdn-images-1.medium.com/max/1200/1*ksYSRaBl6r5Y9gq3iFuiVw.png 848w, https://cdn-images-1.medium.com/max/1200/1*ksYSRaBl6r5Y9gq3iFuiVw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*ksYSRaBl6r5Y9gq3iFuiVw.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Comparing how assets work today versus how they&#8217;d work if aligned with&nbsp;code</figcaption></figure></div><h4>So design and code are different. So&nbsp;what?</h4><p>The evidence is clear. Beyond interactive states like <code>hover</code> and <code>active</code>, Figma assets and code components offer distinct API signatures. Actually, let&#8217;s be more precise: design <em>assets</em> <em>published for reuse by product designers</em> are different from code assets that product developers use.</p><p>It could be that the design solution handed off by the system designer to a system developer is perfectly consistent with what happened in code. Nah. My experience suggests otherwise. Design iterations and specifications (often automated with the <a href="https://www.figma.com/community/plugin/1205622541257680763/eightshapes-specs">EightShapes Specs plugin</a>) almost always reveal the same &#8220;States as kitchen sink&#8221; approach. Why should we care?</p><h4>Corrosive impacts on efficiency, usability and satisfaction</h4><p>At a minimum, most designers are aware of the common pitfalls of imprecise and/or incomplete design delivery. This leads to challenges like:</p><ol><li><p><strong>Handoff friction</strong> as product designers deliver to product developers using published Figma assets that use different models from code.</p></li><li><p><strong>Poorly organized props</strong> in Figma assets that are harder to use, littering one or a few props with various choices that are actually independent.</p></li><li><p><strong>Continued distrust</strong> <strong>and disrespect</strong> of developers seeing designers as less or ill-equipped to model component props effectively.</p></li></ol><p>That last one hurts, perpetuating an at times justified &#8220;don&#8217;t touch my stuff&#8221; attitude that some developers persist have when instead we could be working to <a href="https://medium.com/eightshapes-llc/crafting-ui-component-api-together-81946d140371">craft component API, together</a>. That&#8217;s a subject for another day.</p><h4>Limiting impacts on automation</h4><p>Less visible to some but far more important to many of my current collaborators are the negative impacts to taking advantage of Figma&#8217;s API to automate and cleanse increasing areas of a system&#8217;s surface. Poorly modeled properties can:</p><ol><li><p><strong>Limit automation</strong> opportunities to audit and report on alignment across design and code libraries.</p></li><li><p><strong>Limit the ability to use assets as data</strong> to inform, serve as a source of truth, or even automate code development.</p></li><li><p><strong>Increase costs of mapping</strong> complicated (and brittle?) transformations in tools like <a href="https://help.figma.com/hc/en-us/articles/23920389749655-Code-Connect">Figma&#8217;s Code Connect</a> that could be avoided.</p></li></ol><p>My belief about API alignment across libraries including design has only hardened further since I <a href="https://medium.com/eightshapes-llc/crafting-ui-component-api-together-81946d140371">wrote about it in 2021</a>. When I see so many revered design systems unnecessarily diverge from code (just like those I work on too), I want us all to do better. This particular challenge isn&#8217;t hard.</p><h3>Modeling Prop Combinations and Interactions</h3><p>So let&#8217;s dig in, step by step, to think through stateful properties and how they work. We&#8217;ll start with the cleanly combined nature of <code>selected</code> and <code>state</code> found in radio buttons and checkboxes. From there, we&#8217;ll use Text input&#8217;s <code>disabled</code>, <code>readonly</code>, and validation states to learn how properties combine and interact with one another.</p><h4>Complete sets of combination</h4><p>Some types of states combine to form a complete set of relevant combinations. For example, <code>Checkbox</code> and <code>Radio button</code> combine interactive <code>state</code> (<code>rest</code>, <code>hover</code>, <code>active</code> and <code>focus</code>) and <code>selected</code> state (<code>not selected</code> and <code>selected</code>) into eight combinations.</p><p>The following table illustrates that for every combination of <code>state</code> and <code>selected</code>, the combination exists (depicted as &#9989;) and could warrant a distinct visual design.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*Jm05v1pIaQZ_WmFmk7lmLA.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*Jm05v1pIaQZ_WmFmk7lmLA.png 424w, https://cdn-images-1.medium.com/max/1200/1*Jm05v1pIaQZ_WmFmk7lmLA.png 848w, https://cdn-images-1.medium.com/max/1200/1*Jm05v1pIaQZ_WmFmk7lmLA.png 1272w, https://cdn-images-1.medium.com/max/1200/1*Jm05v1pIaQZ_WmFmk7lmLA.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*Jm05v1pIaQZ_WmFmk7lmLA.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*Jm05v1pIaQZ_WmFmk7lmLA.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*Jm05v1pIaQZ_WmFmk7lmLA.png 424w, https://cdn-images-1.medium.com/max/1200/1*Jm05v1pIaQZ_WmFmk7lmLA.png 848w, https://cdn-images-1.medium.com/max/1200/1*Jm05v1pIaQZ_WmFmk7lmLA.png 1272w, https://cdn-images-1.medium.com/max/1200/1*Jm05v1pIaQZ_WmFmk7lmLA.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Combination table of state versus&nbsp;selected</figcaption></figure></div><p>To <code>Radio button</code> states in a Figma component, one could include a <code>state</code> property with options for <code>hover</code>, <code>active</code>, <code>focus</code> and <code>selected</code>. However, that would omit possible combinations like <code>selected</code> and <code>hover</code> simultaneously. Those <em>could </em>be added as additional <code>state</code> options like <code>hover selected</code>, but risks sliding down the slippery slope of providing all combinations via compound option names. Better to separate concerns with distinct Figma variant properties for <code>selected</code> (even if it&#8217;s options are <code>true</code> and <code>false</code>, the visual design varies) and <code>state</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*_uzdglmWmTDLQ4Dhd2PWTg.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*_uzdglmWmTDLQ4Dhd2PWTg.png 424w, https://cdn-images-1.medium.com/max/1200/1*_uzdglmWmTDLQ4Dhd2PWTg.png 848w, https://cdn-images-1.medium.com/max/1200/1*_uzdglmWmTDLQ4Dhd2PWTg.png 1272w, https://cdn-images-1.medium.com/max/1200/1*_uzdglmWmTDLQ4Dhd2PWTg.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*_uzdglmWmTDLQ4Dhd2PWTg.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*_uzdglmWmTDLQ4Dhd2PWTg.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*_uzdglmWmTDLQ4Dhd2PWTg.png 424w, https://cdn-images-1.medium.com/max/1200/1*_uzdglmWmTDLQ4Dhd2PWTg.png 848w, https://cdn-images-1.medium.com/max/1200/1*_uzdglmWmTDLQ4Dhd2PWTg.png 1272w, https://cdn-images-1.medium.com/max/1200/1*_uzdglmWmTDLQ4Dhd2PWTg.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Radio buttonwith selected as a separate prop versus as options of a state&nbsp;prop</figcaption></figure></div><p>Checkbox&#8217;s potential of a third <code>checked</code> state&#8202;&#8212;&#8202;<code>indeterminate</code>&#8202;&#8212;&#8202;results in 12 possible combinations, make the enumerated <code>state</code> list of compound terms less desirable. Additionally, the <code>checked</code> property would shift from a binary variant to one revealing enumerated options of <code>not checked</code> (default), <code>indeterminate</code> and <code>checked</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*krjtipY6DwWKqDqg5XSQhQ.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*krjtipY6DwWKqDqg5XSQhQ.png 424w, https://cdn-images-1.medium.com/max/1200/1*krjtipY6DwWKqDqg5XSQhQ.png 848w, https://cdn-images-1.medium.com/max/1200/1*krjtipY6DwWKqDqg5XSQhQ.png 1272w, https://cdn-images-1.medium.com/max/1200/1*krjtipY6DwWKqDqg5XSQhQ.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*krjtipY6DwWKqDqg5XSQhQ.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*krjtipY6DwWKqDqg5XSQhQ.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*krjtipY6DwWKqDqg5XSQhQ.png 424w, https://cdn-images-1.medium.com/max/1200/1*krjtipY6DwWKqDqg5XSQhQ.png 848w, https://cdn-images-1.medium.com/max/1200/1*krjtipY6DwWKqDqg5XSQhQ.png 1272w, https://cdn-images-1.medium.com/max/1200/1*krjtipY6DwWKqDqg5XSQhQ.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Checkbox with selected as a separate prop versus as options of a state&nbsp;prop</figcaption></figure></div><p>To those brave enough to review Eric Bailey&#8217;s states list in detail, you may notice even more relevant considerations such as <code>Deselected</code>. For most teams, it&#8217;s impractical to include <code>Deselected</code> (having been changed from <code>Selected</code>) as distinct from <code>Rest</code> (neither selected nor interacted with).</p><h4>Partial sets of combinations</h4><p>The <code>disabled</code> property is different, as a variant set to <code>true</code> or (by default) <code>false</code>. Disabled controls are essentially at <code>rest</code>, visually distinct and <code>hover</code>, <code>active</code> and <code>focus</code> states are irrelevant.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*uPw26gJ3W8XZqKSR6c122w.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*uPw26gJ3W8XZqKSR6c122w.png 424w, https://cdn-images-1.medium.com/max/1200/1*uPw26gJ3W8XZqKSR6c122w.png 848w, https://cdn-images-1.medium.com/max/1200/1*uPw26gJ3W8XZqKSR6c122w.png 1272w, https://cdn-images-1.medium.com/max/1200/1*uPw26gJ3W8XZqKSR6c122w.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*uPw26gJ3W8XZqKSR6c122w.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*uPw26gJ3W8XZqKSR6c122w.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*uPw26gJ3W8XZqKSR6c122w.png 424w, https://cdn-images-1.medium.com/max/1200/1*uPw26gJ3W8XZqKSR6c122w.png 848w, https://cdn-images-1.medium.com/max/1200/1*uPw26gJ3W8XZqKSR6c122w.png 1272w, https://cdn-images-1.medium.com/max/1200/1*uPw26gJ3W8XZqKSR6c122w.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Combination table of state versus&nbsp;disabled</figcaption></figure></div><p>As a result, the designer has a choice: separate <code>disabled</code> from interactive <code>state</code> or include <code>disabled</code> as an option of <code>state</code>. Either choice results in a partial set of five out of eight possible combinations, so long as the Figma asset doesn&#8217;t implement disabled states not at rest.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*Es0LLX4sitgAq3wHEsd9GA.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*Es0LLX4sitgAq3wHEsd9GA.png 424w, https://cdn-images-1.medium.com/max/1200/1*Es0LLX4sitgAq3wHEsd9GA.png 848w, https://cdn-images-1.medium.com/max/1200/1*Es0LLX4sitgAq3wHEsd9GA.png 1272w, https://cdn-images-1.medium.com/max/1200/1*Es0LLX4sitgAq3wHEsd9GA.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*Es0LLX4sitgAq3wHEsd9GA.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*Es0LLX4sitgAq3wHEsd9GA.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*Es0LLX4sitgAq3wHEsd9GA.png 424w, https://cdn-images-1.medium.com/max/1200/1*Es0LLX4sitgAq3wHEsd9GA.png 848w, https://cdn-images-1.medium.com/max/1200/1*Es0LLX4sitgAq3wHEsd9GA.png 1272w, https://cdn-images-1.medium.com/max/1200/1*Es0LLX4sitgAq3wHEsd9GA.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Text input with disabled as a separate prop versus as an option of a state&nbsp;prop</figcaption></figure></div><p>Would it be convenient to stuff a <code>disabled</code> option into the <code>state</code> dimension? Sure, it feels easy. Yet, that&#8217;s not how code works. Plus, collapsing <code>disabled</code> into <code>state</code> reduces the model&#8217;s clarity and meaning, and disables (pun intended) you from properly modeling other relationships, as we&#8217;ll see next.</p><h4>Interdependent properties</h4><p>The plot thickens with <code>readonly</code>, also conventionally a boolean property in code. Like <code>disabled</code>, <code>readonly</code> is <code>false</code> by default. Unlike <code>disabled</code>, <code>readonly</code> supports <code>rest</code> <em>and</em> <code>focus</code> but typically not <code>hover</code> and <code>active</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*8kDC0LT6J3JOG8J12Cd2kw.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*8kDC0LT6J3JOG8J12Cd2kw.png 424w, https://cdn-images-1.medium.com/max/1200/1*8kDC0LT6J3JOG8J12Cd2kw.png 848w, https://cdn-images-1.medium.com/max/1200/1*8kDC0LT6J3JOG8J12Cd2kw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*8kDC0LT6J3JOG8J12Cd2kw.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*8kDC0LT6J3JOG8J12Cd2kw.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*8kDC0LT6J3JOG8J12Cd2kw.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*8kDC0LT6J3JOG8J12Cd2kw.png 424w, https://cdn-images-1.medium.com/max/1200/1*8kDC0LT6J3JOG8J12Cd2kw.png 848w, https://cdn-images-1.medium.com/max/1200/1*8kDC0LT6J3JOG8J12Cd2kw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*8kDC0LT6J3JOG8J12Cd2kw.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Combination table of state versus disabled and&nbsp;readonly</figcaption></figure></div><p>Additionally, <code>disabled</code> and <code>readonly</code> never occur simultaneously. When both <code>readonly</code> <em>and</em> <code>disabled</code> are set to <code>true</code>, <code>disabled</code> takes precedence and <code>readonly</code> is ignored, making these properties interdependent.</p><p>If a designer implements all seven valid combinations, Figma handles this case well enough. Since it takes precedence, <code>disabled</code> should be ordered first, followed by <code>readonly</code>, followed by <code>state</code>. Should a component user set <code>disabled</code> to false, the component would revert any other <code>state</code> to <code>rest</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*j7RQtWABdX40Mu0eDa0ULw.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*j7RQtWABdX40Mu0eDa0ULw.png 424w, https://cdn-images-1.medium.com/max/1200/1*j7RQtWABdX40Mu0eDa0ULw.png 848w, https://cdn-images-1.medium.com/max/1200/1*j7RQtWABdX40Mu0eDa0ULw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*j7RQtWABdX40Mu0eDa0ULw.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*j7RQtWABdX40Mu0eDa0ULw.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*j7RQtWABdX40Mu0eDa0ULw.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*j7RQtWABdX40Mu0eDa0ULw.png 424w, https://cdn-images-1.medium.com/max/1200/1*j7RQtWABdX40Mu0eDa0ULw.png 848w, https://cdn-images-1.medium.com/max/1200/1*j7RQtWABdX40Mu0eDa0ULw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*j7RQtWABdX40Mu0eDa0ULw.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Text input with readonly as a separate prop versus as an option of a state&nbsp;prop</figcaption></figure></div><p>Could both <code>disabled</code> and <code>readonly</code> be collapsed into options of a <code>state</code> property? Yes, but properties combining multiple dimensions into a one property with compound names doesn&#8217;t match code and doesn&#8217;t scale well.</p><h4>Choosing enumerated or boolean&nbsp;props</h4><p>Error and success validation states raise more questions. Both <code>disabled</code> and <code>readonly</code> are delightfully binary, easily represented with <code>true</code> and <code>false</code> values (even if built as Figma variant properties).</p><p>Some design systems only offer <code>error</code> states, which raises the already familiar choice (and recommendation) to offer an <code>error</code> variant property one can set to <code>false</code> (default) or <code>true</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*vxdc3lzsoAt5VnxZej56dQ.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*vxdc3lzsoAt5VnxZej56dQ.png 424w, https://cdn-images-1.medium.com/max/1200/1*vxdc3lzsoAt5VnxZej56dQ.png 848w, https://cdn-images-1.medium.com/max/1200/1*vxdc3lzsoAt5VnxZej56dQ.png 1272w, https://cdn-images-1.medium.com/max/1200/1*vxdc3lzsoAt5VnxZej56dQ.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*vxdc3lzsoAt5VnxZej56dQ.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*vxdc3lzsoAt5VnxZej56dQ.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*vxdc3lzsoAt5VnxZej56dQ.png 424w, https://cdn-images-1.medium.com/max/1200/1*vxdc3lzsoAt5VnxZej56dQ.png 848w, https://cdn-images-1.medium.com/max/1200/1*vxdc3lzsoAt5VnxZej56dQ.png 1272w, https://cdn-images-1.medium.com/max/1200/1*vxdc3lzsoAt5VnxZej56dQ.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The combination table below does raise interesting questions: can an input be set to both <code>error</code>&nbsp;: <code>true</code> and either <code>readonly</code>&nbsp;: <code>true</code> or <code>disabled</code>&nbsp;: <code>true</code>? From a purist&#8217;s perspective, yes, probably.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*5fVngudjyccTI3EkAo0vTA.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*5fVngudjyccTI3EkAo0vTA.png 424w, https://cdn-images-1.medium.com/max/1200/1*5fVngudjyccTI3EkAo0vTA.png 848w, https://cdn-images-1.medium.com/max/1200/1*5fVngudjyccTI3EkAo0vTA.png 1272w, https://cdn-images-1.medium.com/max/1200/1*5fVngudjyccTI3EkAo0vTA.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*5fVngudjyccTI3EkAo0vTA.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*5fVngudjyccTI3EkAo0vTA.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*5fVngudjyccTI3EkAo0vTA.png 424w, https://cdn-images-1.medium.com/max/1200/1*5fVngudjyccTI3EkAo0vTA.png 848w, https://cdn-images-1.medium.com/max/1200/1*5fVngudjyccTI3EkAo0vTA.png 1272w, https://cdn-images-1.medium.com/max/1200/1*5fVngudjyccTI3EkAo0vTA.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Combination table of state versus error, disabled and&nbsp;readonly</figcaption></figure></div><p>But such combinations of <code>error</code> (in HTML, <code>invalid</code>?) with<code>disabled</code> or <code>readonly</code> carries heavier considerations like:</p><ul><li><p>Competing visual cues: what signals it&#8217;s in <code>error</code> versus <code>disabled</code>?</p></li><li><p>Conflicting resolution: if an input is in <code>error</code>, the user should be able to interact with it to resolve the issue. If it&#8217;s <code>disabled</code>, they cannot.</p></li></ul><p>These are user experience design issues rather than API design issues. Guidance may suggest avoiding the combination unless it&#8217;s necessary and intuitive to users and encourage other UI patterns instead. For the Figma component and it&#8217;s attendant communications to implementing developers, however, at least a conversation if not explicit asset is warranted to clarify what happens if both are set to <code>true</code>.</p><p>Properties evolve further if an input also implements a <code>success</code> state (often combining a green color with a checkmark icon) that&#8217;s the opposite of an <code>error</code> state (that could use red color and an X icon).</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*zCBj9CIXCY7ZMZWugH1bAw.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*zCBj9CIXCY7ZMZWugH1bAw.png 424w, https://cdn-images-1.medium.com/max/1200/1*zCBj9CIXCY7ZMZWugH1bAw.png 848w, https://cdn-images-1.medium.com/max/1200/1*zCBj9CIXCY7ZMZWugH1bAw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*zCBj9CIXCY7ZMZWugH1bAw.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*zCBj9CIXCY7ZMZWugH1bAw.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*zCBj9CIXCY7ZMZWugH1bAw.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*zCBj9CIXCY7ZMZWugH1bAw.png 424w, https://cdn-images-1.medium.com/max/1200/1*zCBj9CIXCY7ZMZWugH1bAw.png 848w, https://cdn-images-1.medium.com/max/1200/1*zCBj9CIXCY7ZMZWugH1bAw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*zCBj9CIXCY7ZMZWugH1bAw.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>In this case, <code>error</code> (or, <code>invalid</code>) is mutually exclusive from <code>success</code> (or, <code>valid</code>), and a visualized <code>success</code> state is different than showing neither an <code>error</code>'s red or <code>success</code>'s green. Therefore, consider an enumerated <code>validation</code> variant property with options for <code>none</code> (default), <code>error</code> and <code>success</code>.</p><h4>Standalone prop versus or option of another&nbsp;prop</h4><p>All this time, <code>focus</code> has been presumed a mutually exclusive option in a set that also includes <code>rest</code>, <code>hover</code> and <code>active</code>. In fact, an element can be both <code>hover</code>+<code>focus</code> or <code>active</code>+<code>focus</code> simultaneously.</p><p>Should <code>focus</code> (<code>true</code>,<code>false</code>) be a separate property from iteractive <code>state </code>(<code>rest</code>, <code>hover</code>, <code>active</code>)?</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*4CWwfwd6_ZThgfub4MkECg.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*4CWwfwd6_ZThgfub4MkECg.png 424w, https://cdn-images-1.medium.com/max/1200/1*4CWwfwd6_ZThgfub4MkECg.png 848w, https://cdn-images-1.medium.com/max/1200/1*4CWwfwd6_ZThgfub4MkECg.png 1272w, https://cdn-images-1.medium.com/max/1200/1*4CWwfwd6_ZThgfub4MkECg.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*4CWwfwd6_ZThgfub4MkECg.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*4CWwfwd6_ZThgfub4MkECg.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*4CWwfwd6_ZThgfub4MkECg.png 424w, https://cdn-images-1.medium.com/max/1200/1*4CWwfwd6_ZThgfub4MkECg.png 848w, https://cdn-images-1.medium.com/max/1200/1*4CWwfwd6_ZThgfub4MkECg.png 1272w, https://cdn-images-1.medium.com/max/1200/1*4CWwfwd6_ZThgfub4MkECg.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Combination table of state versus disabled, readonly and&nbsp;focus</figcaption></figure></div><p>A designer converted to be a purist by preceding sections may be incorrectly led to further separate concerns and add a <code>focus</code> variant property set to <code>false</code> by default. That&#8217;s likely going too far.</p><p>In a practical sense, separating a <code>focus</code> property from a <code>state</code> property isn&#8217;t practically necessary, because:</p><ul><li><p><strong>Focus is almost always triggered client-side, not a developer&#8217;s configuration</strong>: <code>focus</code>, like <code>hover</code>, is an interactive state based on user interaction. Although some libraries offer it, most implementing developers don&#8217;t find themselves forcing <code>focus</code> with a prop, unlike <code>disabled</code>, <code>readonly</code> or <code>error</code>.</p></li><li><p><strong>Focus impacts distinct visual attributes, usually</strong>: <code>focus</code> typically impacts visual attributes (such as a container shadow or a showing a separate focus ring element) are distinct from those impacted by <code>hover</code> or <code>active </code>(usually, a container&#8217;s background or stroke color).</p></li><li><p><strong>Focus overrides the same visual attributes, otherwise</strong>: Even if <code>focus</code> impacts container stroke weight and color as <code>hover</code> does, once the element has <code>focus</code>, the weaker visual cues relevant to <code>hover</code> or <code>active</code> matter far less if at all. <code>focus</code> takes precendence over <code>hover</code> as <code>disabled</code> did over <code>readonly</code>, and there&#8217;s no relevant third, distinct appearance for <code>focus</code> + <code>hover</code>.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*_RCGYFqIfu1e05AljV1bcA.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*_RCGYFqIfu1e05AljV1bcA.png 424w, https://cdn-images-1.medium.com/max/800/1*_RCGYFqIfu1e05AljV1bcA.png 848w, https://cdn-images-1.medium.com/max/800/1*_RCGYFqIfu1e05AljV1bcA.png 1272w, https://cdn-images-1.medium.com/max/800/1*_RCGYFqIfu1e05AljV1bcA.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*_RCGYFqIfu1e05AljV1bcA.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*_RCGYFqIfu1e05AljV1bcA.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/800/1*_RCGYFqIfu1e05AljV1bcA.png 424w, https://cdn-images-1.medium.com/max/800/1*_RCGYFqIfu1e05AljV1bcA.png 848w, https://cdn-images-1.medium.com/max/800/1*_RCGYFqIfu1e05AljV1bcA.png 1272w, https://cdn-images-1.medium.com/max/800/1*_RCGYFqIfu1e05AljV1bcA.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Hover, active, and multiple focus states grouped as a set in Chrome&#8217;s inspector</figcaption></figure></div><ul><li><p><strong>Conventionally related as a set: </strong>The three are very closely related CSS pseudo classes, presented as and usually pursued as illustrated by their presence. If we&#8217;re going to distinguish <code>focus</code>, might as well distinguish <code>hover</code> from <code>active</code>. While we&#8217;re at it, is it time to further distinguish <code>focus-within</code>? I&#8217;ve never encountered a developer coding that yet, let alone a designer solving for it. We can all aspire for greatness, someday?</p></li></ul><p>All but one code examples assessed lack a <code>focused</code> property. Only Shopify Polaris&#8217; offered a <code>focused</code> property to force the focused state. I&#8217;m guessing at purpose: maybe interactions with elements slotted inside the input must force the focus state of the parent container? Additionally, Shopify Polaris&#8217; <code>focused</code> property is additive to the <code>focus</code> interactive state triggered without applying the property.</p><p>I&#8217;m unconvinced that separating <code>focus</code>:<code>true</code>, <code>false</code> from an interactive <code>state</code>:<code>rest</code>, <code>hover</code> and <code>active</code> is necessary. That is, until collaboration fails (it won&#8217;t) or automation between libraries requires it (it could, someday).</p><p>Ending there is a useful illustration: the pursuit of perfect alignment&#8202;&#8212;&#8202;and a perfect model for configuring our design&#8202;&#8212;&#8202;loses steam before perfection. That three year old blog post was more than comfortable with diverging <code>state</code> across design and code assets.</p><p>Today, the threshold has moved towards deeper integration and stronger alignment. That&#8217;s the same journey many teams will be on over their years pursing systems. Maybe someday they&#8217;ll converge. Maybe soon.</p>]]></content:encoded></item><item><title><![CDATA[Managing Design Systems with Many Core Libraries]]></title><description><![CDATA[How you align design and engineering and synchronize releases depends on the frameworks, platforms and teams involved]]></description><link>https://nathanacurtis.substack.com/p/managing-design-systems-that-make-many-core-libraries-28b80444865e</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/managing-design-systems-that-make-many-core-libraries-28b80444865e</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Mon, 28 Oct 2024 15:47:56 GMT</pubDate><enclosure url="https://cdn-images-1.medium.com/max/2560/1*Q06rPUwx7x715G7mObjYXA.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4>How you align design and engineering and synchronize releases depends on the frameworks, platforms and teams&nbsp;involved</h4><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/2560/1*Q06rPUwx7x715G7mObjYXA.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/2560/1*Q06rPUwx7x715G7mObjYXA.png 424w, https://cdn-images-1.medium.com/max/2560/1*Q06rPUwx7x715G7mObjYXA.png 848w, https://cdn-images-1.medium.com/max/2560/1*Q06rPUwx7x715G7mObjYXA.png 1272w, https://cdn-images-1.medium.com/max/2560/1*Q06rPUwx7x715G7mObjYXA.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/2560/1*Q06rPUwx7x715G7mObjYXA.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/2560/1*Q06rPUwx7x715G7mObjYXA.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/2560/1*Q06rPUwx7x715G7mObjYXA.png 424w, https://cdn-images-1.medium.com/max/2560/1*Q06rPUwx7x715G7mObjYXA.png 848w, https://cdn-images-1.medium.com/max/2560/1*Q06rPUwx7x715G7mObjYXA.png 1272w, https://cdn-images-1.medium.com/max/2560/1*Q06rPUwx7x715G7mObjYXA.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>Design systems come in many shapes and sizes, especially evident by how core catalogs of foundations and UI components are implemented across more than one code library.</p><p>As a system scales to meet expanding needs, it often grows to offer parallel component code libraries for web, iOS and Android along with commensurate Figma assets for designers. Four &#8220;core libraries&#8221; (three code, one design), parity of all relevant components, expanding and evolving over time. Let&#8217;s roll up our sleeves.</p><p>This post explores how expanding to support many platforms and frameworks impacts how you support and align it with a shared design source-of-truth. Success gets complicated as libraries increase, challenging how teams collaborate, designers test, everyone aligns API, and users still expect to see synced features each release.</p><p>The example of IBM&#8217;s Carbon design system offers a tantalizing public example of a core library implemented across many frameworks in parallel. Such a model inspires, even if it&#8217;s not necessarily a target to emulate for simpler problems most systems face.</p><h3>Describing core libraries of design and&nbsp;code</h3><p>A <strong>core library</strong> refers to a library of reusable assets implementing a design system&#8217;s core components like <code>Text input</code>, <code>Button</code> and <code>Checkbox</code>.</p><h4>Platforms and frameworks</h4><p>Each library implementation targets a specific <strong>platform</strong> (such as <code>design</code>, <code>web</code>, <code>iOS</code> and <code>Android</code>) and is built with a particular <strong>framework</strong> (such as <code>Figma</code> or <code>Sketch</code>, <code>React</code> or <code>Lit</code> or <code>Angular</code>, <code>SwiftUI</code> or <code>Jetpack Compose</code>).</p><h4>Team model: central and/or federated?</h4><p>For smaller design systems, design and code implementations are usually maintained by <strong>central</strong> teams dedicated to the work. As additional code implementations arise supporting other platforms and frameworks, the more likely each will be made by <strong>federated</strong> maintainers and contributors.</p><h4>Design source-of-truth: specifications?</h4><p>Designers and developers using a core libraries expect that library to support all core components like <code>button</code>, <code>text input</code> and <code>checkbox</code>. Each component is expected to implement a common <strong><a href="https://medium.com/eightshapes-llc/component-specifications-1492ca4c94c">design specification</a></strong> (that may include platform&#8211; and/or framework&#8211;specific considerations).</p><h4>Code source-of-truth: the reference implementation?</h4><p>In addition, one code library may serve as a <strong>reference implementation:</strong> a working component demonstrating how it should be correctly implemented and used. The reference is usually produced by the central team, showcases best practices, and reflects a recommended API. Such a &#8220;canonical&#8221; reference provides federated teams implementing additional libraries with a reasonable technical design to align with.</p><h3>Example models, from simple to complicated</h3><p>Managing and aligning one code library with design is delightfully simple compared to when two or more code libraries begin to scale. As a manager of design system work, it&#8217;s up to me to solve for concerns across libraries that include:</p><ul><li><p><strong>Roadmap</strong>: How do we align features across code libraries over time?</p></li><li><p><strong>Collaboration</strong>: How do we enable collaborative best practices between design and multiple engineering teams, especically when federated?</p></li><li><p><strong>API</strong>: How do we align API architecture across frameworks, platforms?</p></li><li><p><strong>Testing</strong>: How do we integrate designers into testing code outputs?</p></li><li><p><strong>Release synchronization</strong>: Do we align releases and communications across libraries? If not, what does that mean?</p></li></ul><p>The example models that follow will progress from simple to complicated to highlight how these concerns get more complicated.</p><h4>One code library, by a central&nbsp;team</h4><p>The majority of design systems I&#8217;ve led support one design library (these days, Figma) and one code library (such as React) through the work of a central team. Production aligns three primary outputs&#8202;&#8212;&#8202;(1) Figma assets, (2) React code packages, and (3) docs published to the &#8220;doc site&#8221;&#8202;&#8212;&#8202;released in synchronization in a <a href="http://Step-by-Step">step-by-step process</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*6EmLdKgyOGGCacyQru20Ig.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*6EmLdKgyOGGCacyQru20Ig.png 424w, https://cdn-images-1.medium.com/max/800/1*6EmLdKgyOGGCacyQru20Ig.png 848w, https://cdn-images-1.medium.com/max/800/1*6EmLdKgyOGGCacyQru20Ig.png 1272w, https://cdn-images-1.medium.com/max/800/1*6EmLdKgyOGGCacyQru20Ig.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*6EmLdKgyOGGCacyQru20Ig.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*6EmLdKgyOGGCacyQru20Ig.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/800/1*6EmLdKgyOGGCacyQru20Ig.png 424w, https://cdn-images-1.medium.com/max/800/1*6EmLdKgyOGGCacyQru20Ig.png 848w, https://cdn-images-1.medium.com/max/800/1*6EmLdKgyOGGCacyQru20Ig.png 1272w, https://cdn-images-1.medium.com/max/800/1*6EmLdKgyOGGCacyQru20Ig.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption"><a href="http://Step-by-Step">Steps to design and produce library outputs</a> for a design system&nbsp;feature</figcaption></figure></div><ul><li><p><strong>Roadmap</strong>, <strong>collaboration</strong>, <strong>designer VQA</strong> and <strong>release synchronization</strong>? As easy as it gets managing a single central team.</p></li><li><p><strong>API alignment</strong>? While <a href="https://medium.com/eightshapes-llc/crafting-ui-component-api-together-81946d140371">crafting components with aligned features and API</a> challenges designers and developers, a smaller group producing React and Figma can figure it out.</p></li></ul><h4>Many web core libraries, by a central&nbsp;team</h4><p>A central team could implement multiple web code libraries, such as releasing parallel Angular, Web Components, and vanilla HTML/CSS libraries.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*IlhQKJ-k5CSKUEQ8c_94lw.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*IlhQKJ-k5CSKUEQ8c_94lw.png 424w, https://cdn-images-1.medium.com/max/800/1*IlhQKJ-k5CSKUEQ8c_94lw.png 848w, https://cdn-images-1.medium.com/max/800/1*IlhQKJ-k5CSKUEQ8c_94lw.png 1272w, https://cdn-images-1.medium.com/max/800/1*IlhQKJ-k5CSKUEQ8c_94lw.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*IlhQKJ-k5CSKUEQ8c_94lw.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*IlhQKJ-k5CSKUEQ8c_94lw.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/800/1*IlhQKJ-k5CSKUEQ8c_94lw.png 424w, https://cdn-images-1.medium.com/max/800/1*IlhQKJ-k5CSKUEQ8c_94lw.png 848w, https://cdn-images-1.medium.com/max/800/1*IlhQKJ-k5CSKUEQ8c_94lw.png 1272w, https://cdn-images-1.medium.com/max/800/1*IlhQKJ-k5CSKUEQ8c_94lw.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">One engineering team producing Angular and Web components sharing a common CSS styling architecture, all three of which made available to&nbsp;adopters</figcaption></figure></div><ul><li><p><strong>Roadmap</strong> and <strong>collaboration</strong>? No different.</p></li><li><p><strong>API alignment:</strong> Vagaries of different web frameworks can fray API alignment subtly. When they differ, which should Figma assets favor?</p></li><li><p><strong>Designer VQA</strong>: As frameworks suggest an internal code waterfall, when are the right time(s) for design to test near-complete dev assets?</p></li><li><p><strong>Release synchronization</strong>: Is it ok to release some web code changes before others? While they remain locked together in a single, synced release, this setup could tempt teams to release one before others.</p></li></ul><p>Code could also diverge due to per-framework conventions, feature requests or fix cadences. However, these low risks can be mitigated by team processes and a single, directly responsible dev lead.</p><h4>Core libraries across platforms, by separate central&nbsp;teams</h4><p>A &#8220;team of teams&#8221; responsible for three libraries serving web, iOS and Android is very common in today&#8217;s design systems. More often than not, each platform&#8217;s library has a distinct dev lead and or more additional developers. Anecdotally in my experience, web has often 2&#215; the developers of iOS or Android, for whatever reason.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*tFWHVZ7misJx0Rui_x4myw.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*tFWHVZ7misJx0Rui_x4myw.png 424w, https://cdn-images-1.medium.com/max/800/1*tFWHVZ7misJx0Rui_x4myw.png 848w, https://cdn-images-1.medium.com/max/800/1*tFWHVZ7misJx0Rui_x4myw.png 1272w, https://cdn-images-1.medium.com/max/800/1*tFWHVZ7misJx0Rui_x4myw.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*tFWHVZ7misJx0Rui_x4myw.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*tFWHVZ7misJx0Rui_x4myw.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/800/1*tFWHVZ7misJx0Rui_x4myw.png 424w, https://cdn-images-1.medium.com/max/800/1*tFWHVZ7misJx0Rui_x4myw.png 848w, https://cdn-images-1.medium.com/max/800/1*tFWHVZ7misJx0Rui_x4myw.png 1272w, https://cdn-images-1.medium.com/max/800/1*tFWHVZ7misJx0Rui_x4myw.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Three platform libraries made by separate engineering teams centrally managed as a larger &#8220;team of&nbsp;teams&#8221;</figcaption></figure></div><p>Given the multiple dev teams and leads, things get more complicated.</p><ul><li><p><strong>Roadmap</strong>: Centralized but diversified into groups, persisting a shared roadmap takes a bit more effort.</p></li><li><p><strong>Collaboration</strong>: Distinct dev leads per &#8220;platform team&#8221; need their own ceremonies, which can begin to diverge decisions and understanding. Are there routines where designers should participate? Previously <a href="https://danmall.com/posts/hot-potato-process/">&#8220;hot potato&#8221; behaviors</a> give way to increasing focus on handoffs and specs for provisional decision making. Are all three dev leads in handoff meetings, or do we need <em>multiple</em> handoffs?</p></li><li><p><strong>API alignment:</strong> Systems must allow for platform-specific conventions, so it&#8217;s up to leads to agree on guardrails of what&#8217;s shared or not. In this setup, I lean even more into component, property and option naming.</p></li><li><p><strong>Designer VQA</strong>: A designer responsible for specs gets called back into visually test different platforms at different times. Review timing is less predictable and more disruptive. Tracking needs deliberate attention.</p></li><li><p><strong>Release synchronization</strong>: The tug of independent releases strengthens considerably, allowing for code enhancements and fixes to release quickly to support business needs.</p></li></ul><p>Once multiple development teams and/or platforms get involved, it&#8217;s often time to invoke a <strong>&#8220;Release individually, communicate collectively&#8221;</strong> model.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*zhLNMpP8CTs3bKY31MfYjQ.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*zhLNMpP8CTs3bKY31MfYjQ.png 424w, https://cdn-images-1.medium.com/max/800/1*zhLNMpP8CTs3bKY31MfYjQ.png 848w, https://cdn-images-1.medium.com/max/800/1*zhLNMpP8CTs3bKY31MfYjQ.png 1272w, https://cdn-images-1.medium.com/max/800/1*zhLNMpP8CTs3bKY31MfYjQ.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*zhLNMpP8CTs3bKY31MfYjQ.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*zhLNMpP8CTs3bKY31MfYjQ.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/800/1*zhLNMpP8CTs3bKY31MfYjQ.png 424w, https://cdn-images-1.medium.com/max/800/1*zhLNMpP8CTs3bKY31MfYjQ.png 848w, https://cdn-images-1.medium.com/max/800/1*zhLNMpP8CTs3bKY31MfYjQ.png 1272w, https://cdn-images-1.medium.com/max/800/1*zhLNMpP8CTs3bKY31MfYjQ.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Release communications occurring when all outputs are done, even if some (here, React and iOS) release quietly prior when&nbsp;ready</figcaption></figure></div><p>Here, React and iOS could release days or even weeks prior to Android, the Figma library and documentation site. Once Android is done, Figma and doc site materials complete the &#8220;Release&#8221; and<a href="https://medium.com/eightshapes-llc/design-system-communications-ca679ffc36d3"> communications</a> across Slack, email and formal doc can broadcast new feature availability to the masses. This strikes a balance between enabling teams that need component code as soon as possible with a system driving (perceived) alignment across platforms.</p><p>If the gap between platforms is longer, then releases separate by platform. This is almost always the case when libraries are federated.</p><h4>Web library by central team, iOS and Android federated</h4><p>In my experience, it&#8217;s less common for iOS and Android to be centrally managed with and allocated with the same dedicated capacity as developers supporting a design system&#8217;s web code. Instead, I&#8217;m used to coordinating more loosely with iOS and Android library leads. These libraries emerge to serve their &#8220;main app,&#8221; and the benefit to teams making other apps is a secondary concern at best.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*npwLN42z8612EC9dv-2Jmg.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*npwLN42z8612EC9dv-2Jmg.png 424w, https://cdn-images-1.medium.com/max/800/1*npwLN42z8612EC9dv-2Jmg.png 848w, https://cdn-images-1.medium.com/max/800/1*npwLN42z8612EC9dv-2Jmg.png 1272w, https://cdn-images-1.medium.com/max/800/1*npwLN42z8612EC9dv-2Jmg.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*npwLN42z8612EC9dv-2Jmg.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*npwLN42z8612EC9dv-2Jmg.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/800/1*npwLN42z8612EC9dv-2Jmg.png 424w, https://cdn-images-1.medium.com/max/800/1*npwLN42z8612EC9dv-2Jmg.png 848w, https://cdn-images-1.medium.com/max/800/1*npwLN42z8612EC9dv-2Jmg.png 1272w, https://cdn-images-1.medium.com/max/800/1*npwLN42z8612EC9dv-2Jmg.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>When working with those making federated libraries, ways-of-working diverge far more. Considerations include:</p><ul><li><p><strong>Roadmap</strong>: Very often, the &#8220;main app&#8221; product leaders get involved. Different interests&#8202;&#8212;&#8202;deliver a library (my outcome), &#8220;main app&#8221; integration (their outcome)&#8202;&#8212;&#8202;become clear. Artifacts to plan, distinguish and connect those outcomes become essential.</p></li><li><p><strong>Collaboration</strong>: It&#8217;s very difficult to integrate federated dev leads into routine (weekly?) handoffs from design to the central dev team(s). Integrating them into critiques that precede handoff? Even more so. Therefore, collaborative value rises to the fore: do these libraries justify a separate handoff meeting? How about a separate planning meeting, and how often (tip: it ebbs and flows)?</p></li><li><p><strong>API alignment:</strong> In this example, web code undoubtedly becomes the reference library, especially if synced strongly with design specs. However, results are uneven in getting iOS and Android dev leads to use that reference. To that end, I&#8217;ll work involve web dev lead to lean into handoffs and coordination too.</p></li><li><p><strong>Designer VQA</strong>: No different, if spread more widely across the calendar.</p></li><li><p><strong>Release synchronization</strong>: Releases aren&#8217;t synced, and trying to sync them is the wrong focus. Federated releases tend to lag central ones by months, quarters or even a year. So your communication challenge is two fold: set expectations clearly and clearly communicate the status of each item in each library to those that use them.</p></li></ul><h4>Case study: IBM Carbon as the federated dream</h4><p>I&#8217;ve not contributed to IBM Carbon, but have watched its impressive progress for years. IBM Carbon supports code libraries across many web frameworks, each with a public code repositories that provide a clear glimpse into it&#8217;s evolving catalog.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*X2Ipu0mSw5AZViWrg5MTjQ.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*X2Ipu0mSw5AZViWrg5MTjQ.png 424w, https://cdn-images-1.medium.com/max/800/1*X2Ipu0mSw5AZViWrg5MTjQ.png 848w, https://cdn-images-1.medium.com/max/800/1*X2Ipu0mSw5AZViWrg5MTjQ.png 1272w, https://cdn-images-1.medium.com/max/800/1*X2Ipu0mSw5AZViWrg5MTjQ.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*X2Ipu0mSw5AZViWrg5MTjQ.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*X2Ipu0mSw5AZViWrg5MTjQ.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/800/1*X2Ipu0mSw5AZViWrg5MTjQ.png 424w, https://cdn-images-1.medium.com/max/800/1*X2Ipu0mSw5AZViWrg5MTjQ.png 848w, https://cdn-images-1.medium.com/max/800/1*X2Ipu0mSw5AZViWrg5MTjQ.png 1272w, https://cdn-images-1.medium.com/max/800/1*X2Ipu0mSw5AZViWrg5MTjQ.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>In 2022, I analyzed commit activity across public repositories of IBM Carbon&#8217;s core libraries supporting Vanilla HTML &amp; CSS, <a href="https://github.com/carbon-design-system/carbon?tab=readme-ov-file">React</a>, <a href="https://github.com/carbon-design-system/carbon-components-angular">Angular</a>, <a href="https://github.com/carbon-design-system/carbon-components-svelte">Svelte</a>, Web components (now integrated into the <a href="https://github.com/carbon-design-system/carbon?tab=readme-ov-file">core library</a>) and <a href="https://github.com/carbon-design-system/carbon-components-vue">Vue</a>. The libraries emerged over years, with varying levels of activity and growth over time.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*DHKsw1OQlGc5vN8vutPbsg.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*DHKsw1OQlGc5vN8vutPbsg.png 424w, https://cdn-images-1.medium.com/max/800/1*DHKsw1OQlGc5vN8vutPbsg.png 848w, https://cdn-images-1.medium.com/max/800/1*DHKsw1OQlGc5vN8vutPbsg.png 1272w, https://cdn-images-1.medium.com/max/800/1*DHKsw1OQlGc5vN8vutPbsg.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*DHKsw1OQlGc5vN8vutPbsg.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*DHKsw1OQlGc5vN8vutPbsg.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/800/1*DHKsw1OQlGc5vN8vutPbsg.png 424w, https://cdn-images-1.medium.com/max/800/1*DHKsw1OQlGc5vN8vutPbsg.png 848w, https://cdn-images-1.medium.com/max/800/1*DHKsw1OQlGc5vN8vutPbsg.png 1272w, https://cdn-images-1.medium.com/max/800/1*DHKsw1OQlGc5vN8vutPbsg.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Table of IBM library metadata as of 2022, including age and quantity of core maintainers, recurring contributors, and light/one-time contributors</figcaption></figure></div><p>Per contributor commits made evident one or few core maintainer(s), additional contributors and a long tail of one-commit wonders.</p><p>Conversation with <a href="https://medium.com/@joshblack">Josh Black</a>, the dev lead in charge of the React library at the time, confirmed that React served as the reference implementation and the other libraries were not supported by the core team and released independently. A recent conversation with current team members confirmed that the central team had taken responsibility for and integrated the Web Components library. Other library implementations live on.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*L0p_zRkU1miduwgoM6Gu1w.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*L0p_zRkU1miduwgoM6Gu1w.png 424w, https://cdn-images-1.medium.com/max/1200/1*L0p_zRkU1miduwgoM6Gu1w.png 848w, https://cdn-images-1.medium.com/max/1200/1*L0p_zRkU1miduwgoM6Gu1w.png 1272w, https://cdn-images-1.medium.com/max/1200/1*L0p_zRkU1miduwgoM6Gu1w.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*L0p_zRkU1miduwgoM6Gu1w.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*L0p_zRkU1miduwgoM6Gu1w.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*L0p_zRkU1miduwgoM6Gu1w.png 424w, https://cdn-images-1.medium.com/max/1200/1*L0p_zRkU1miduwgoM6Gu1w.png 848w, https://cdn-images-1.medium.com/max/1200/1*L0p_zRkU1miduwgoM6Gu1w.png 1272w, https://cdn-images-1.medium.com/max/1200/1*L0p_zRkU1miduwgoM6Gu1w.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Github.com commit activity across React/Vanilla, Angular, Vue, Web components, Carbon for IBM.com and Svelte libraries, scaled to match vertical axis&nbsp;scale</figcaption></figure></div><p>Commit activity across repos visualized over time revealed trends like:</p><ul><li><p>Some libraries like <code>React + Vanilla</code> and then <code>Carbon for IBM.com</code> evidenced persistent activity, whereas <code>Angular</code> seemed to fade in 2021.</p></li><li><p>As <code>React + Vanilla</code> spiked in late 2018 (due to <a href="https://medium.com/@nathanacurtis/design-system-generations-65f99960dc3d">generational change</a>?), <code>Angular</code> similarly spiked as <code>Vue</code> and <code>Web components</code> entered the scene.</p></li><li><p><code>Vue</code> and <code>Web Component</code> activity was lower than <code>React + Vanilla</code>&nbsp;, yet seemed continuous enough to trust each was being maintained.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*u7KfDZ5S1SQOcRYnxCcx2Q.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*u7KfDZ5S1SQOcRYnxCcx2Q.png 424w, https://cdn-images-1.medium.com/max/1200/1*u7KfDZ5S1SQOcRYnxCcx2Q.png 848w, https://cdn-images-1.medium.com/max/1200/1*u7KfDZ5S1SQOcRYnxCcx2Q.png 1272w, https://cdn-images-1.medium.com/max/1200/1*u7KfDZ5S1SQOcRYnxCcx2Q.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*u7KfDZ5S1SQOcRYnxCcx2Q.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*u7KfDZ5S1SQOcRYnxCcx2Q.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*u7KfDZ5S1SQOcRYnxCcx2Q.png 424w, https://cdn-images-1.medium.com/max/1200/1*u7KfDZ5S1SQOcRYnxCcx2Q.png 848w, https://cdn-images-1.medium.com/max/1200/1*u7KfDZ5S1SQOcRYnxCcx2Q.png 1272w, https://cdn-images-1.medium.com/max/1200/1*u7KfDZ5S1SQOcRYnxCcx2Q.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">IBM Carbon&#8217;s main documentation site (left), alongside screenshots of Storybook site navigation for various implementations</figcaption></figure></div><p><a href="https://medium.com/@nathanacurtis/the-fallacy-of-federated-design-systems-23b9a9a05542">Despite my best intentions</a>, there are situations where a federated dream is possible. However, my gut says IBM Carbon is more an exception than rule.</p><p>Virtually every other design system in the world will not achieve or even aim for IBM&#8217;s massive scale. Yet, seeing the models at play&#8202;&#8212;&#8202;central versus federated, web versus native, growth and strategic change over time&#8202;&#8212;&#8202;offer lessons we can all take away.</p><p>So get at it. Clearly communicate your system&#8217;s scope of core library support. Chip away at collaborative best practices to agree on API, critique each other&#8217;s ideas, test and ship as one. We&#8217;re in this together.</p>]]></content:encoded></item><item><title><![CDATA[The Fallacy of Federated Design Systems]]></title><description><![CDATA[Avoid the damage and distress of glorifying the wrong model]]></description><link>https://nathanacurtis.substack.com/p/the-fallacy-of-federated-design-systems-23b9a9a05542</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/the-fallacy-of-federated-design-systems-23b9a9a05542</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Fri, 13 Sep 2024 17:03:43 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/11625e0d-dea2-4985-b547-1a337eac7b7b_2560x1440.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4>Avoid the damage and distress of glorifying the wrong&nbsp;model</h4><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!JNry!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea1abe7-c299-40bf-b5c1-61051b4de62e_2560x1440.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!JNry!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea1abe7-c299-40bf-b5c1-61051b4de62e_2560x1440.png 424w, /__u/substackcdn.com/image/fetch/$s_!JNry!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea1abe7-c299-40bf-b5c1-61051b4de62e_2560x1440.png 848w, /__u/substackcdn.com/image/fetch/$s_!JNry!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea1abe7-c299-40bf-b5c1-61051b4de62e_2560x1440.png 1272w, /__u/substackcdn.com/image/fetch/$s_!JNry!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea1abe7-c299-40bf-b5c1-61051b4de62e_2560x1440.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!JNry!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea1abe7-c299-40bf-b5c1-61051b4de62e_2560x1440.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4ea1abe7-c299-40bf-b5c1-61051b4de62e_2560x1440.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!JNry!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea1abe7-c299-40bf-b5c1-61051b4de62e_2560x1440.png 424w, /__u/substackcdn.com/image/fetch/$s_!JNry!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea1abe7-c299-40bf-b5c1-61051b4de62e_2560x1440.png 848w, /__u/substackcdn.com/image/fetch/$s_!JNry!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea1abe7-c299-40bf-b5c1-61051b4de62e_2560x1440.png 1272w, /__u/substackcdn.com/image/fetch/$s_!JNry!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ea1abe7-c299-40bf-b5c1-61051b4de62e_2560x1440.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>My inquiry of &#8220;So, how can I help?&#8221; was met with design system distress.</p><p>Six months back, the design system team disbanded. In its place, a &#8220;federated model&#8221; of design and engineering staff (none relieved of other responsibilities) was designated to drive design system progress. Yet, the system stalled. Assets are aging. Trust is shaken. Heads are scratched as everyone wonders what to do. Putting a prospective project at risk, I bluntly responded &#8220;Well, you deallocated people responsible for doing the work. What did you expect?&#8221;</p><p>In 2015, I established three <a href="https://medium.com/eightshapes-llc/team-models-for-scaling-a-design-system-2cf9d03be6a0">models of forming teams for scaling design systems</a>: <strong>solitary</strong>, <strong>central</strong>, and <strong>federated</strong>. The article progressed through each, scoffing at solitary, considering central, and favoring federated based on the section&#8217;s positioning and proportional length.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!cETT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe5d29d0-6dee-4748-8f0c-5f6ced2cd6ee_1200x435.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!cETT!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe5d29d0-6dee-4748-8f0c-5f6ced2cd6ee_1200x435.png 424w, /__u/substackcdn.com/image/fetch/$s_!cETT!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe5d29d0-6dee-4748-8f0c-5f6ced2cd6ee_1200x435.png 848w, /__u/substackcdn.com/image/fetch/$s_!cETT!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe5d29d0-6dee-4748-8f0c-5f6ced2cd6ee_1200x435.png 1272w, /__u/substackcdn.com/image/fetch/$s_!cETT!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe5d29d0-6dee-4748-8f0c-5f6ced2cd6ee_1200x435.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!cETT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe5d29d0-6dee-4748-8f0c-5f6ced2cd6ee_1200x435.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/be5d29d0-6dee-4748-8f0c-5f6ced2cd6ee_1200x435.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!cETT!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe5d29d0-6dee-4748-8f0c-5f6ced2cd6ee_1200x435.png 424w, /__u/substackcdn.com/image/fetch/$s_!cETT!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe5d29d0-6dee-4748-8f0c-5f6ced2cd6ee_1200x435.png 848w, /__u/substackcdn.com/image/fetch/$s_!cETT!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe5d29d0-6dee-4748-8f0c-5f6ced2cd6ee_1200x435.png 1272w, /__u/substackcdn.com/image/fetch/$s_!cETT!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbe5d29d0-6dee-4748-8f0c-5f6ced2cd6ee_1200x435.png 1456w" sizes="100vw"></picture><div></div></div></a></figure></div><p>Since then, design system practitioners throughout our community (see articles as examples below) have leveraged and extended the models to frame thinking, promote opportunities, and sell stakeholders on how and why to pursue systems in a federated way.</p><p><strong>Favoring federated was and is wrong. </strong>Since publishing nearly a decade ago, I&#8217;ve been clarifying, nuancing and even contradicting what I wrote. It&#8217;s time to set the record straight.</p><p>In this article, I&#8217;ll dig into how federated is not a choice, it&#8217;s a facet. In practice, it&#8217;s <em>never</em> pursued first and <em>never</em> without central investment. In most cases, it&#8217;s <em>optional</em> and its outcomes can be so expensive and frustrating that it&#8217;s not worth it. Even worse, positioning federated as a primary objective anchors so many stakeholder myths to unwind that it damages system potential and even threatens its existence.</p><h3>Federated dreams are not most people&#8217;s&nbsp;reality</h3><p>Organizations in general and system practitioners specifically strive to involve people. The &#8220;People&#8221; part of design systems is essential, effortful and often difficult. My colleague <a href="https://medium.com/u/f5d1807b4e38">Jina Anne</a> has made that people point in her long running, well known <a href="https://publication.design.systems/design-systems-are-for-people-a484620b6988">Design Systems are For People</a> talk.</p><h4>For, of, and by the&nbsp;people?</h4><p>Couple that focus on people with expectations of governance, and conversations quickly veer into principled territory. A design system shouldn&#8217;t be just <em>for</em> the people, but also <em>of </em>and <em>by</em> the people, right? In many mindsets, that implies <em>of and by <strong>all</strong></em> the people.</p><p>But from a practical and historical perspective, <em>all</em> people making the design system simply isn&#8217;t how it ends up working. Design systems I encounter are made by directly responsible, dedicated teams or individual designer(s) and/or developer(s). Aka, &#8220;Central people&#8221; making a <a href="https://medium.com/eightshapes-llc/a-design-system-isn-t-a-project-it-s-a-product-serving-products-74dcfffef935">design system as a product, serving products</a>.</p><p>Sure, there&#8217;s also services supporting a community to <a href="https://medium.com/eightshapes-llc/stewarding-design-system-contributions-817665b6c7dd">steward participation, influence and even contribution</a> (<a href="https://medium.com/eightshapes-llc/defining-design-system-contributions-eb48e00e8898">those are different concepts</a>, mind you). Those <a href="https://medium.com/eightshapes-llc/why-contributions-matter-22652d8676c6">contributions matter</a>, right? I guess so. However, virtually all productive output is delivered by central people.</p><h4>Federated-only exceptions distract and muddle conversations</h4><p>I can hear a few of you now: &#8220;I got federated-only to work!&#8221;</p><p>Sure, maybe in a limited context or temporal endeavor. Those situations are inconsistent with how I <a href="https://medium.com/eightshapes-llc/defining-design-systems-6dd4b03e0ff6">define design systems</a>: deliver foundations and UI components via evolving, ideally mirrored design and code libraries that scaling organizations depend on.</p><p>Sure, maybe it works if exceedingly rare conditions hold. I&#8217;m aware of a fellow expert that combines inarguable talent, sharp intelligence, supreme confidence, and unassailable authority to drive product outcomes without a central design system team. I&#8217;ve read righteous claims of a small group of collaboratively-tight, high-performing, coding-capable designers evolving a product without a design system at all (there are systems in there somewhere, nevertheless). The federated dream comes alive!</p><h4>Federated people don&#8217;t and can&#8217;t prioritize (extra) system&nbsp;work</h4><p>However, my experience suggests a different reality. The hope for aligned outputs emerging from independent federated contributors driven by altruism is at best misplaced. At its worst, it&#8217;s recklessly naive. I see organizations orient priorities to evolve products, individuals align to those priorities, and no one set aside an allowance for system contribution.</p><p>My consulting across 80+ design system spans diverse setups: product or marketing, adopter communities large (100s) or small (10s), design-only or design-and-code, etc. Every organization sought system success and was willing to invest.</p><p>How many had a wizard oozing confidence, tight-enough collaborative culture, or other secret that made federated&#8211;only magic happen?</p><div class="captioned-image-container"><figure><figcaption class="image-caption">Steve Carrell as Mark Baum declares &#8220;Zero.&#8221; in <a href="https://www.youtube.com/watch?v=_4KrHwvtxrc">The Big Short</a></figcaption></figure></div><p>In the spirit of Steve Carrell&#8217;s memorable portrayal of disdainful expert Mark Baum in <a href="https://en.wikipedia.org/wiki/The_Big_Short_%28film%29">The Big Short</a>: &#8220;Zero. Zero. Zero percent [of design systems thrived without centrally allocated people to make and support it].&#8221;</p><p>None experienced federated-only success without a investment in central capacity. Federated-only is not a choice.</p><h3>Federated is a False&nbsp;Choice</h3><p>So let&#8217;s get to it. Why isn&#8217;t federated-only a choice?</p><p>The diagram&#8217;s arrangement implies choice, unfortunately. Should your design system be centrally managed or a federated community?</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!T5dG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad2b29e7-8e50-4606-9621-5ee479cfb910_1200x436.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!T5dG!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad2b29e7-8e50-4606-9621-5ee479cfb910_1200x436.png 424w, /__u/substackcdn.com/image/fetch/$s_!T5dG!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad2b29e7-8e50-4606-9621-5ee479cfb910_1200x436.png 848w, /__u/substackcdn.com/image/fetch/$s_!T5dG!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad2b29e7-8e50-4606-9621-5ee479cfb910_1200x436.png 1272w, /__u/substackcdn.com/image/fetch/$s_!T5dG!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad2b29e7-8e50-4606-9621-5ee479cfb910_1200x436.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!T5dG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad2b29e7-8e50-4606-9621-5ee479cfb910_1200x436.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ad2b29e7-8e50-4606-9621-5ee479cfb910_1200x436.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!T5dG!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad2b29e7-8e50-4606-9621-5ee479cfb910_1200x436.png 424w, /__u/substackcdn.com/image/fetch/$s_!T5dG!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad2b29e7-8e50-4606-9621-5ee479cfb910_1200x436.png 848w, /__u/substackcdn.com/image/fetch/$s_!T5dG!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad2b29e7-8e50-4606-9621-5ee479cfb910_1200x436.png 1272w, /__u/substackcdn.com/image/fetch/$s_!T5dG!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fad2b29e7-8e50-4606-9621-5ee479cfb910_1200x436.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The article bridged to federated misleadingly with <em>&#8220;if a central model doesn&#8217;t fit, there is a more complicated path to pursue&#8230;&#8221;</em> The implication was clear: choose federated! Ugh. Positioning central versus federated as a mutually exclusive choice was a mistake.</p><h4>Embracing federated doesn&#8217;t mean avoiding&nbsp;central</h4><p>That&#8217;s thinking in binary, described well in <a href="https://www.amazon.com/Black-White-Thinking-Burden-Complex/dp/1250829453/ref=tmm_pap_swatch_0?_encoding=UTF8&amp;dib_tag=se&amp;dib=eyJ2IjoiMSJ9.fCyRr4zq4XSMwuXkcB7Lg52MBd3-BEuXOZho_cJ6KibBXBMFvW8WJvu1VDWlay9ymOOhysW8jju_Nxz9WZj6MBikJjFqUhEwQaRakqx4ouxqJoCc04zTafzQ9vafykZf8Ysporuo5PCBxtY7AR7FOUeI9rNx_mWXd4xc-0Zrt7lOi4ACoR8mmjJjq2LACProG-o4cFDbTekQd8DeR5BquGtBA1uqP5kAuRk3g0YYNgM.ecV6WkVEsVGM5cAWh8YhTyKVvV2rD-U2uIMYjDO_kIQ&amp;qid=1726158216&amp;sr=8-1">Black and White Thinking:The Burden of a Binary Brain in a Complex World</a>. Just because there&#8217;s two options doesn&#8217;t make them mutually exclusive. It certainly doesn&#8217;t mean that if federated is desirable, then central isn&#8217;t. Shift that <strong>or</strong> to an <strong>and</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!9tep!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33d76615-b5e6-4a55-ab4f-124252f0ec10_1200x436.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!9tep!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33d76615-b5e6-4a55-ab4f-124252f0ec10_1200x436.png 424w, /__u/substackcdn.com/image/fetch/$s_!9tep!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33d76615-b5e6-4a55-ab4f-124252f0ec10_1200x436.png 848w, /__u/substackcdn.com/image/fetch/$s_!9tep!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33d76615-b5e6-4a55-ab4f-124252f0ec10_1200x436.png 1272w, /__u/substackcdn.com/image/fetch/$s_!9tep!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33d76615-b5e6-4a55-ab4f-124252f0ec10_1200x436.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!9tep!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33d76615-b5e6-4a55-ab4f-124252f0ec10_1200x436.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/33d76615-b5e6-4a55-ab4f-124252f0ec10_1200x436.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!9tep!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33d76615-b5e6-4a55-ab4f-124252f0ec10_1200x436.png 424w, /__u/substackcdn.com/image/fetch/$s_!9tep!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33d76615-b5e6-4a55-ab4f-124252f0ec10_1200x436.png 848w, /__u/substackcdn.com/image/fetch/$s_!9tep!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33d76615-b5e6-4a55-ab4f-124252f0ec10_1200x436.png 1272w, /__u/substackcdn.com/image/fetch/$s_!9tep!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F33d76615-b5e6-4a55-ab4f-124252f0ec10_1200x436.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>In my practice, successful design systems <em>always</em> have a central team and <em>always </em>seek the participation (and, if worth it, contribution) from a federated community. Evolving models to invest in both to varying degrees.</p><h4>Being only federated doesn&#8217;t&nbsp;work</h4><p>When discussions get tough, bracket the conversation with an uncomfortable extreme. Injecting an intentionally impractical assertion can establish the value of centrally allocated people:</p><blockquote><p>It&#8217;s not as if we should create an empty Figma library file, empty code repository, and empty ZeroHeight instance and encourage contributors to have at it.</p></blockquote><p>Instead, central people setup architecture, create tools, define process, create playbooks, and support the platform. 100% of the time, those central people make and maintain the core components too.</p><h4>Don&#8217;t choose federated. Instead, add federated. Gradually.</h4><p>As you consider your system&#8217;s future, consider how to progressively <em>add</em> federated contribution gradually to a centrally supported endeavor.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!diir!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45dfc3b6-1bbb-481b-a7f5-be873e3b19f4_1200x490.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!diir!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45dfc3b6-1bbb-481b-a7f5-be873e3b19f4_1200x490.png 424w, /__u/substackcdn.com/image/fetch/$s_!diir!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45dfc3b6-1bbb-481b-a7f5-be873e3b19f4_1200x490.png 848w, /__u/substackcdn.com/image/fetch/$s_!diir!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45dfc3b6-1bbb-481b-a7f5-be873e3b19f4_1200x490.png 1272w, /__u/substackcdn.com/image/fetch/$s_!diir!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45dfc3b6-1bbb-481b-a7f5-be873e3b19f4_1200x490.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!diir!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45dfc3b6-1bbb-481b-a7f5-be873e3b19f4_1200x490.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/45dfc3b6-1bbb-481b-a7f5-be873e3b19f4_1200x490.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!diir!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45dfc3b6-1bbb-481b-a7f5-be873e3b19f4_1200x490.png 424w, /__u/substackcdn.com/image/fetch/$s_!diir!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45dfc3b6-1bbb-481b-a7f5-be873e3b19f4_1200x490.png 848w, /__u/substackcdn.com/image/fetch/$s_!diir!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45dfc3b6-1bbb-481b-a7f5-be873e3b19f4_1200x490.png 1272w, /__u/substackcdn.com/image/fetch/$s_!diir!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F45dfc3b6-1bbb-481b-a7f5-be873e3b19f4_1200x490.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>If federated work really succeeds, you may even tune down central investment as circumstances permit. A stable and complete core architecture (when the <a href="https://medium.com/@nathanacurtis/design-system-generations-65f99960dc3d">design system isn&#8217;t going through a period of generational change</a>) can evolve with federated contributions coupled with a lower investment in central curation. Don&#8217;t hold your breath, however. I&#8217;ve rarely experienced conditions in the past decade where either stable or complete hold for long, let alone both.</p><h4>Federated is optional.</h4><p>Some teams gradually incorporate federated influence, such as via <a href="https://medium.com/eightshapes-llc/design-system-tiers-2c827b67eae1">tiers</a> and <a href="https://medium.com/eightshapes-llc/figma-shared-libraries-d2dfbf9d1b8d">shared libraries</a>. However, many systems thrive and create tremendous value without a focus on contributions. Some systems even transcend contributions, shedding responsibility to let the community fend for itself.</p><p>I revere <a href="https://atlassian.design/">Atlassian&#8217;s design system</a> and have cited the Atlaskit code catalog for years as a vibrant melting pot of contribution. Their community-supported <a href="https://www.npmjs.com/package/@atlaskit/editor-core?activeTab=versions">Editor component</a> hit major version 197 recently! Yet, Editor seems a concern now separate from the core system, which explicitly <a href="https://atlassian.design/resources/contribution">limits contributions to fixes</a>:</p><blockquote><p>We are currently accepting&nbsp;&#8230; <strong>fixes</strong>&nbsp;&#8230; At this time, we are unable to take <strong>[small enhancement, major enhancement, and new component or pattern]</strong> contributions.</p></blockquote><p>Their rationale cites familiar values: build for widely shared need, ensure quality, avoid being a bottleneck. Just because Editor is a component, serving and evolved by a community doesn&#8217;t mean it &#8220;goes in the <em>design system</em>&#8221; (even though it&#8217;s clearly in <em>a system</em>). I love it!</p><h3>Federated Anchors Damaging&nbsp;Myths</h3><p>Stakeholders anchor assumptions the moment they see that diagram.</p><p>An <a href="https://en.wikipedia.org/wiki/Anchoring_effect">anchoring bias</a> is a cognitive bias by which stakeholders rely heavily on what&#8217;s first presented (and how they interpret it), and new information is referenced relative to that anchor rather than considered objectively. This distorts new information, impairing influence and decision making.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!5eEH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e0099a-d1e7-465f-9f93-b217906eb9f5_1200x436.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!5eEH!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e0099a-d1e7-465f-9f93-b217906eb9f5_1200x436.png 424w, /__u/substackcdn.com/image/fetch/$s_!5eEH!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e0099a-d1e7-465f-9f93-b217906eb9f5_1200x436.png 848w, /__u/substackcdn.com/image/fetch/$s_!5eEH!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e0099a-d1e7-465f-9f93-b217906eb9f5_1200x436.png 1272w, /__u/substackcdn.com/image/fetch/$s_!5eEH!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_webp, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e0099a-d1e7-465f-9f93-b217906eb9f5_1200x436.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!5eEH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e0099a-d1e7-465f-9f93-b217906eb9f5_1200x436.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/16e0099a-d1e7-465f-9f93-b217906eb9f5_1200x436.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!5eEH!, /__u/nathanacurtis.substack.com/w_424, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e0099a-d1e7-465f-9f93-b217906eb9f5_1200x436.png 424w, /__u/substackcdn.com/image/fetch/$s_!5eEH!, /__u/nathanacurtis.substack.com/w_848, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e0099a-d1e7-465f-9f93-b217906eb9f5_1200x436.png 848w, /__u/substackcdn.com/image/fetch/$s_!5eEH!, /__u/nathanacurtis.substack.com/w_1272, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e0099a-d1e7-465f-9f93-b217906eb9f5_1200x436.png 1272w, /__u/substackcdn.com/image/fetch/$s_!5eEH!, /__u/nathanacurtis.substack.com/w_1456, /__u/nathanacurtis.substack.com/c_limit, /__u/nathanacurtis.substack.com/f_auto, /__u/nathanacurtis.substack.com/q_auto:good, /__u/nathanacurtis.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16e0099a-d1e7-465f-9f93-b217906eb9f5_1200x436.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Many of those assumptions are damaging myths, including:</p><p>&#9875;&#65038; Everyone can, should and will contribute.<br>&#9875;&#65038; Every component made goes in the system.<br>&#9875;&#65038; Anyone that makes UI is capable of contributing.<br>&#9875;&#65038; All UI components of any level of composition are welcome.<br>&#9875; &#65038;Federated contribution is a primary success indicator.<br>&#9875; Federated gets you a design system for free.</p><p>When educating stakeholders, you want to be on the front foot. You want to confidently build a rational case so they understand impacts, opportunities, risks and efforts ahead. You don&#8217;t want to position yourself as saying &#8220;No&#8221; repeatedly to correct mistaken assumptions of superiors that approve or deny the system&#8217;s existence.</p><p>So, you face a choice: let the anchored myths stick, or contradict your stakeholders and unwind the myths. <a href="https://en.wikipedia.org/wiki/Weigh_anchor">Weighing anchor</a> is difficult, effortful and worst of all, risky. Let&#8217;s dig in to each one.</p><h4><strong>Myth: </strong>&#9875; <strong>Everyone can, should and will contribute.</strong></h4><p>Fact: Few if any contribute meaningful new features and enhancements.</p><blockquote><p>Wait, if almost no one will contribute, then this isn&#8217;t made by everybody?&nbsp;<br>(Yes.)&nbsp;<br>That&#8217;s bad.</p></blockquote><p>It can be very, very good to have central team makes a library everyone depends on. A central team can focus on details, solicit shared needs, architect small parts into a cohesive whole, document and release it, and support others. Federated people don&#8217;t, can&#8217;t and/or won&#8217;t do that.</p><h4>Myth: &#9875; <strong>Every component made goes in the&nbsp;system.</strong></h4><p>Fact: Almost all components made across teams don&#8217;t belong in the system.</p><blockquote><p>Wait, so the system will have barely any components our organization makes, and most of the UI everyone makes isn&#8217;t going to be shared?&nbsp;<br>(Yes.)&nbsp;<br>That stinks.</p></blockquote><p>Design systems offer assets that serve widely shared needs and prioritize features that can evolve in a stable way to serve many groups.</p><p>You should expect that teams will still need to create considerable UI <em>using</em> system assets. You should also expect that most components that teams make&#8202;&#8212;&#8202;even low level components&#8202;&#8212;&#8202;will not serve a need shared by other teams, and thus don&#8217;t belong in any system.</p><h4>Myth: &#9875; Anyone that makes UI is capable of contributing<strong>.</strong></h4><p>Fact: Most contributors lack systems experience generally and knowledge of this system&#8217;s architecture specifically to contribute efficiently.</p><blockquote><p>Wait, so people can&#8217;t contribute because you say they lack skills?&nbsp;<br>(Yes.)&nbsp;<br>That&#8217;s terrible gatekeeping and risks morale.</p></blockquote><p>Design systems are about business value. If the cost to steward a contribution (effort of all participants plus maintenance and <a href="https://en.wikipedia.org/wiki/Opportunity_cost">opportunity cost</a>s) exceeds business benefits (value of reusable assets <em>and</em> staff personal development), then the contribution is a bad idea. Only do it if it&#8217;s worth it.</p><p>Additionally, identifying <a href="https://medium.com/@mmamet/directly-responsible-individuals-f5009f465da4">directly responsible individuals</a> (DRI) and teams leads to the clarity needed for a satisfying workplace. Positioning capable and talented staff in DRI roles is a strength.</p><p>Finally, central systems practitioners are responsible to support system integration, pair with others, and curate contributions that do arise. Sharing knowledge and resolving incidents responsively are ways of how system practitioners can be a rising tide lifting everyone&#8217;s capability.</p><h4>Myth: &#9875; Components of any level of composition are&nbsp;welcome.</h4><p>Fact: Design systems are visual foundations threaded through a library of usually lower-level UI components that equip teams to compose digital experiences on their own teams.</p><blockquote><p>Wait, system UI components are limited to a bunch of low-level widgets?&nbsp;<br>(Yes, at least in the core library.)&nbsp;<br>That&#8217;s lame and lacks business value.</p></blockquote><p>There&#8217;s a ton of business value in that. Have you seen what goes into a system&#8217;s <code>button</code>, <code>alert</code>&nbsp;, <code>textInput</code> or <code>modal</code>? Each relies on 10s or 100s of visual attributes across a component&#8217;s anatomy, property configurations, layouts, behaviors and other stuff. That&#8217;s measurable work, done at a high-level of accessible quality, packaged as design and code libraries so that other teams don&#8217;t need to make that stuff.</p><h4>Myth: &#9875; <strong>Federated contribution is our primary success indicator.</strong></h4><p>Fact: Core libraries made by a central team and containing no contributions from outsiders can be extremely valuable.</p><blockquote><p>Wait, if our goals are to <strong>make</strong> a library and enable other people to <strong>use</strong> the library, how does users that <strong>contribute</strong> to the library matter?<br>(Exactly.)<br>That feels wrong.</p></blockquote><p>When semi-annual or annual planning season comes along, federated contribution is rarely a published objective and never an existential one focusing a significant proportion of central people&#8217;s capacity (although efforts to like <a href="https://medium.com/eightshapes-llc/figma-shared-libraries-d2dfbf9d1b8d">Figma Shared Libraries</a> are pursued secondarily).</p><p>Instead, federated investments are often on the periphery, deprioritized in favor of other efforts. It&#8217;s never a galvanizing singular focus of a system&#8217;s team relative to responsible people making system outputs and enabling others to successfully use them.</p><h4>Myth: &#9875; Federated gets you a design system for&nbsp;free.</h4><p>Fact: Successful federated activity requires a non-trivial capital expense and ongoing operational costs to make and maintain a platform, support federated people, and curate contributions. It&#8217;s not free.</p><blockquote><p>Wait, so I need to pay for a group of people to build a platform and make it all work when seconds ago I thought this was largely free?<br>(Yes.)&nbsp;<br>That&#8217;s expensive.</p></blockquote><p>Going federated in the long run means more than composing a designer&#8217;s playbook (often not read) and developer&#8217;s <code>CONTRIBUTING.md</code>. There&#8217;s far more work needed.</p><p>Once built, using platforms isn&#8217;t a long leap for developers. Coding in systems should be familiar: build modularly, manage dependencies, run test suites, commit to repos, review a pull request. Tasks are familiar (if with some system spice) such that once setup, running a platform can be predictable. However, there&#8217;s still the work of curation, quality and approval for core engineering maintainers to do.</p><p>Familiarity is less true for designers, where <a href="https://medium.com/eightshapes-llc/design-system-ui-is-more-expensive-than-a-product-teams-ui-f3c3e48c555">diverse tasks carry unfamiliar system-specific expectations</a>. Audit and synthesize shared needs. Compare existing component examples. Devise an API. Document usage. <a href="https://medium.com/eightshapes-llc/testing-figma-components-a47fc978465f">Produce and test </a><em><a href="https://medium.com/eightshapes-llc/testing-figma-components-a47fc978465f">high quality</a></em><a href="https://medium.com/eightshapes-llc/testing-figma-components-a47fc978465f"> Figma assets</a>. The bar is higher and skills are different than &#8220;normal product design work.&#8221;</p><p>Learning takes practice and collaboration time with system experts (read: operational cost) to produce good things and grow individually. I love that work, which offers tremendous intrinsic reward. But it&#8217;s time consuming. You reap what you sow.</p><p>Did you notice how verbose it is explaining away those myths? Did you even read the text above, or did you skim it as your mind drifted?</p><p>Now, imagine you are a stakeholder that had to listen to someone&#8202;&#8212;&#8202;often lower level or from a different group&#8202;&#8212;&#8202;contradicting what you believe. So be careful. Explaining what you don&#8217;t get with federated contribution isn&#8217;t just complicated. It risks irritation, boredom, distraction, insufficient time, indignation, and dismissiveness. Such emotions are not to be trifled with.</p><h3>References to Central v Federated Models</h3><p>The following posts all reference the concepts of central and federated models described in <a href="https://medium.com/eightshapes-llc/team-models-for-scaling-a-design-system-2cf9d03be6a0">Team Models for Scaling a Design System</a>.</p><ol><li><p><a href="https://medium.com/salesforce-ux/the-salesforce-team-model-for-scaling-a-design-system-d89c2a2d404b">The Salesforce Team Model for Scaling a Design System</a> by <a href="https://medium.com/u/f5d1807b4e38">Jina Anne</a>, 2015</p></li><li><p><a href="https://www.linkedin.com/pulse/designing-design-system-step-guide-sascha-marc-louis-henrich/">Designing a Design System (a step by step guide)</a> by Louis Henrich, 2017</p></li><li><p><a href="https://uxplanet.org/scaling-design-as-the-company-grows-e99af38f9e8d">Scaling Design as the Company Grows</a> by <a href="https://medium.com/u/4709e5887030">Ian Armstrong</a>, 2018</p></li><li><p><a href="https://spotify.design/article/the-paradox-of-design-systems">The Paradox of Design Systems</a> by <a href="https://medium.com/u/b58d5887fe0f">Brendon Manwaring</a> and <a href="https://medium.com/u/506b37832ee2">Josh Mateo</a>, 2018</p></li><li><p><a href="https://www.smashingmagazine.com/2019/05/tips-managing-design-systems/">Tips For Managing Design Systems</a> by <a href="https://medium.com/u/bcab753a4d4e">Nick Babich</a>, 2019</p></li><li><p><a href="https://bootcamp.uxdesign.cc/design-systems-why-do-they-matter-83149e76101c">Design Systems: Why Do They Matter?</a> by <a href="https://medium.com/u/63e1625a9efa">Marcela Morales</a>, 2021</p></li><li><p><a href="https://isadoradigitalagency.com/insights/strategy/ux-design-teams">Remarkable UX Design Teams</a> by <a href="https://medium.com/u/85d64590100">Isadora Agency</a>, After 2019</p></li><li><p><a href="https://www.linkedin.com/pulse/how-do-teams-work-your-design-system-raktim-chatterjee/">How do teams work with your Design System?</a> by Raktim Chatterjee, 2022</p></li><li><p><a href="https://rangle.io/blog/is-your-design-system-performing">Is your design system performing?</a> by <a href="https://medium.com/u/7f33e8acc40">Alicia Cheung</a> and Rebecca Holland, 2022</p></li><li><p><a href="https://www.viget.com/articles/design-systems-investing-in-the-people-behind-the-system/">Design Systems: Investing in the People Behind the System</a> by <a href="https://medium.com/u/cf83bc1ff014">Rene&#233; Cagnina Haynes</a>, 2022</p></li><li><p><a href="https://apiko.com/blog/enterprise-design-system/">From Vision to Reality: The Roadmap to Building an Enterprise Design System</a> by Oleksii Popovych, 2023</p></li><li><p><a href="https://bootcamp.uxdesign.cc/opening-up-the-design-system-for-everyone-11b9b92f3f75">Opening up the Design System for Everyone&#8202;&#8212;&#8202;The Federated Model</a> by <a href="https://medium.com/u/b4cb61d5a5c0">Anirudh Hothur</a>, 2023</p></li><li><p><a href="https://www.netguru.com/blog/design-system-in-existing-product">Implementing a Design System in an Existing Product</a> by<a href="https://medium.com/u/13df56357048">Justyna Klimkowska</a>, 2024</p></li><li><p><a href="https://www.baianat.com/books/merits-of-design-systems/design-systems-and-their-benefits">The merits of design systems</a> by Balanet, 2024</p></li><li><p><a href="https://www.netguru.com/blog/roi-design-systems">ROI of Having a Design System by Kim Nguyen</a>, 2024</p></li><li><p><a href="https://webflow.com/blog/enterprise-design-systems">How to build effective enterprise design systems for your company</a> by Webflow, 2024</p></li><li><p><a href="https://www.mikhailbelstar.com/portfolio/project-ds-fevo">Design System: Pancake</a> by <a href="https://medium.com/u/784637ff1e0f">Mikhail Belstar</a></p></li><li><p><a href="https://www.designsystems.com/keeping-design-system-contributions-in-check/">Keeping design system contributions in check</a> by <a href="https://medium.com/u/d86823ecc6f0">Wart Burggraaf</a></p></li></ol>]]></content:encoded></item><item><title><![CDATA[Adopting Design System Generations]]></title><description><![CDATA[How to face and reframe challenges of a changing system]]></description><link>https://nathanacurtis.substack.com/p/adopting-design-system-generations-900535442a16</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/adopting-design-system-generations-900535442a16</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Mon, 11 Mar 2024 18:20:39 GMT</pubDate><enclosure url="https://cdn-images-1.medium.com/max/2560/1*Q54M9xeo0bWFee9BvYp9sA.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4>How to face and reframe challenges of a changing&nbsp;system</h4><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/2560/1*Q54M9xeo0bWFee9BvYp9sA.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/2560/1*Q54M9xeo0bWFee9BvYp9sA.png 424w, https://cdn-images-1.medium.com/max/2560/1*Q54M9xeo0bWFee9BvYp9sA.png 848w, https://cdn-images-1.medium.com/max/2560/1*Q54M9xeo0bWFee9BvYp9sA.png 1272w, https://cdn-images-1.medium.com/max/2560/1*Q54M9xeo0bWFee9BvYp9sA.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/2560/1*Q54M9xeo0bWFee9BvYp9sA.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/2560/1*Q54M9xeo0bWFee9BvYp9sA.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/2560/1*Q54M9xeo0bWFee9BvYp9sA.png 424w, https://cdn-images-1.medium.com/max/2560/1*Q54M9xeo0bWFee9BvYp9sA.png 848w, https://cdn-images-1.medium.com/max/2560/1*Q54M9xeo0bWFee9BvYp9sA.png 1272w, https://cdn-images-1.medium.com/max/2560/1*Q54M9xeo0bWFee9BvYp9sA.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p><em>#3 of 5 of the series Design Systems Generations:<br></em><a href="https://medium.com/@nathanacurtis/design-system-generations-65f99960dc3d">Defining</a> | <a href="https://medium.com/@nathanacurtis/planning-a-design-system-generation-ce4120393557">Planning</a> | <strong>Adopting</strong> | Naming |Retiring</p><blockquote><p>What&#8217;s changing? All colors, typography, space and component designs.&nbsp;<br>Why? Because executives decided to.<br>How big is the change? It&#8217;s big. More a revolution than a refinement.</p></blockquote><p>Now that you&#8217;ve painted the big picture, it&#8217;s time to talk specifics. What does all this mean to how adopters must change? Each adopter&#8217;s questions reveal the bias of they may see their world:</p><blockquote><p>&#8220;When can we start?&#8221;<em> (&#8594; Eager)</em><br>&#8220;By when must we be done?&#8221;<em> (&#8594; Pragmatic)</em><br>&#8220;Do we have to? What if we don&#8217;t?&#8221;<em> (&#8594; Reluctant)</em><br>&#8220;What if we didn&#8217;t use your system to do it?&#8221;<em> (&#8594; Individualist)</em></p></blockquote><p>These questions aren&#8217;t complicated. Unfortunately, answers can be. Harried product owners and leaders may not be interested in what to them feel like complicated conversations. For generational changes, answering sufficiently requires you understanding who&#8217;s asking it and their patience to listen. Both may be in short supply. Under pressure, they just want to get on with it and see a system as blocking them from delivering the goods. Heck, will they even wait?</p><p>This post covers common challenges that emerge when aligning how a design system <em>deliver</em> changes to adopting teams to <em>integrate</em> that change into their experiences.</p><h4>Challenge 1: A system IS a dependency. Or, lots of&nbsp;them.</h4><p>When keen adopters ask &#8220;How long?&#8221;, you can&#8217;t keep responding &#8220;We&#8217;ll let you know.&#8221; A system generation may take three, six, twelve or even more months, and you must <a href="https://medium.com/@nathanacurtis/planning-a-design-system-generation-ce4120393557">have a plan</a> to clearly communicate. As you start to explain things, reality sets in. You deliver things like colors and components to them, and then they integrate them. That puts the system in a position of being &#8220;The Dependency.&#8221;</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*JPeAKAODMCBI-wBj6UOGMw.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*JPeAKAODMCBI-wBj6UOGMw.png 424w, https://cdn-images-1.medium.com/max/1200/1*JPeAKAODMCBI-wBj6UOGMw.png 848w, https://cdn-images-1.medium.com/max/1200/1*JPeAKAODMCBI-wBj6UOGMw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*JPeAKAODMCBI-wBj6UOGMw.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*JPeAKAODMCBI-wBj6UOGMw.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*JPeAKAODMCBI-wBj6UOGMw.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;DON&#8217;T reinforce perceptions of the system as a monolithic dependency&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="DON&#8217;T reinforce perceptions of the system as a monolithic dependency" title="DON&#8217;T reinforce perceptions of the system as a monolithic dependency" srcset="https://cdn-images-1.medium.com/max/1200/1*JPeAKAODMCBI-wBj6UOGMw.png 424w, https://cdn-images-1.medium.com/max/1200/1*JPeAKAODMCBI-wBj6UOGMw.png 848w, https://cdn-images-1.medium.com/max/1200/1*JPeAKAODMCBI-wBj6UOGMw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*JPeAKAODMCBI-wBj6UOGMw.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">DON&#8217;T reinforce perceptions of the system as a monolithic dependency</figcaption></figure></div><p>Yet, a design system library is made of many subsystems and component parts. That means you can decompose delivery into a succession of dependencies as relevant for adopters.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*OgvkBsVUzgjSbKoa8mR7vw.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*OgvkBsVUzgjSbKoa8mR7vw.png 424w, https://cdn-images-1.medium.com/max/1200/1*OgvkBsVUzgjSbKoa8mR7vw.png 848w, https://cdn-images-1.medium.com/max/1200/1*OgvkBsVUzgjSbKoa8mR7vw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*OgvkBsVUzgjSbKoa8mR7vw.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*OgvkBsVUzgjSbKoa8mR7vw.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*OgvkBsVUzgjSbKoa8mR7vw.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;DO position the system as capable of incremental delivery for those interested&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="DO position the system as capable of incremental delivery for those interested" title="DO position the system as capable of incremental delivery for those interested" srcset="https://cdn-images-1.medium.com/max/1200/1*OgvkBsVUzgjSbKoa8mR7vw.png 424w, https://cdn-images-1.medium.com/max/1200/1*OgvkBsVUzgjSbKoa8mR7vw.png 848w, https://cdn-images-1.medium.com/max/1200/1*OgvkBsVUzgjSbKoa8mR7vw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*OgvkBsVUzgjSbKoa8mR7vw.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">DO position the system as capable of incremental delivery for those interested</figcaption></figure></div><ul><li><p>Adopters <em>must</em> be encouraged to start before a system is done. To deliver incrementally means they could integrate incrementally too if it helps.</p></li><li><p>Adopter <em>should</em> influence priorities to get what they need when they need it, which may give the system more time for other things too.</p></li><li><p>Adopters <em>could</em> finish before the system finishes, since the system can defer features many don&#8217;t need to the end. Wouldn&#8217;t that be delightful?</p></li></ul><p><em>Takeaway</em>: Be generous with the time you invest in crafting, sharing, aligning and nurturing plans with adopters throughout the cycle. Critical is a shared sense of purpose in delivering value to end customers. We&#8217;re in this together. So let&#8217;s figure this out and deliver as best we can, together.</p><h4>Challenge 2: The system HAS dependencies</h4><p>What&#8217;s more challenging than the system <em>being</em> a dependency? A system that <em>has</em> dependencies causing it to move slowly, wait, or not even start.</p><p>A typical example: the system team may be blocked by an agency hired by design and brand VPs to establish a new design language. The agency may iterate, concept after concept. Delays arise when stakeholders schedules don&#8217;t align. Iterations continue to get things just right. Nobody seems to acknowledge that all the iteration impacts timing of delivering downstream work.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*3d5ZhkPbaekEvEAX4Yrc-g.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*3d5ZhkPbaekEvEAX4Yrc-g.png 424w, https://cdn-images-1.medium.com/max/1200/1*3d5ZhkPbaekEvEAX4Yrc-g.png 848w, https://cdn-images-1.medium.com/max/1200/1*3d5ZhkPbaekEvEAX4Yrc-g.png 1272w, https://cdn-images-1.medium.com/max/1200/1*3d5ZhkPbaekEvEAX4Yrc-g.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*3d5ZhkPbaekEvEAX4Yrc-g.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*3d5ZhkPbaekEvEAX4Yrc-g.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;DON&#8217;T let a system&#8217;s reality of dependencies position the system as a blocker&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="DON&#8217;T let a system&#8217;s reality of dependencies position the system as a blocker" title="DON&#8217;T let a system&#8217;s reality of dependencies position the system as a blocker" srcset="https://cdn-images-1.medium.com/max/1200/1*3d5ZhkPbaekEvEAX4Yrc-g.png 424w, https://cdn-images-1.medium.com/max/1200/1*3d5ZhkPbaekEvEAX4Yrc-g.png 848w, https://cdn-images-1.medium.com/max/1200/1*3d5ZhkPbaekEvEAX4Yrc-g.png 1272w, https://cdn-images-1.medium.com/max/1200/1*3d5ZhkPbaekEvEAX4Yrc-g.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">DON&#8217;T let a system&#8217;s reality of dependencies position the system as a&nbsp;blocker</figcaption></figure></div><p>The system team may not control any of this. Heck, the system team may not be in many of these conversations. Such opaqueness and uncertainty can feel paralyzing. Even worse, it&#8217;s the system that seems &#8220;The Blocker.&#8221;</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*QAXEFR-r0IC7yDY7h2p3SA.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*QAXEFR-r0IC7yDY7h2p3SA.png 424w, https://cdn-images-1.medium.com/max/1200/1*QAXEFR-r0IC7yDY7h2p3SA.png 848w, https://cdn-images-1.medium.com/max/1200/1*QAXEFR-r0IC7yDY7h2p3SA.png 1272w, https://cdn-images-1.medium.com/max/1200/1*QAXEFR-r0IC7yDY7h2p3SA.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*QAXEFR-r0IC7yDY7h2p3SA.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*QAXEFR-r0IC7yDY7h2p3SA.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;DO position system practices as flexible to start activities early, balancing benefits with the risks of unstable inputs&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="DO position system practices as flexible to start activities early, balancing benefits with the risks of unstable inputs" title="DO position system practices as flexible to start activities early, balancing benefits with the risks of unstable inputs" srcset="https://cdn-images-1.medium.com/max/1200/1*QAXEFR-r0IC7yDY7h2p3SA.png 424w, https://cdn-images-1.medium.com/max/1200/1*QAXEFR-r0IC7yDY7h2p3SA.png 848w, https://cdn-images-1.medium.com/max/1200/1*QAXEFR-r0IC7yDY7h2p3SA.png 1272w, https://cdn-images-1.medium.com/max/1200/1*QAXEFR-r0IC7yDY7h2p3SA.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">DO position system practices as flexible to start activities early, balancing benefits with the risks of unstable&nbsp;inputs</figcaption></figure></div><p>So, to serve adopters best, shift the mindset to getting &#8220;The Head Start&#8221; instead. Getting a head start can include:</p><ul><li><p>Quick passes to inject emerging design language choices into existing system assets to show the future (and expose gaps from here to there).</p></li><li><p>Explore refactored system models&#8202;&#8212;&#8202;token taxomony, expanded modes, a spike of component code&#8202;&#8212;&#8202;based on emerging designs even if those designs are unstable or disposable.</p></li><li><p>Coordinate with upstream providers to deliver incrementally, too. Could they finish color language before optimizing typography? Could semantic colors be delivered before data visualization palettes?</p></li></ul><p><em>Takeaway</em>: Challenge yourself to start the system engine without waiting for dependencies to finish. Possible setbacks and wasted work occur. That&#8217;s the game you play. But when time is short, it can be worth the risk.</p><h4>Challenge 3: Adopters may be unwilling to&nbsp;wait</h4><p>Separating an agency&#8217;s design language activities from a system team&#8217;s library production exposes most dangerous misperception: Once a design language is approved, adopters can get started, right? Not so fast. Most of the system team&#8217;s work to finalize, code, test and produce library assets may be just beginning.</p><p>Will adopters wait? If they don&#8217;t, what if they deliver the design directly themselves? When an external force triggers change, speed to market creates pressure on adopters to implement <em>without system assets</em>. They&#8217;ll push the system to the side or ignore it altogether. &#8220;It&#8217;ll look the same, right?&#8221; seems, to them, a reasonable compromise. If waiting for a design language is paralyzing, becoming &#8220;The Ignored&#8221; system is even worse.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*xcbnjVqnlBXvLdSWaf46CA.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*xcbnjVqnlBXvLdSWaf46CA.png 424w, https://cdn-images-1.medium.com/max/1200/1*xcbnjVqnlBXvLdSWaf46CA.png 848w, https://cdn-images-1.medium.com/max/1200/1*xcbnjVqnlBXvLdSWaf46CA.png 1272w, https://cdn-images-1.medium.com/max/1200/1*xcbnjVqnlBXvLdSWaf46CA.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*xcbnjVqnlBXvLdSWaf46CA.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*xcbnjVqnlBXvLdSWaf46CA.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;AVOID conditions where adopters ignore system assets and build redundant system features themselves&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="AVOID conditions where adopters ignore system assets and build redundant system features themselves" title="AVOID conditions where adopters ignore system assets and build redundant system features themselves" srcset="https://cdn-images-1.medium.com/max/1200/1*xcbnjVqnlBXvLdSWaf46CA.png 424w, https://cdn-images-1.medium.com/max/1200/1*xcbnjVqnlBXvLdSWaf46CA.png 848w, https://cdn-images-1.medium.com/max/1200/1*xcbnjVqnlBXvLdSWaf46CA.png 1272w, https://cdn-images-1.medium.com/max/1200/1*xcbnjVqnlBXvLdSWaf46CA.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">AVOID conditions where adopters ignore system assets and build redundant system features themselves</figcaption></figure></div><p>This behavior may seem consistent with the first part of my third principle of my 2017 <a href="https://medium.com/eightshapes-llc/principles-of-designing-systems-294ee45dcf81">Principles of Designing Systems</a>:</p><blockquote><p>Products own their&nbsp;destiny&#8230;</p></blockquote><p>Yet, design systems promise much more than making disparate experiences &#8220;look the same.&#8221; In this moment, the system must educate partners on tradeoffs grounded in system principles. If the adopter ignores the system, outcomes include:</p><ul><li><p><strong>Redundancy</strong> to produce features the system team will also deliver.</p></li><li><p><strong>Inconsistency</strong> with a system when adopter implements an incomplete and often unstable design language the system ends up refining.</p></li><li><p>Poor feature <strong>quality</strong> (such as accessibility) and <strong>completeness</strong> (such as states and variations) when they cut corners. Which adopters will.</p></li><li><p><strong>Inability to upgrade</strong> as the system delivers, fixes and extends features.</p></li></ul><p>You don&#8217;t have come in too heavy handed, like:</p><blockquote><p>&#8220;So, to be clear, you want to be the product building redundant, lower quality, incomplete things inconsistent with the other products? To be fast? Got it.&#8221;</p></blockquote><p>I mean, you could. But you probably shouldn&#8217;t. And you shouldn&#8217;t need to. Instead, this is when I&#8217;d bridge to the second half of that principle:</p><blockquote><p>&#8230;systems equip products to realize that&nbsp;destiny.</p></blockquote><p>Unfortunately, &#8220;The Wait&#8221;&#8202;&#8212;&#8202;the time between the design language being complete and the adopter able to use system assets to achieve their destiny&#8202;&#8212;&#8202;is real, impactful, and largely out of an adopter&#8217;s control.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*Qc5gDH6_MpMw5SqE-9U3Wg.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*Qc5gDH6_MpMw5SqE-9U3Wg.png 424w, https://cdn-images-1.medium.com/max/1200/1*Qc5gDH6_MpMw5SqE-9U3Wg.png 848w, https://cdn-images-1.medium.com/max/1200/1*Qc5gDH6_MpMw5SqE-9U3Wg.png 1272w, https://cdn-images-1.medium.com/max/1200/1*Qc5gDH6_MpMw5SqE-9U3Wg.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*Qc5gDH6_MpMw5SqE-9U3Wg.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*Qc5gDH6_MpMw5SqE-9U3Wg.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*Qc5gDH6_MpMw5SqE-9U3Wg.png 424w, https://cdn-images-1.medium.com/max/1200/1*Qc5gDH6_MpMw5SqE-9U3Wg.png 848w, https://cdn-images-1.medium.com/max/1200/1*Qc5gDH6_MpMw5SqE-9U3Wg.png 1272w, https://cdn-images-1.medium.com/max/1200/1*Qc5gDH6_MpMw5SqE-9U3Wg.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">DO plan rigorously with partners to deliver what they need, when they need it to minimize their&nbsp;wait</figcaption></figure></div><p>Design system planners must minimize &#8220;The Wait&#8221; to best suits interests of that adopter AND the organization overall to:</p><ul><li><p>Order features based on (prioritized) adopter needs.</p></li><li><p>Prioritize minimum viable features, such that upgraded features not needed now can be delivered later but not impact component API.</p></li><li><p>Delivering useful but not yet fully tested features so that adopters to can start implementing and the system can follow with stability and robustness later.</p></li></ul><p><em>Takeaway</em>: Assuaging the fears and tamping the tendencies of impatient adopters is hard. So equip yourself with talking points of system rationale, patience to tread difficult conversations, and peace in the control you <em>don&#8217;t</em> have over the decisions they make. But you can control what you deliver how well by when, so get to work optimizing that with your partners.</p><h4>Challenge 4: Adopters fear migration is too complicated</h4><p>Of course you&#8217;ve planned for roadshows, training materials, playgrounds and automations to help adopters bridge from here to there. Yet, the work ahead may feel daunting to even talented designers and engineers.</p><p>When work looks hard, unfamiliar, complicated or a distraction, that can lead to a &#8220;Rough Start.&#8221; Teams may delay getting going. Once they do get going, their progress seems slow and stunted.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*QTT0WXuj-2BjuHEJmDJ08Q.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*QTT0WXuj-2BjuHEJmDJ08Q.png 424w, https://cdn-images-1.medium.com/max/1200/1*QTT0WXuj-2BjuHEJmDJ08Q.png 848w, https://cdn-images-1.medium.com/max/1200/1*QTT0WXuj-2BjuHEJmDJ08Q.png 1272w, https://cdn-images-1.medium.com/max/1200/1*QTT0WXuj-2BjuHEJmDJ08Q.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*QTT0WXuj-2BjuHEJmDJ08Q.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*QTT0WXuj-2BjuHEJmDJ08Q.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;DON&#8217;T leave adopters in a position where integration starts unnecessarily slowly and in isolation&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="DON&#8217;T leave adopters in a position where integration starts unnecessarily slowly and in isolation" title="DON&#8217;T leave adopters in a position where integration starts unnecessarily slowly and in isolation" srcset="https://cdn-images-1.medium.com/max/1200/1*QTT0WXuj-2BjuHEJmDJ08Q.png 424w, https://cdn-images-1.medium.com/max/1200/1*QTT0WXuj-2BjuHEJmDJ08Q.png 848w, https://cdn-images-1.medium.com/max/1200/1*QTT0WXuj-2BjuHEJmDJ08Q.png 1272w, https://cdn-images-1.medium.com/max/1200/1*QTT0WXuj-2BjuHEJmDJ08Q.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">DON&#8217;T leave adopters in a position where integration starts unnecessarily slowly and in isolation</figcaption></figure></div><p>Would you be willing to help get them started? In vast ecosystems across a big enterprise, the design system team isn&#8217;t responsible for integration work. However, system experts can be well equipped to demonstrate work in context rapidly, such as in the form of &#8220;Kickstarts&#8221; large and small.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*smKSdZ9a2xTna-iKY-quvw.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*smKSdZ9a2xTna-iKY-quvw.png 424w, https://cdn-images-1.medium.com/max/1200/1*smKSdZ9a2xTna-iKY-quvw.png 848w, https://cdn-images-1.medium.com/max/1200/1*smKSdZ9a2xTna-iKY-quvw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*smKSdZ9a2xTna-iKY-quvw.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*smKSdZ9a2xTna-iKY-quvw.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*smKSdZ9a2xTna-iKY-quvw.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;DO kickstart integration efforts by demonstrating-through-doing for them in their environments&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="DO kickstart integration efforts by demonstrating-through-doing for them in their environments" title="DO kickstart integration efforts by demonstrating-through-doing for them in their environments" srcset="https://cdn-images-1.medium.com/max/1200/1*smKSdZ9a2xTna-iKY-quvw.png 424w, https://cdn-images-1.medium.com/max/1200/1*smKSdZ9a2xTna-iKY-quvw.png 848w, https://cdn-images-1.medium.com/max/1200/1*smKSdZ9a2xTna-iKY-quvw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*smKSdZ9a2xTna-iKY-quvw.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">DO kickstart integration efforts by demonstrating-through-doing for them in their environments</figcaption></figure></div><p>Examples of kickstarts include:</p><ul><li><p>A front end system technologist migrating a flagship product from using old variables to new tokens in what becomes a massive pull request full of small edits. <a href="https://www.linkedin.com/in/eddaword/">Ed</a>, you rule!</p></li><li><p>A system Figma-expert branching other team&#8217;s <a href="https://medium.com/p/d2dfbf9d1b8d">shared libraries</a>, converting select components from styles to variables, and using outputs to train those library owners to do the rest. Plus, take learning outcomes back to improve system docs too.</p></li><li><p>A system advocate auditing an existing build&#8202;&#8212;&#8202;whether code or Figma&#8202;&#8212;&#8202;to identify examples of items to upgrade or swap, impacts to API, and tips on how to order the work.</p></li></ul><p>Kickstarts aren&#8217;t for everyone and require available system team capacity, adopter priority, and adopter interest. Plus, let&#8217;s be clear: the kickstart doesn&#8217;t do <em>all </em>the work (well, Ed&#8217;s did, but that&#8217;s because Ed is awesome). Usually, a kickstart can quicken integration in most-impactful places. Benefits go both ways, since the system can learn lessons that lead to improved features and documentation, too.</p><p><em>Takeaway</em>: If willing and able, ask &#8220;How can we help?&#8221; Even if you have to say no to some ideas, conversations can lead to partnerships benefitting both and remove a fog of fear of how new things work.</p><h4>Challenge 5: Adopters coordinating launches, particularly a big&nbsp;bang</h4><p>When working with many adopters, a few things become clear quickly:</p><ol><li><p>Adopters often start integrating at different times.</p></li><li><p>Adopters often launch integrations at different times.</p></li><li><p>Adopters may not coordinate when to launch integrations in concert, but are expected to launch in concert nonetheless.</p></li><li><p>Adopters own their own roadmaps and backlog, it&#8217;s often already full of other priorities, and it&#8217;s up to them to fit the system in.</p></li></ol><p>Typically, the design system doesn&#8217;t own, drive, or is accountable for <em>any</em> of these decisions or outcomes. That&#8217;s up to other stakeholders, leaders, and business units that the system serves.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*nyWUMFxQzoxZKwY-_ZvUgQ.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*nyWUMFxQzoxZKwY-_ZvUgQ.png 424w, https://cdn-images-1.medium.com/max/1200/1*nyWUMFxQzoxZKwY-_ZvUgQ.png 848w, https://cdn-images-1.medium.com/max/1200/1*nyWUMFxQzoxZKwY-_ZvUgQ.png 1272w, https://cdn-images-1.medium.com/max/1200/1*nyWUMFxQzoxZKwY-_ZvUgQ.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*nyWUMFxQzoxZKwY-_ZvUgQ.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*nyWUMFxQzoxZKwY-_ZvUgQ.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;DO stay involved in ongoing planning to support evolving needs across adopters in support of a broader, coordinated launch&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="DO stay involved in ongoing planning to support evolving needs across adopters in support of a broader, coordinated launch" title="DO stay involved in ongoing planning to support evolving needs across adopters in support of a broader, coordinated launch" srcset="https://cdn-images-1.medium.com/max/1200/1*nyWUMFxQzoxZKwY-_ZvUgQ.png 424w, https://cdn-images-1.medium.com/max/1200/1*nyWUMFxQzoxZKwY-_ZvUgQ.png 848w, https://cdn-images-1.medium.com/max/1200/1*nyWUMFxQzoxZKwY-_ZvUgQ.png 1272w, https://cdn-images-1.medium.com/max/1200/1*nyWUMFxQzoxZKwY-_ZvUgQ.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">DO stay involved in ongoing planning to support evolving needs across adopters in support of a broader, coordinated launch</figcaption></figure></div><p>Adopter roadmaps and coordination are out of the design system&#8217;s control, but are certainly within the system team&#8217;s influence. In particular, I would expect that the system team is often best positioned to:</p><ul><li><p>Identify opportunities for and gaps of adopters lacking alignment when the should be (even if the system isn&#8217;t responsible for resolving them).</p></li><li><p>Equip adopters launching in concert with shared needs that serve all of them, such as timely ongoing assets, updates and fixes.</p></li><li><p>Communicate needs emerging from one adopter that are relevant to the rest of them, such as an updated logo, refined token values, or revised standard content (such as footer legal and link content).</p></li></ul><p>Takeaway: You want a seat at the table? Then provide the value through mindful participation, helpful hints, and assertive problem solving when systems can have positive impacts. Just as much, don&#8217;t bear responsibilities you shouldn&#8217;t, such as product managing a coordinated launch across stakeholders you don&#8217;t control.</p><p>In summary, coordinating with many independent, self-interested adopters can be complicated and challenging. Turn those challenges into opportunities by being helpful to redirect and reorient conversations with:</p><ul><li><p>How can breaking down what we deliver help you?</p></li><li><p>How can we integrate with upstream activities to move faster?</p></li><li><p>How can we get you enough so you can get started?</p></li><li><p>How can we help kickstart your efforts?</p></li><li><p>How do your efforts relate to other teams?</p></li></ul><p>All those questions&#8202;&#8212;&#8202;and, hopefully, useful answers and conversations that follow&#8212; demonstrate you are as interested in making them successful as you are in getting your token taxonomy and component API done.</p><p>Next: <strong>#5. Naming a generation</strong></p>]]></content:encoded></item><item><title><![CDATA[Planning a Design System Generation]]></title><description><![CDATA[How to approach a cycle sweeping change across a library]]></description><link>https://nathanacurtis.substack.com/p/planning-a-design-system-generation-ce4120393557</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/planning-a-design-system-generation-ce4120393557</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Sat, 02 Mar 2024 15:46:53 GMT</pubDate><enclosure url="https://cdn-images-1.medium.com/max/2560/1*aFkTtxKcVYkE08XbU43McA.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4>How to approach a cycle sweeping change across a&nbsp;library</h4><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/2560/1*aFkTtxKcVYkE08XbU43McA.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/2560/1*aFkTtxKcVYkE08XbU43McA.png 424w, https://cdn-images-1.medium.com/max/2560/1*aFkTtxKcVYkE08XbU43McA.png 848w, https://cdn-images-1.medium.com/max/2560/1*aFkTtxKcVYkE08XbU43McA.png 1272w, https://cdn-images-1.medium.com/max/2560/1*aFkTtxKcVYkE08XbU43McA.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/2560/1*aFkTtxKcVYkE08XbU43McA.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/2560/1*aFkTtxKcVYkE08XbU43McA.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/2560/1*aFkTtxKcVYkE08XbU43McA.png 424w, https://cdn-images-1.medium.com/max/2560/1*aFkTtxKcVYkE08XbU43McA.png 848w, https://cdn-images-1.medium.com/max/2560/1*aFkTtxKcVYkE08XbU43McA.png 1272w, https://cdn-images-1.medium.com/max/2560/1*aFkTtxKcVYkE08XbU43McA.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p><em>#2 of 5 of the series Design Systems Generations:<br></em><a href="https://medium.com/@nathanacurtis/design-system-generations-65f99960dc3d">Defining</a> | <strong>Planning</strong> | <a href="https://medium.com/eightshapes-llc/adopting-design-system-generations-900535442a16">Adopting</a> | Naming | Retiring</p><p>Changing the entire library is a daunting challenge. It takes months of work. Sometimes, over a year. Updates and refactors ripple across a catalog of complicated, interdependent features. Waves of tasks and reviews wash across disciplines and stakeholders. Brave early adopters crave access to anything as fast as possible to get work done. You burst ahead. Then backtrack and refactor as you learn. The scale of work is immense.</p><p>Design system leaders and managers, don&#8217;t fret. A well-devised plan can guide work across phases, deliver it gradually and communicate clearly at key milestones along the way.</p><p>This post describes a high-level approach to steward a design system&#8217;s library through a significant, generational change. Once demos and planning enable an organization to commit to a <strong>strategy</strong>, work on the <strong>implementation</strong> can progress across phases to deliver the library. Along the way, you can apply <strong>tactics</strong> to assign, group, and order the work. Once complete, <strong>launch</strong> the library while taking the previous generation through <strong>deprecation</strong> and <strong>end-of-life</strong> activities.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*t07BxRG-sRAbr_1bmMgf4Q.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*t07BxRG-sRAbr_1bmMgf4Q.png 424w, https://cdn-images-1.medium.com/max/1200/1*t07BxRG-sRAbr_1bmMgf4Q.png 848w, https://cdn-images-1.medium.com/max/1200/1*t07BxRG-sRAbr_1bmMgf4Q.png 1272w, https://cdn-images-1.medium.com/max/1200/1*t07BxRG-sRAbr_1bmMgf4Q.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*t07BxRG-sRAbr_1bmMgf4Q.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*t07BxRG-sRAbr_1bmMgf4Q.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*t07BxRG-sRAbr_1bmMgf4Q.png 424w, https://cdn-images-1.medium.com/max/1200/1*t07BxRG-sRAbr_1bmMgf4Q.png 848w, https://cdn-images-1.medium.com/max/1200/1*t07BxRG-sRAbr_1bmMgf4Q.png 1272w, https://cdn-images-1.medium.com/max/1200/1*t07BxRG-sRAbr_1bmMgf4Q.png 1456w" sizes="100vw"></picture><div></div></div></a><figcaption class="image-caption">Life cycle of a design system generation, bridged by key milestones</figcaption></figure></div><h3>The Strategy&nbsp;Phase</h3><p>Whether triggered by external needs or system-driven pursuits, a strategic phase can shift from discovery into agreements across concurrent tracks to explore directions, align stakeholders, and plan an implementation.</p><h4>Common activities</h4><ul><li><p><strong>Discovering</strong> needs through gathering requirements, interviewing stakeholders, and auditing existing systems and backlog(s).</p></li><li><p><strong>Exploring</strong> potential future(s), whether evolving a visual language and/or coding proof(s)-of-concepts via technical spikes.</p></li><li><p><strong>Planning</strong> who will make what, how, and by when.</p></li><li><p><strong>Aligning</strong> stakeholders with explorations and plans to generate awareness and foster agreement.</p></li></ul><h4>Defining done</h4><p>A strategy phase is done when all stakeholders align and commit to the plan (the &#8220;Commit&#8221;) to implement what&#8217;s been explored and demo&#8217;ed.</p><p>A strategy phase&#8217;s explorations can cascade into implementation. If the latter starts before the former ends, that&#8217;s fine. The planner&#8217;s focus should be on confident commitments and a clear path forward.</p><h3>The Implementation Phase</h3><p>The implementation phase produces the complete library and always progresses over multiple phases that end with meaningful milestones.</p><p>Over the years, I&#8217;ve settled on progressing through two periods:</p><ul><li><p><strong>Alpha</strong>(s), where a few features (<code>Color</code>, <code>Typography</code>,<code>Icon</code>, <code>Button</code>,&nbsp;&#8230;) evolve sufficiently to demonstrate how features will be built.</p></li><li><p><strong>Beta</strong>(s), where enough features are built at sufficient quality and stability to permit production use by interested and willing adopters.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*feyAgY-p3gk6h597WXuJrQ.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*feyAgY-p3gk6h597WXuJrQ.png 424w, https://cdn-images-1.medium.com/max/1200/1*feyAgY-p3gk6h597WXuJrQ.png 848w, https://cdn-images-1.medium.com/max/1200/1*feyAgY-p3gk6h597WXuJrQ.png 1272w, https://cdn-images-1.medium.com/max/1200/1*feyAgY-p3gk6h597WXuJrQ.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*feyAgY-p3gk6h597WXuJrQ.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*feyAgY-p3gk6h597WXuJrQ.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*feyAgY-p3gk6h597WXuJrQ.png 424w, https://cdn-images-1.medium.com/max/1200/1*feyAgY-p3gk6h597WXuJrQ.png 848w, https://cdn-images-1.medium.com/max/1200/1*feyAgY-p3gk6h597WXuJrQ.png 1272w, https://cdn-images-1.medium.com/max/1200/1*feyAgY-p3gk6h597WXuJrQ.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Separating an implementation phase into two main periods: Alpha and&nbsp;Beta</figcaption></figure></div><h4>Common activities</h4><ul><li><p>Regular progress demos, particularly influential community members.</p></li><li><p>Regular status meetings to monitor doneness of features and outputs</p></li><li><p>Per-milestone <a href="https://medium.com/eightshapes-llc/design-system-communications-ca679ffc36d3">communications</a> to show progress, generate excitement</p></li><li><p>Pilots and testing cycles to validate approach, changes and migration</p></li><li><p>Revisiting and refactoring completed portions based on what you learn</p></li><li><p>Pre-launch teaser and expectation-setting communications</p></li></ul><h4>Defining done</h4><p>The library &#8220;goes beta&#8221; when enough components are available at sufficient, production level quality that early adopters can use them with confidence. Implementation overall is complete when the library exits beta and launches as generally available.</p><h3>Implementation Tactics</h3><h4>Augment main milestones with incremental delivery</h4><p>The larger the scale of work, the longer it takes. As a result, break work down into milestones to communicate at key moments and incrementally deliver otherwise.</p><p>In recent years, the simplest &#8220;redesign&#8221; implementation I&#8217;ve led included an alpha release followed by three betas, roughly by month, before launch.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*MolMCeUDxLaBELoyVKkTqQ.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*MolMCeUDxLaBELoyVKkTqQ.png 424w, https://cdn-images-1.medium.com/max/1200/1*MolMCeUDxLaBELoyVKkTqQ.png 848w, https://cdn-images-1.medium.com/max/1200/1*MolMCeUDxLaBELoyVKkTqQ.png 1272w, https://cdn-images-1.medium.com/max/1200/1*MolMCeUDxLaBELoyVKkTqQ.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*MolMCeUDxLaBELoyVKkTqQ.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*MolMCeUDxLaBELoyVKkTqQ.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*MolMCeUDxLaBELoyVKkTqQ.png 424w, https://cdn-images-1.medium.com/max/1200/1*MolMCeUDxLaBELoyVKkTqQ.png 848w, https://cdn-images-1.medium.com/max/1200/1*MolMCeUDxLaBELoyVKkTqQ.png 1272w, https://cdn-images-1.medium.com/max/1200/1*MolMCeUDxLaBELoyVKkTqQ.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Further breaking Alpha or Beta periods into incremental deliveries of more and more features.</figcaption></figure></div><p>More often, a &#8220;redesign&#8221; cycle lasts nine to twelve months to deliver, with more alpha and beta moments to incrementally deliver the work.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*HsXEjJ_Lx4I7u7HxLunqHw.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*HsXEjJ_Lx4I7u7HxLunqHw.png 424w, https://cdn-images-1.medium.com/max/1200/1*HsXEjJ_Lx4I7u7HxLunqHw.png 848w, https://cdn-images-1.medium.com/max/1200/1*HsXEjJ_Lx4I7u7HxLunqHw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*HsXEjJ_Lx4I7u7HxLunqHw.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*HsXEjJ_Lx4I7u7HxLunqHw.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*HsXEjJ_Lx4I7u7HxLunqHw.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*HsXEjJ_Lx4I7u7HxLunqHw.png 424w, https://cdn-images-1.medium.com/max/1200/1*HsXEjJ_Lx4I7u7HxLunqHw.png 848w, https://cdn-images-1.medium.com/max/1200/1*HsXEjJ_Lx4I7u7HxLunqHw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*HsXEjJ_Lx4I7u7HxLunqHw.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Longer implementation cycle with more Alpha and Beta phase milestones</figcaption></figure></div><p>Consider important moments across milestones. For example, one output (such as a documentation site) could emerge visible to all adopters for the first time later than other outputs (such as a published Figma library and Storybook docs).</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*V8w6vZWu_z95l3h3FK9mNw.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*V8w6vZWu_z95l3h3FK9mNw.png 424w, https://cdn-images-1.medium.com/max/1200/1*V8w6vZWu_z95l3h3FK9mNw.png 848w, https://cdn-images-1.medium.com/max/1200/1*V8w6vZWu_z95l3h3FK9mNw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*V8w6vZWu_z95l3h3FK9mNw.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*V8w6vZWu_z95l3h3FK9mNw.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*V8w6vZWu_z95l3h3FK9mNw.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*V8w6vZWu_z95l3h3FK9mNw.png 424w, https://cdn-images-1.medium.com/max/1200/1*V8w6vZWu_z95l3h3FK9mNw.png 848w, https://cdn-images-1.medium.com/max/1200/1*V8w6vZWu_z95l3h3FK9mNw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*V8w6vZWu_z95l3h3FK9mNw.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Distinguishing moments when major outputs (Storybook, Figma Library, Doc Site) first become available to early&nbsp;adopters</figcaption></figure></div><h4>Use dependencies to order the&nbsp;work</h4><p>A complete generation of a library can include anywhere from 10 or 15 to upwards of 100+ components. How do you decide how to sequence the work? Certainly, you don&#8217;t start at A and end at Z.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*J4bpsi-rDyZ4WkK0P5CB1A.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*J4bpsi-rDyZ4WkK0P5CB1A.png 424w, https://cdn-images-1.medium.com/max/1200/1*J4bpsi-rDyZ4WkK0P5CB1A.png 848w, https://cdn-images-1.medium.com/max/1200/1*J4bpsi-rDyZ4WkK0P5CB1A.png 1272w, https://cdn-images-1.medium.com/max/1200/1*J4bpsi-rDyZ4WkK0P5CB1A.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*J4bpsi-rDyZ4WkK0P5CB1A.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*J4bpsi-rDyZ4WkK0P5CB1A.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*J4bpsi-rDyZ4WkK0P5CB1A.png 424w, https://cdn-images-1.medium.com/max/1200/1*J4bpsi-rDyZ4WkK0P5CB1A.png 848w, https://cdn-images-1.medium.com/max/1200/1*J4bpsi-rDyZ4WkK0P5CB1A.png 1272w, https://cdn-images-1.medium.com/max/1200/1*J4bpsi-rDyZ4WkK0P5CB1A.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Library features, ordered alphabetically prior to more intentional sequencing and&nbsp;grouping</figcaption></figure></div><p>In general, a component library is made or remade from small to large. It&#8217;s difficult to consider larger things complete if the smaller things they depend on are incomplete. Therefore, mapping the tree of a library&#8217;s <a href="https://medium.com/eightshapes-llc/dealing-with-dependencies-inside-design-systems-aa6ce2cf7bc3">dependencies</a> directly informs how you order the work.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*J4YfeRmIrRWBacW0FwTlKw.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*J4YfeRmIrRWBacW0FwTlKw.png 424w, https://cdn-images-1.medium.com/max/1200/1*J4YfeRmIrRWBacW0FwTlKw.png 848w, https://cdn-images-1.medium.com/max/1200/1*J4YfeRmIrRWBacW0FwTlKw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*J4YfeRmIrRWBacW0FwTlKw.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*J4YfeRmIrRWBacW0FwTlKw.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*J4YfeRmIrRWBacW0FwTlKw.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*J4YfeRmIrRWBacW0FwTlKw.png 424w, https://cdn-images-1.medium.com/max/1200/1*J4YfeRmIrRWBacW0FwTlKw.png 848w, https://cdn-images-1.medium.com/max/1200/1*J4YfeRmIrRWBacW0FwTlKw.png 1272w, https://cdn-images-1.medium.com/max/1200/1*J4YfeRmIrRWBacW0FwTlKw.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Library features, arranged as a dependency tree</figcaption></figure></div><p>Simple components like <code>Breadcrumb</code> and <code>Tabs</code> have no dependencies. You can do those whenever. <code>List Group</code>&nbsp;? That&#8217;s another story. It depends on <code>Checkbox</code> (if you have checkable items), which depends on <code>Form label</code> which depends on <code>Tooltip</code> (in a few systems I work on) which depends on <code>Icon</code>. Many paths trace back to <code>Icon</code>, so tackle that in the first batch.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*9DFvtwg04dP4barIt4VakQ.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*9DFvtwg04dP4barIt4VakQ.png 424w, https://cdn-images-1.medium.com/max/1200/1*9DFvtwg04dP4barIt4VakQ.png 848w, https://cdn-images-1.medium.com/max/1200/1*9DFvtwg04dP4barIt4VakQ.png 1272w, https://cdn-images-1.medium.com/max/1200/1*9DFvtwg04dP4barIt4VakQ.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*9DFvtwg04dP4barIt4VakQ.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*9DFvtwg04dP4barIt4VakQ.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*9DFvtwg04dP4barIt4VakQ.png 424w, https://cdn-images-1.medium.com/max/1200/1*9DFvtwg04dP4barIt4VakQ.png 848w, https://cdn-images-1.medium.com/max/1200/1*9DFvtwg04dP4barIt4VakQ.png 1272w, https://cdn-images-1.medium.com/max/1200/1*9DFvtwg04dP4barIt4VakQ.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Increasingly complicated dependency tree</figcaption></figure></div><p>Large libraries, particularly those with <a href="https://medium.com/eightshapes-llc/subcomponents-753ce9f6600a">subcomponents</a>, result in dependency tree maps that are complicated, difficult to create and annoying to maintain. Therefore, treat it less formally. Until you automate such diagrams, avoid perfecting and maintaining it. Instead, capture these relationships into a tool better equipped for it, like a spreadsheet or task management tool like Jira or Asana.</p><h4>Group and assign based on dependencies and shared attributes</h4><p>Don&#8217;t let the tree diagram deceive you. Arrange features and groups to respect dependencies while prioritizing and grouping effectively. For example, <code>Button</code> is needed early, resolving <code>Text input</code> opens the door to finish other form components, and <code>Breadcrumbs</code> are both isolated in layouts and a low priority. Order batches accordingly.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*UYWKSXVsjJ4NDK7gbIrdbg.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*UYWKSXVsjJ4NDK7gbIrdbg.png 424w, https://cdn-images-1.medium.com/max/1200/1*UYWKSXVsjJ4NDK7gbIrdbg.png 848w, https://cdn-images-1.medium.com/max/1200/1*UYWKSXVsjJ4NDK7gbIrdbg.png 1272w, https://cdn-images-1.medium.com/max/1200/1*UYWKSXVsjJ4NDK7gbIrdbg.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*UYWKSXVsjJ4NDK7gbIrdbg.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*UYWKSXVsjJ4NDK7gbIrdbg.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*UYWKSXVsjJ4NDK7gbIrdbg.png 424w, https://cdn-images-1.medium.com/max/1200/1*UYWKSXVsjJ4NDK7gbIrdbg.png 848w, https://cdn-images-1.medium.com/max/1200/1*UYWKSXVsjJ4NDK7gbIrdbg.png 1272w, https://cdn-images-1.medium.com/max/1200/1*UYWKSXVsjJ4NDK7gbIrdbg.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Features organized by batches, often aligned with&nbsp;releases</figcaption></figure></div><p>However, features are made by people. Distribute and assign across staff while respect dependencies, grouping components with similar attributes and aligning assignments with their interests.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*dpN565lmkS1VRvO1BeaiCA.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*dpN565lmkS1VRvO1BeaiCA.png 424w, https://cdn-images-1.medium.com/max/1200/1*dpN565lmkS1VRvO1BeaiCA.png 848w, https://cdn-images-1.medium.com/max/1200/1*dpN565lmkS1VRvO1BeaiCA.png 1272w, https://cdn-images-1.medium.com/max/1200/1*dpN565lmkS1VRvO1BeaiCA.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*dpN565lmkS1VRvO1BeaiCA.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*dpN565lmkS1VRvO1BeaiCA.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*dpN565lmkS1VRvO1BeaiCA.png 424w, https://cdn-images-1.medium.com/max/1200/1*dpN565lmkS1VRvO1BeaiCA.png 848w, https://cdn-images-1.medium.com/max/1200/1*dpN565lmkS1VRvO1BeaiCA.png 1272w, https://cdn-images-1.medium.com/max/1200/1*dpN565lmkS1VRvO1BeaiCA.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Batched features assigned to distinct designers</figcaption></figure></div><p>In the revised example, designer 1 is clearly the &#8220;forms designer.&#8221; Early yet complicated considerations on <code>Tooltip</code> give way to doing <code>Label</code> and <code>Error</code> to deliver <code>Text input</code> and finishing batches of &#8220;selectables&#8221; (<code>Checkbox</code>, <code>Radio button</code> and <code>Toggle</code>) and other stuff.</p><p>Designer 2 focuses on <code>Icon</code> and <code>Button</code>, throws in &#8220;easy&#8221; components like <code>List unordered</code> and <code>Breadcrumb</code> along the way, and is responsible to deliver what can be a behemoth <code>List group</code> later. Notice the limited number dependency connectors between assignees, minimizing the risk of one blocking the other.</p><p>Feature assignments are now roughly equally distributed by effort, clearly divide work across teammates, and respect the flow of dependencies. Assuming both deliver as expected, that is &#128521;.</p><h4>Increase feature quality, quantity and stability at different rates</h4><p>As implementing a full generation of a design system progresses, component quantity, quality and stability increase across phases differently.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*pJiUjsAK1AmGBddlYsl9xg.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*pJiUjsAK1AmGBddlYsl9xg.png 424w, https://cdn-images-1.medium.com/max/1200/1*pJiUjsAK1AmGBddlYsl9xg.png 848w, https://cdn-images-1.medium.com/max/1200/1*pJiUjsAK1AmGBddlYsl9xg.png 1272w, https://cdn-images-1.medium.com/max/1200/1*pJiUjsAK1AmGBddlYsl9xg.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*pJiUjsAK1AmGBddlYsl9xg.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*pJiUjsAK1AmGBddlYsl9xg.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*pJiUjsAK1AmGBddlYsl9xg.png 424w, https://cdn-images-1.medium.com/max/1200/1*pJiUjsAK1AmGBddlYsl9xg.png 848w, https://cdn-images-1.medium.com/max/1200/1*pJiUjsAK1AmGBddlYsl9xg.png 1272w, https://cdn-images-1.medium.com/max/1200/1*pJiUjsAK1AmGBddlYsl9xg.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Quality, stability and quantity increasing across&nbsp;phases</figcaption></figure></div><p>Such enable you to frame the alpha, beta and GA moments of a cycle:</p><blockquote><p>The alpha release includes a <strong>few</strong> <strong>unstable</strong> features that, while of <strong>unproven quality</strong>, sufficiently demonstrate how things work.</p></blockquote><blockquote><p>The first beta release includes <strong>many</strong> increasingly <strong>stable</strong> features built at <strong>sufficient quality</strong> for production use.</p></blockquote><blockquote><p>The &#8220;GA&#8221; release includes <strong>every</strong> feature, completely <strong>stable</strong> at highest <strong>quality</strong>.</p></blockquote><p>Feature <strong>quality </strong>starts high and stays high. System practitioners tend to consider architectural precision, usability, accessibility, performance and within library consistency as nonnegotiable. I love that about them. Yet, defects occur. Missed details need correcting. Perfection can become the enemy of progress. Quality compromises matter less for an alpha, but they will impact adopters delivering production work. So set expectations that quality need not be perfect early on, and that OK. Instead, focus on a vital inflection point: beta. Once the library is available for beta, early adopters must trust quality is good enough for production work.</p><p>The <strong>quantity </strong>of completed features resembles an &#8220;S curve&#8221; over time, accelerating gradually before flattening as launch approaches. An alpha need only include a few components. Then, the team churns out more and more, faster and faster. However, as launch approaches, perceived production can slow because:</p><ul><li><p>Focus shifts from making things to testing and documenting things</p></li><li><p>Later components can be larger and more complicated</p></li><li><p>Feedback necessitates revisiting things already considered complete</p></li></ul><p>Each feature visual and API <strong>stability </strong>increases over the course of implementation. Yet, reversals happen. As you make more, expect to revisit things already presumed done based on what you learn. A commitment to a stable API need only be ironclad by launch. Some choices, like a component&#8217;s name should be stable as it&#8217;s introduced. On the other hand, property API, layout and visual detailing should be allowed to shift. During the cycle, a system team needs space to zoom out, compare and evaluate patterns and normalize them across features.</p><p>Each organization will define their own definition for how complete, stable and good a system is in each phase. Regardless, by the time you&#8217;re done, adopters need a generation that&#8217;s complete, stable and well made.</p><h4>Report on work using a doneness&nbsp;matrix</h4><p>Once work is scoped, planned and underway, the most concrete single visual I&#8217;ve used to summarize progress is a <a href="https://medium.com/@nathanacurtis/doneness-matrices-c7f0a026365f">doneness matrix</a>. The primary structure is <a href="https://medium.com/eightshapes-llc/design-system-subtasks-by-step-2f43d7d4bce0">top level tasks and/or outputs</a> as columns, features as rows grouped by type (Foundations, Components, Patterns) and ordered by release milestones (Alpha, Beta 1, Beta 2&#8230;).</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/1200/1*7vtS2m_WHZ1wIoHdpbASSQ.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/1200/1*7vtS2m_WHZ1wIoHdpbASSQ.png 424w, https://cdn-images-1.medium.com/max/1200/1*7vtS2m_WHZ1wIoHdpbASSQ.png 848w, https://cdn-images-1.medium.com/max/1200/1*7vtS2m_WHZ1wIoHdpbASSQ.png 1272w, https://cdn-images-1.medium.com/max/1200/1*7vtS2m_WHZ1wIoHdpbASSQ.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/1200/1*7vtS2m_WHZ1wIoHdpbASSQ.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/1200/1*7vtS2m_WHZ1wIoHdpbASSQ.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/1200/1*7vtS2m_WHZ1wIoHdpbASSQ.png 424w, https://cdn-images-1.medium.com/max/1200/1*7vtS2m_WHZ1wIoHdpbASSQ.png 848w, https://cdn-images-1.medium.com/max/1200/1*7vtS2m_WHZ1wIoHdpbASSQ.png 1272w, https://cdn-images-1.medium.com/max/1200/1*7vtS2m_WHZ1wIoHdpbASSQ.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Abstract depiction of a doneness&nbsp;matrix</figcaption></figure></div><p>Unfortunately, it&#8217;s difficult automate producing this matrix in task management tools like Jira or Asana (although creating custom fields as columns in a release board can go a long way). Otherwise, it becomes a manual process to update a table maintained in Figma, Confluence or a presentation slide.</p><h3>Launch and General availability (&#8220;GA&#8221;)</h3><p>The formal launch. This &#8220;It&#8217;s done and ready for everyone!&#8221; moment is reinforced by heavy communications and can be followed by a brief if intense &#8220;warranty&#8221; period. Don&#8217;t dismiss how much adopters expect a system team to train them, help solve problems, and fix things.</p><h4>Common activities</h4><ul><li><p>Launch email, Slack and other notifications</p></li><li><p>Live demos tailored to broad and diverse audiences</p></li><li><p>Celebration(s) with parties for the system team and friends</p></li><li><p>Training deep dives focused on migration and new capabilities</p></li><li><p>Shifting system team capacity temporarily to favor <em>more </em>of support and consulting over <em>less</em> of<em> </em>&#8220;delivering the next component(s)&#8221;</p></li><li><p>Taking a breath, calming the nerves, and letting the team recharge as plans for the next things shape up.</p></li></ul><h4>Defining done</h4><p>A launch period ends when design system practices settle back into &#8220;business as usual&#8221; (BAU). Incremental work enhances what&#8217;s there, offers new things, and breaks smaller things slowly as needs require.</p><p>But, for most, periods of smaller, incremental change doesn&#8217;t last forever. Another generation shows up on the horizon, and&#8230;</p><p>Periods of generational change are the biggest, most momentous moments in the life of a design system. By planning and communicating how you&#8217;ll progress across phases of strategy, implementation and ultimately end-of-life, you set expectations and enable your partners to plan accordingly. Best to you and your team as you prepare for that next, big moment!</p><p>Next: <strong>#3. Naming a generation</strong></p>]]></content:encoded></item><item><title><![CDATA[Design System Generations]]></title><description><![CDATA[How to discuss and describe a design system&#8217;s biggest changes]]></description><link>https://nathanacurtis.substack.com/p/design-system-generations-65f99960dc3d</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/design-system-generations-65f99960dc3d</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Fri, 01 Mar 2024 12:45:51 GMT</pubDate><enclosure url="https://cdn-images-1.medium.com/max/2560/1*eKZf3gWUUWjyyN4yxm4-8w.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4>How to discuss and describe a design system&#8217;s biggest&nbsp;changes</h4><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/2560/1*eKZf3gWUUWjyyN4yxm4-8w.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/2560/1*eKZf3gWUUWjyyN4yxm4-8w.png 424w, https://cdn-images-1.medium.com/max/2560/1*eKZf3gWUUWjyyN4yxm4-8w.png 848w, https://cdn-images-1.medium.com/max/2560/1*eKZf3gWUUWjyyN4yxm4-8w.png 1272w, https://cdn-images-1.medium.com/max/2560/1*eKZf3gWUUWjyyN4yxm4-8w.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/2560/1*eKZf3gWUUWjyyN4yxm4-8w.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/2560/1*eKZf3gWUUWjyyN4yxm4-8w.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/2560/1*eKZf3gWUUWjyyN4yxm4-8w.png 424w, https://cdn-images-1.medium.com/max/2560/1*eKZf3gWUUWjyyN4yxm4-8w.png 848w, https://cdn-images-1.medium.com/max/2560/1*eKZf3gWUUWjyyN4yxm4-8w.png 1272w, https://cdn-images-1.medium.com/max/2560/1*eKZf3gWUUWjyyN4yxm4-8w.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p><em>#1 of 5 of the series Design Systems Generations:<br></em><strong>Defining</strong> | <a href="https://medium.com/@nathanacurtis/planning-a-design-system-generation-ce4120393557">Planning</a> | <a href="https://medium.com/eightshapes-llc/adopting-design-system-generations-900535442a16">Adopting</a> | Naming | Retiring</p><p>You&#8217;ve made a library. Users adopted the library. The design system has settled into an operational rhythm. Days, weeks, and months go by as your design system kicks out new features, smooths rough edges, and help teams along. Then, the whispers. Something is afoot. Is that a VP working concepts with an agency? Is IT grumbling about frameworks? Something...</p><p>Bang! &#8220;It&#8217;s redesign time!&#8221; &#8220;Our visual foundation is stale!&#8221; &#8220;We&#8217;re shifting platforms!&#8221; &#8220;We&#8217;re switching from {this} to {that}!&#8221; Just like that, it&#8217;s time for the next generation of your design system. The entire library is in play to be made, delivered, and implemented (again) across adopters that upgrade immediately, sooner or later.</p><h3>What is a generation, anyway?</h3><p>I&#8217;ve been using the term design system <em><strong>generation</strong></em> for years, although it&#8217;s not a term used evenly and regularly across our community:</p><blockquote><p><strong>Design system generation</strong>: a stable and sufficient core library of assets, docs, tools and practices delivered for use by designers (in Figma?) and/or developers (React?, iOS?, Android?,&nbsp;&#8230;).</p></blockquote><p>A new generation generally means:</p><ol><li><p>The entire library&#8217;s features&#8202;&#8212;&#8202;&#8220;All the things&#8221;&#8202;&#8212;&#8202;can be impacted.</p></li><li><p>Upgrading requires attention yet <em>may or may not</em> be effortful, depending on the scale of <a href="https://medium.com/p/1e9109fac9c4">breaking change</a>, tooling and <a href="https://en.wikipedia.org/wiki/Regression_testing">regression</a> required.</p></li><li><p>Changes require aligning with partners like brand and/or architecture.</p></li><li><p>Because things are breaking, it&#8217;s time to revisit a backlog to do things a system couldn&#8217;t do before so as to not break things.</p></li><li><p>Other system work slows or stops, crowded out by the focus on updating &#8220;all the things&#8221; and enabling adoption.</p></li></ol><p>Delivering a new generation is the largest, most complicated cycle a design system goes through. The system and its adopters may live with the outcome for years. Therefore, everyone must understand what it is, why it&#8217;s happening, and the scale of the effort and reward. This introductory post explores the big questions that define a generation:</p><ul><li><p><strong>Cause: </strong>Why are we changing?</p></li><li><p><strong>Scope: </strong>What is changing?</p></li><li><p><strong>Scale: </strong>How expensive is the change? How big is the impact?</p></li></ul><p>Equipped with high-level answers, you can orient your team, set expectations across an organization and start planning.</p><h3>Cause: Why are we changing?</h3><p>A design system&#8217;s next generation can arise from one of many triggers, including a system&#8217;s need to:</p><ul><li><p><strong>Start</strong> from scratch as a &#8220;first generation,&#8221; because no library exists.</p></li><li><p><strong>Redesign </strong>features like foundations and components, such as a <strong>rebrand</strong>.</p></li><li><p><strong>Rearchitect</strong> features like tokens and component API extensively to support new capabilities, evolve with tools, or right all the old wrongs.</p></li><li><p><strong>Switch framework</strong> like going from Angular to React or Sketch to Figma, or possibly <strong>framework version</strong>, such as React 16 to 17.</p></li></ul><p>Not every library-wide change is a &#8220;next generation,&#8221; however. Improving accessibility or adding component density and sizing controls across a catalog are considerable improvements.</p><p>Sometimes, the term <em>generation</em> doesn&#8217;t apply: a framework version update or a partial foundation overhaul also may not qualify. The characteristics of a rollout are the same, but at a far lower scale. Such library-wide fixes and enhancements are certainly worth communicating but fall short of the fanfare of a &#8220;next generation.&#8221;</p><h4>Who&#8217;s driving change: external forces or the design system&nbsp;itself?</h4><p>Sometimes change is triggered from a system team, other times the change is thrust upon a design system. Both types of triggers&#8202;&#8212;&#8202;external and internal&#8202;&#8212;&#8202;come with tradeoffs.</p><p>Brand updating a visual identity and IT norming on a &#8220;north star architecture&#8221; are examples of <strong>externally driven</strong> generational change. In these cases, a design system has no choice but to &#8220;hitch to the wagon&#8221; (credit: <a href="https://www.linkedin.com/in/alexskougarevskaya/">Alex Skougarevskaya</a>, one-time <a href="https://atlassian.design/">Atlassian Design System</a> design lead) to enable the outcome.</p><p>External forces make things complicated: executives decree timelines, other groups create plans, stakeholders unpredictably communicate. Amid the chaos, a design system can struggle for control. System aspirations can be lost in the din. Therefore, it&#8217;s critical to take a &#8220;seat at the table&#8221; to influence emerging design and the system&#8217;s role in implementation.</p><p>Communicating priority of generational change to adopters is easy when externally driven: they&#8217;ve heard about it, can&#8217;t object to it, and may already be planning for it. However, that pressure is double-edged: adopters may be unwilling to wait. A design system&#8217;s work translates and encodes a design language into reusable bits. That takes time. Communicating long term values&#8202;&#8212;&#8202;efficiency, quality, consistency&#8202;&#8212;&#8202;of that translation is essential to avoid adopters rushing to hardcode answers themselves.</p><p>On the other hand, generational change can be <strong>internally driven</strong> by the system team without external pressures. Stale visual language, outdated architecture, or unachievable new capabilities all drive change. There may be no broader wagon to hitch to, but why wait? There&#8217;s no reason a system team can&#8217;t rollout big changes themselves.</p><p>Adopters are less likely to request generational change, and can resist it once cognizant of the effort required to upgrade. When internally driven, system-led activities require more attention communicate scope (&#8220;What you get!&#8221;), process (&#8220;How to get it!&#8221;), and benefits (&#8220;Why it matters!&#8221;). For example, the design system may target advocates across design and development communities to present explorations, agree on API, and support pilots. Without a galvanizing external force, it&#8217;s the up to the system to form groups, drive consensus, and communicate outcomes.</p><p><em>Takeaway</em>: Ensure you&#8212;and your team&#8202;&#8212;&#8202;know who&#8217;s driving the change in order to orient what role to play, what posture to take, how flexible to be with your time and how assertive to be when driving decisions.</p><h3>Scope: What is changing?</h3><p>Generational change opens minds. Moments that sweep change can lead teams to (re)consider everything they&#8217;ve ever wanted to do. It&#8217;s all on the table: new features, platforms, tools and ways of working.</p><h4>Foundations and components&nbsp;&#8230; and other&nbsp;stuff?</h4><p>Usually, adopters expect a new design system generation to refresh visual foundations (implemented as a token taxonomy) and UI components across the catalog. These updates can cascade to UX patterns, page layouts and templates. Less certain is the overlap of design and content, where a new generation may or may not impact content standards and practices.</p><blockquote><p>This generation will update <strong>all components</strong> with a refreshed take on <strong>color</strong> and <strong>typography</strong> that means a new <strong>design token</strong> taxonomy. We expect minimal impacts to <strong>space</strong> and <strong>size</strong>, although <strong>shape</strong> is in play. Existing standards for <strong>accessibility</strong> and <strong>content</strong> (like <strong>voice and tone</strong>) aren&#8217;t expected to change.</p></blockquote><p>To describe feature scope, use visible models that customers are familiar with. For example, sections and oft-used pages of a documentation site provide a foundation to succinctly describe change.</p><p><em>Takeaways</em>: Establish boundaries of what is in and out, balance aspiration with time, resources and customer needs and take opportunities to expand the portfolio</p><h4>Design assets or code packages or&nbsp;both?</h4><p>Most generational moments synchronize change across design assets (like a Figma library) and code (like React, Angular, iOS and Android).</p><p>However, sometimes a generation can be output and discipline specific. For example, imagine shifting a Figma library from using props to variable/modes to enable color theming. Designers have a whole new model for fundamentals, yet code isn&#8217;t impacted. Alternatively, a system may update a React-based code library to support only React 17 and above. Developers must make careful updates, yet designers have no work to do.</p><p>In both cases, the work carried all the hallmarks of a generation: touch &#8220;all the things,&#8221; break and deprecate some things, slow the BAU work, and communicate heavily to system customers. Ironically, in this story, those events occurred at the <em>same</em> time in the <em>same</em> design system. The only overlap of this big moment was to balance program-level communications when they released simultaneously.</p><p><em>Takeaway</em>: Generational change need not impact both design <em>and</em> code, libraries <em>and</em> docs all at the same time. Sometimes, it&#8217;s narrower to only one library or one type of output, and that&#8217;s ok. Just make sure each audience gets the message(s) they need.</p><h4>Just docs content, or the publishing platform&nbsp;too?</h4><p>When features change, so does documentation. The scale of copy, images and examples updates can feel like an approaching slog, but a familiar and predictable slog. Adopters, too, expect the system to update feature documentation. On the other hand, adopters fear is their ability to consume the changes cleanly.</p><p>So get past the conversations about &#8220;What are we doing with Foundations and Components content?&#8221; Get to the richer topic of how you&#8217;ll prepare adopters to change through documentation. Upgrades must feel straightforward, easy and risk free. <strong>Getting started</strong>, procedural <strong>migration guides</strong>, self guided <strong>training</strong> materials and <strong>demo and playgrounds</strong> can carry big payoffs. Done right, they also require meticulous attention and iteration to smooth out rough edges. As you set expectations about your big changes, it&#8217;s essential to think through and communicate all you&#8217;ll do to enable their changes too.</p><p>A generational moment also zooms a team out out to challenge platform assumptions, too. Beyond new <em>content</em>, does documentation need&#8230;</p><ul><li><p>&#8230;a site design refreshed to match the new visual foundation?</p></li><li><p>&#8230;an overhaul to how to author, manage and publish content?</p></li><li><p>&#8230;to migrate to or from a platform like ZeroHeight, Storybook,&nbsp;&#8230; or both?</p></li></ul><p>Any of those transitions will be a major project within a major project (delivering a generation), warranting considerable strategy, planning and communication. Must you pursue any of them to deliver a new generation? Often, no. Should you consider pursuing some of them? Usually, absolutely. Bottom line: generational change usually impacts both and work typically exceeds a simple, fresh coat of paint on an existing site.</p><p><em>Takeaway</em>: Use generational moments to challenge both <em>what</em> and <em>how </em>you publish docs of both <em>what</em> to use and <em>how</em> to change.</p><h4>Tools and practices</h4><p>Generational change in a library may be coupled with&#8212; or even require&#8202;&#8212;&#8202;changes to how a system approaches:</p><ul><li><p><strong>Testing</strong> practices, such as <a href="https://medium.com/p/a47fc978465f">Figma component testing</a>, automated visual regression, unit testing and how you integrate accessibility</p></li><li><p><strong>Releasing</strong> pipelines and practices, such as new places and locations to publish assets or stewarding users through alphas and betas</p></li><li><p><strong>Ways-of-working</strong> for system makers and adopters and tooling in which they collaborate (such as Jira or Asana)</p></li><li><p><strong>Communications</strong> throughout implementation and past launch (including email distribution lists and platforms)</p></li></ul><p>Such changes also present as projects within a bigger project. They can be disruptive, unfamiliar, and risk consuming considerable time (such as when licensing third party tools or getting security approvals).</p><p><em>Takeaway</em>: Think upfront about potential new tools and practices rather than organically realize them as you go. Set aside session(s) for the team to explore implications and ambitions that change how the system works.</p><h3>Scale: How big is the&nbsp;change?</h3><p>When characterizing change, focus how the change matters to adopters:</p><ul><li><p>What&#8217;s <strong>impact</strong> of what I get?</p></li><li><p>How much will it <strong>cost</strong> to upgrade?</p></li></ul><h4>When upgrading is hard, focus on core and long-term values</h4><p>Generational terms like &#8220;redesign&#8221; and &#8220;refactor&#8221; trigger costs and fears of major changes. Whether a visual overhaul, transition to Figma, or a wholly rebuilt React library, impact may be massive but the switching cost can feel daunting, even paralyzing.</p><p>If you are hitching to a wagon carrying the whole organization, teams tend to bow to efforts that seem non-negotiable. There, the system has an opportunity to be perceived as a solution enabling, not albatross preventing, of realizing of that value. When the trigger is internal, the system must communicate how the generation makes an adopter&#8217;s present even better and/or describes a now-possible future that previously felt impossible. Let the slidemaking commence.</p><h4>If upgrading can be easy, make it so and say&nbsp;so</h4><p>Other times, impacts can be positive and catalog wide, but change costs are limited. At Morningstar, I led the delivery of a second major generation in 2018 refactored all components to <a href="https://medium.com/eightshapes-llc/size-in-design-systems-64f234aec519">synthesize sizing and support varying densities</a>. Sure, every component technically had a breaking change. All the version numbers bumped to a next major version. But developers could integrate updates mostly using search and replace with little fuss.</p><p>More recently, I led a team to refactor the Figma library from color styles to variables to ease setting light and dark themes. Fill and stroke color attributes changed across the catalog. Over half of the component assets (including all with a <code>surface</code> property set to <code>dark</code>) were deprecated. Yet, upgrades were trivial (click &#8220;Update&#8221;), broke nothing in existing files, changed nothing visually, and made finding and swapping deprecated versions a breeze. Developers, apart from interpreting files differently during handoff, were not impacted.</p><p>Was the variables switch a next generation? Depends on how you want to apply the term. For tools? Definitely. It reinvented how to apply and use fundamentals, setting a new baseline to grow from. For fundamentals features like core colors and typography? No, those didn&#8217;t change.</p><p>In both cases sizing/density and variables, communications focused on what adopters got and how <em>not</em> hard and <em>not </em>risky it was to change.</p><p><em>Takeaway</em>: Adopters will compare what&#8217;s in it for them with how hard change will be. Relating the value a system enables to the costs it incurs is something you must do succinctly, clearly and honestly.</p><p>From the outset, clarifying what will change (scope), why it&#8217;ll change (cause), and how big a change it&#8217;ll be (scale) is essential. Once those broad strokes are defined, it&#8217;s time to dig into how the system will align everyone to a vision and strategy, get the work done, and launch for adopters to use.</p><p>Next: <strong>#2. <a href="https://medium.com/@nathanacurtis/planning-a-design-system-generation-ce4120393557">Planning a generation</a></strong></p>]]></content:encoded></item><item><title><![CDATA[Component Specifications]]></title><description><![CDATA[What to include, where it goes, and why it matters more now]]></description><link>https://nathanacurtis.substack.com/p/component-specifications-1492ca4c94c</link><guid isPermaLink="false">https://nathanacurtis.substack.com/p/component-specifications-1492ca4c94c</guid><dc:creator><![CDATA[Nathan Curtis]]></dc:creator><pubDate>Mon, 20 Feb 2023 17:01:53 GMT</pubDate><enclosure url="https://cdn-images-1.medium.com/max/800/1*Z7WZtOcU2lSi5M1nNlb4kg.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4>What to include, where it goes, and why it matters more&nbsp;now</h4><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*Z7WZtOcU2lSi5M1nNlb4kg.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*Z7WZtOcU2lSi5M1nNlb4kg.png 424w, https://cdn-images-1.medium.com/max/800/1*Z7WZtOcU2lSi5M1nNlb4kg.png 848w, https://cdn-images-1.medium.com/max/800/1*Z7WZtOcU2lSi5M1nNlb4kg.png 1272w, https://cdn-images-1.medium.com/max/800/1*Z7WZtOcU2lSi5M1nNlb4kg.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*Z7WZtOcU2lSi5M1nNlb4kg.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*Z7WZtOcU2lSi5M1nNlb4kg.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Component specifications format&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Component specifications format" title="Component specifications format" srcset="https://cdn-images-1.medium.com/max/800/1*Z7WZtOcU2lSi5M1nNlb4kg.png 424w, https://cdn-images-1.medium.com/max/800/1*Z7WZtOcU2lSi5M1nNlb4kg.png 848w, https://cdn-images-1.medium.com/max/800/1*Z7WZtOcU2lSi5M1nNlb4kg.png 1272w, https://cdn-images-1.medium.com/max/800/1*Z7WZtOcU2lSi5M1nNlb4kg.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>During the emerging years of design systems (2015&#8211;2018), designers and developers <a href="https://medium.com/eightshapes-llc/designing-a-systems-team-d22f27a2d81d">form teams</a> to crank out components. Tight collaborative connections favored conversation over artifacts to align, decide, and move forward. As a component design stabilized, designers might have erratically sprinkle callouts, tidied up the variant grid, or redlined a variant. After that, it was ready to handoff to a developer.</p><p>Things have changed. Components are more complicated. Designers are delivering to <em>many</em> different developers. Accessibility has risen to the fore. For design systems that scale, teams are finding it necessary to write down all the details again.</p><p>Over the past three to four years, I&#8217;ve worked across many design systems to formalize a design specifications format that&#8217;s proven repeatable and robust. Parts of it are repeatable enough that we&#8217;ve published a <a href="https://www.figma.com/community/plugin/1205622541257680763/EightShapes-Specs">Specs Figma plugin</a> that&#8217;s described in a <a href="https://medium.com/eightshapes-llc/the-eightshapes-specs-figma-plugin-2892f21adc96">companion article</a> and supported by a <a href="https://www.figma.com/community/file/1209522764482054077">Figma community file with templates and components</a>. This article expands on why component specs are important, where teams consolidate them, and what kinds of details and artwork they include.</p><h3>Why specs&nbsp;matter</h3><p>I&#8217;m still amazed when designers schlep together a few pictures, publish a configurable Figma component, point their developer counterparts at the main component and say &#8220;Use Figma&#8217;s inspect tool.&#8221;</p><p>First, Figma&#8217;s Inspect tool isn&#8217;t bad, but it&#8217;s limited. Inspection in general requires considerable scrutiny and persistence to find every decision you&#8217;ve made. Understanding design intent shouldn&#8217;t be a treasure hunt. Don&#8217;t give a developer a shovel, point into the distance and say &#8220;Dig over here, try that area too, but bother digging in those corners?&#8221; If you know where the treasure is, just dig it up and given it to them.</p><blockquote><p>Understanding design intent shouldn&#8217;t be a treasure&nbsp;hunt</p></blockquote><p>Second, Figma components don&#8217;t reveal everything you need to know to built a well-designed component. There&#8217;s more to it than that: behaviors, code only properties, accessibility to name a few. Therefore, it&#8217;s like dishonestly setting a teammate out with a shovel to dig up treasure when you know half the treasure isn&#8217;t even buried there anyway.</p><p>Nevertheless, for a few years, design system teams were small and strong enough to talk often and synchrously enough to agree on those things.</p><p>Now, the game has changed.</p><h4>Multi-platform builds &#8594; Collaborative connections are&nbsp;weaker</h4><p>A single code library has given way to building across platforms. A three platform setup (iOS, Android, and web) is common, and some systems like <a href="https://carbondesignsystem.com/developing/frameworks/react/">IBM Carbon</a> spread across many more. As a result, one design serves many independent development teams. While handoffs across teams remain, developers lack tight relationships with designer(s) to understand requirements. Specs fill that void.</p><h4>Props, motion, accessibility,&nbsp;&#8230; &#8594; Components are complicated</h4><p>It&#8217;s not just styling. Components increasingly encapsulate many features. From detailed accessibility notes to analytics integration to content to tokens, there&#8217;s so much more to describe and decide. Specs provide a model to fill in all those blanks.</p><h4>Quality and craft &#8594; Naming needs a decisive focal&nbsp;point</h4><p>We&#8217;re now years into crafting API together. Those conversations can fluidly span from planning a component before you start to polishing and pivoting during coding. Yet, the spec handoff is the routine moment to discuss and decide the structure (element and layer names), configuration (mostly, properties and option names), and default content.</p><h4>Theming &#8594; Tokens must be&nbsp;mapped</h4><p>The component&#8217;s API has extended to include how <a href="https://medium.com/eightshapes-llc/naming-tokens-in-design-systems-9e86c7444676">semantic tokens flow into each component</a>, and how themes may need to target specific attributes of specific elements to vary characteristics. Specs document those mappings.</p><h4>Flexibility &#8594; Components have intricate parts and dependencies</h4><p>The trend towards greater flexibility has design systems thinking in slots and <a href="https://medium.com/eightshapes-llc/subcomponents-753ce9f6600a">subcomponents</a> and offering smaller parts. This disperses configuration across more components of greater nested depth. Specs help us expose, decide, and evolve where we target each feature.</p><h4>Enterprise scale &#8594; Change across generations must be described</h4><p>Systems last longer with impacts that span rebrands, refactors, and replatforms. Designs evolve, often more and more slowly, and different code implementations may upgrade design at different, staggered times. Specs offer a place to record, illustrate, and track that change.</p><h3>Where specs&nbsp;go</h3><p>Teams that I work with are authoring specs in a consistent format in a single <strong>Core Specifications</strong> Figma file. This file is:</p><ul><li><p>Visible to everyone in the organization</p></li><li><p>Branched with only a few editors of the main branch (such as the design system&#8217;s design lead and 1&#8211;2 senior design team members)</p></li><li><p>Begun with Cover, Component status and About this file pages</p></li><li><p>One foundation (e.g., color) or component (e.g., text input) per page</p></li><li><p>Ordered alphabetically within Foundation and Components sections</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*3XdgqXu7siQWTLnymvDkEQ.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*3XdgqXu7siQWTLnymvDkEQ.png 424w, https://cdn-images-1.medium.com/max/800/1*3XdgqXu7siQWTLnymvDkEQ.png 848w, https://cdn-images-1.medium.com/max/800/1*3XdgqXu7siQWTLnymvDkEQ.png 1272w, https://cdn-images-1.medium.com/max/800/1*3XdgqXu7siQWTLnymvDkEQ.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*3XdgqXu7siQWTLnymvDkEQ.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*3XdgqXu7siQWTLnymvDkEQ.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Component specs file cover and page organization&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Component specs file cover and page organization" title="Component specs file cover and page organization" srcset="https://cdn-images-1.medium.com/max/800/1*3XdgqXu7siQWTLnymvDkEQ.png 424w, https://cdn-images-1.medium.com/max/800/1*3XdgqXu7siQWTLnymvDkEQ.png 848w, https://cdn-images-1.medium.com/max/800/1*3XdgqXu7siQWTLnymvDkEQ.png 1272w, https://cdn-images-1.medium.com/max/800/1*3XdgqXu7siQWTLnymvDkEQ.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Component specs file cover and page organization</figcaption></figure></div><h3>What specs&nbsp;include</h3><p>Specifications include a range of content, some automated and others manual, including:</p><ul><li><p>Anatomy</p></li><li><p>Properties</p></li><li><p>Layout and spacing</p></li><li><p>Behavior</p></li><li><p>Accessibility</p></li><li><p>Motion</p></li><li><p>Component tokens</p></li><li><p>Version history</p></li></ul><h4>Anatomy</h4><p>An anatomy breaks down a component into parts, itemizes and names each one, and can describe visual attributes (like text color) and configured properties (of nested component dependencies).</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*R33yRhXLNqpM73fCiRk8JA.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*R33yRhXLNqpM73fCiRk8JA.png 424w, https://cdn-images-1.medium.com/max/800/1*R33yRhXLNqpM73fCiRk8JA.png 848w, https://cdn-images-1.medium.com/max/800/1*R33yRhXLNqpM73fCiRk8JA.png 1272w, https://cdn-images-1.medium.com/max/800/1*R33yRhXLNqpM73fCiRk8JA.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*R33yRhXLNqpM73fCiRk8JA.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*R33yRhXLNqpM73fCiRk8JA.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Anatomy specifications, include nested component properties and element-by-element attributes&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Anatomy specifications, include nested component properties and element-by-element attributes" title="Anatomy specifications, include nested component properties and element-by-element attributes" srcset="https://cdn-images-1.medium.com/max/800/1*R33yRhXLNqpM73fCiRk8JA.png 424w, https://cdn-images-1.medium.com/max/800/1*R33yRhXLNqpM73fCiRk8JA.png 848w, https://cdn-images-1.medium.com/max/800/1*R33yRhXLNqpM73fCiRk8JA.png 1272w, https://cdn-images-1.medium.com/max/800/1*R33yRhXLNqpM73fCiRk8JA.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Anatomy specifications, include nested component properties and element-by-element attributes</figcaption></figure></div><h4>Properties</h4><p>A properties section can illustrate each property, contrast a default with alternative options, and describe detailed differences of visual attributes and nested component properties.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*3rfebiRaGKu0ZirlwHVjWw.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*3rfebiRaGKu0ZirlwHVjWw.png 424w, https://cdn-images-1.medium.com/max/800/1*3rfebiRaGKu0ZirlwHVjWw.png 848w, https://cdn-images-1.medium.com/max/800/1*3rfebiRaGKu0ZirlwHVjWw.png 1272w, https://cdn-images-1.medium.com/max/800/1*3rfebiRaGKu0ZirlwHVjWw.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*3rfebiRaGKu0ZirlwHVjWw.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*3rfebiRaGKu0ZirlwHVjWw.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Compound property specification, detailing tokens and props applying to light and dark variants&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Compound property specification, detailing tokens and props applying to light and dark variants" title="Compound property specification, detailing tokens and props applying to light and dark variants" srcset="https://cdn-images-1.medium.com/max/800/1*3rfebiRaGKu0ZirlwHVjWw.png 424w, https://cdn-images-1.medium.com/max/800/1*3rfebiRaGKu0ZirlwHVjWw.png 848w, https://cdn-images-1.medium.com/max/800/1*3rfebiRaGKu0ZirlwHVjWw.png 1272w, https://cdn-images-1.medium.com/max/800/1*3rfebiRaGKu0ZirlwHVjWw.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Compound property specification, detailing tokens and props applying to light and dark&nbsp;variants</figcaption></figure></div><p>Property specifications can also highlight non-visual props relevant to code, accessibility and content, often in a tabular format.</p><h4>Layout and&nbsp;spacing</h4><p>Specs help us highlight the very intentional spacing choices that separate, inset, and align each element we arrange. A <strong>Spacing</strong> section illustrates padding, margin (in Figma, item spacing), direction and other mechanics.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*HUtFRBWOX3D0auD7oJguQg.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*HUtFRBWOX3D0auD7oJguQg.png 424w, https://cdn-images-1.medium.com/max/800/1*HUtFRBWOX3D0auD7oJguQg.png 848w, https://cdn-images-1.medium.com/max/800/1*HUtFRBWOX3D0auD7oJguQg.png 1272w, https://cdn-images-1.medium.com/max/800/1*HUtFRBWOX3D0auD7oJguQg.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*HUtFRBWOX3D0auD7oJguQg.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*HUtFRBWOX3D0auD7oJguQg.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Layout and spacing specifications by layer by nested layer&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Layout and spacing specifications by layer by nested layer" title="Layout and spacing specifications by layer by nested layer" srcset="https://cdn-images-1.medium.com/max/800/1*HUtFRBWOX3D0auD7oJguQg.png 424w, https://cdn-images-1.medium.com/max/800/1*HUtFRBWOX3D0auD7oJguQg.png 848w, https://cdn-images-1.medium.com/max/800/1*HUtFRBWOX3D0auD7oJguQg.png 1272w, https://cdn-images-1.medium.com/max/800/1*HUtFRBWOX3D0auD7oJguQg.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Layout and spacing specifications by layer by nested&nbsp;layer</figcaption></figure></div><p><strong>Text wrapping</strong>, also labeled as <strong>Overflow</strong>, illustrates what to expect visually with excessive content, such as long text strings and/or large images. These specs can reveal unexpected intents of counter alignment (such as middled aligned text columns) or truncation (such as a text input&#8217;s hiding characters that exceed it&#8217;s width).</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*jM-miXo0ozxDDbKDr8Gfiw.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*jM-miXo0ozxDDbKDr8Gfiw.png 424w, https://cdn-images-1.medium.com/max/800/1*jM-miXo0ozxDDbKDr8Gfiw.png 848w, https://cdn-images-1.medium.com/max/800/1*jM-miXo0ozxDDbKDr8Gfiw.png 1272w, https://cdn-images-1.medium.com/max/800/1*jM-miXo0ozxDDbKDr8Gfiw.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*jM-miXo0ozxDDbKDr8Gfiw.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*jM-miXo0ozxDDbKDr8Gfiw.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Artwork demonstrating how text wraps with long content strings.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Artwork demonstrating how text wraps with long content strings." title="Artwork demonstrating how text wraps with long content strings." srcset="https://cdn-images-1.medium.com/max/800/1*jM-miXo0ozxDDbKDr8Gfiw.png 424w, https://cdn-images-1.medium.com/max/800/1*jM-miXo0ozxDDbKDr8Gfiw.png 848w, https://cdn-images-1.medium.com/max/800/1*jM-miXo0ozxDDbKDr8Gfiw.png 1272w, https://cdn-images-1.medium.com/max/800/1*jM-miXo0ozxDDbKDr8Gfiw.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Text wrapping&nbsp;exhibit</figcaption></figure></div><p>Additional subsections can illustrate aspects <strong>Responsiveness</strong>, <strong>Sizing</strong>, and <strong>Touch Targets</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*2L1Fo7te3LzPg4wJC9gNew.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*2L1Fo7te3LzPg4wJC9gNew.png 424w, https://cdn-images-1.medium.com/max/800/1*2L1Fo7te3LzPg4wJC9gNew.png 848w, https://cdn-images-1.medium.com/max/800/1*2L1Fo7te3LzPg4wJC9gNew.png 1272w, https://cdn-images-1.medium.com/max/800/1*2L1Fo7te3LzPg4wJC9gNew.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*2L1Fo7te3LzPg4wJC9gNew.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*2L1Fo7te3LzPg4wJC9gNew.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Touch targets template&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Touch targets template" title="Touch targets template" srcset="https://cdn-images-1.medium.com/max/800/1*2L1Fo7te3LzPg4wJC9gNew.png 424w, https://cdn-images-1.medium.com/max/800/1*2L1Fo7te3LzPg4wJC9gNew.png 848w, https://cdn-images-1.medium.com/max/800/1*2L1Fo7te3LzPg4wJC9gNew.png 1272w, https://cdn-images-1.medium.com/max/800/1*2L1Fo7te3LzPg4wJC9gNew.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Touch targets&nbsp;template</figcaption></figure></div><h4>Behavior and animation</h4><p>Behavior specifications often document events (such as <code>click</code>, <code>mousedown</code>, and <code>drag</code>) and textually describe or visual depict the change in state triggered by that event.</p><p>Animation specifications can be conflated with behavior, since event triggers and shifts of state are central to the motion that occurs between those moments.</p><h4>Accessibility</h4><p>Designers can add considerable detail across broad considerations to ensure a component design is implemented accessibly. Stephanie Walter gave a great talk at the Clarity Conference in 2022 about <a href="https://stephaniewalter.design/blog/a-designers-guide-to-documenting-accessibility-user-interactions/">A Designer&#8217;s Guide to Documenting Accessibility &amp; User Interactions</a>.</p><p>While I&#8217;m not an accessibility expert, I&#8217;ve worked with many designers who know more than I do to describe the auditable expectations of how a compoennt is built. For example, Felix Kuo and I worked to refine a detailed section on <strong>Screen reading</strong>. Artwork is paired with element-by-element annotations of the <code>reading</code> format, an <code>example</code> in practice (matching the artwork), and the <code>role</code> of the element described.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*Y8CnQ-5DceYG--XOpI4bLA.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*Y8CnQ-5DceYG--XOpI4bLA.png 424w, https://cdn-images-1.medium.com/max/800/1*Y8CnQ-5DceYG--XOpI4bLA.png 848w, https://cdn-images-1.medium.com/max/800/1*Y8CnQ-5DceYG--XOpI4bLA.png 1272w, https://cdn-images-1.medium.com/max/800/1*Y8CnQ-5DceYG--XOpI4bLA.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*Y8CnQ-5DceYG--XOpI4bLA.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*Y8CnQ-5DceYG--XOpI4bLA.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Accessibility screen reading specs per element&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Accessibility screen reading specs per element" title="Accessibility screen reading specs per element" srcset="https://cdn-images-1.medium.com/max/800/1*Y8CnQ-5DceYG--XOpI4bLA.png 424w, https://cdn-images-1.medium.com/max/800/1*Y8CnQ-5DceYG--XOpI4bLA.png 848w, https://cdn-images-1.medium.com/max/800/1*Y8CnQ-5DceYG--XOpI4bLA.png 1272w, https://cdn-images-1.medium.com/max/800/1*Y8CnQ-5DceYG--XOpI4bLA.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Accessibility screen reading specs per&nbsp;element</figcaption></figure></div><p>Among the many potential other component accessibility spec formats, I&#8217;ve most often encountered treatments on <strong>Focus order</strong>, <strong>Announced order</strong>, and <strong>Alternative text</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*0-ppsGrAvREwgi_gtP414Q.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*0-ppsGrAvREwgi_gtP414Q.png 424w, https://cdn-images-1.medium.com/max/800/1*0-ppsGrAvREwgi_gtP414Q.png 848w, https://cdn-images-1.medium.com/max/800/1*0-ppsGrAvREwgi_gtP414Q.png 1272w, https://cdn-images-1.medium.com/max/800/1*0-ppsGrAvREwgi_gtP414Q.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*0-ppsGrAvREwgi_gtP414Q.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*0-ppsGrAvREwgi_gtP414Q.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/800/1*0-ppsGrAvREwgi_gtP414Q.png 424w, https://cdn-images-1.medium.com/max/800/1*0-ppsGrAvREwgi_gtP414Q.png 848w, https://cdn-images-1.medium.com/max/800/1*0-ppsGrAvREwgi_gtP414Q.png 1272w, https://cdn-images-1.medium.com/max/800/1*0-ppsGrAvREwgi_gtP414Q.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Additional accessibility specs for focus order, announced order and alternative text</figcaption></figure></div><h4>Component tokens</h4><p>As design tooling evolves quickly, many teams use plugins like <a href="https://www.figma.com/community/plugin/843461159747178978">Tokens Studio for Figma</a> and homegrown theme plugins to enable designers to apply and swap themes. Nevertheless, component specs can still be valuable to communicate <strong><a href="https://medium.com/eightshapes-llc/naming-tokens-in-design-systems-9e86c7444676">component token</a></strong><a href="https://medium.com/eightshapes-llc/naming-tokens-in-design-systems-9e86c7444676">-level models and overrides</a> and extensions per component.</p><p>Using the format depicted below, teams inventory will component-level tokens (mostly color, but there could be typography, space and other attributes needed for theming. Relevant token details could include a description, alias (usually to a semantic token), Figma style names (when relevant) and default values.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*NKSw2z5GmsysuDe_16JdPg.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*NKSw2z5GmsysuDe_16JdPg.png 424w, https://cdn-images-1.medium.com/max/800/1*NKSw2z5GmsysuDe_16JdPg.png 848w, https://cdn-images-1.medium.com/max/800/1*NKSw2z5GmsysuDe_16JdPg.png 1272w, https://cdn-images-1.medium.com/max/800/1*NKSw2z5GmsysuDe_16JdPg.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*NKSw2z5GmsysuDe_16JdPg.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*NKSw2z5GmsysuDe_16JdPg.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/800/1*NKSw2z5GmsysuDe_16JdPg.png 424w, https://cdn-images-1.medium.com/max/800/1*NKSw2z5GmsysuDe_16JdPg.png 848w, https://cdn-images-1.medium.com/max/800/1*NKSw2z5GmsysuDe_16JdPg.png 1272w, https://cdn-images-1.medium.com/max/800/1*NKSw2z5GmsysuDe_16JdPg.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Component token specs including a description, alias, and Figma style&nbsp;name</figcaption></figure></div><h4>Version history</h4><p>Component specs usually aren&#8217;t handed off once. Instead, specs are managed over time during a redesign cycle, as it evolves, as it&#8217;s adjusted when built for multiple code platforms like React, Angular, iOS and Android, and after it&#8217;s released.</p><p>A version history can be useful for spec readers to understand what&#8217;s changed since they referenced the specification in their own work. Versions are typically added each time a branch is merged that changes the specs.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://cdn-images-1.medium.com/max/800/1*h4lHnciGC5rcla_2mCHO_g.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://cdn-images-1.medium.com/max/800/1*h4lHnciGC5rcla_2mCHO_g.png 424w, https://cdn-images-1.medium.com/max/800/1*h4lHnciGC5rcla_2mCHO_g.png 848w, https://cdn-images-1.medium.com/max/800/1*h4lHnciGC5rcla_2mCHO_g.png 1272w, https://cdn-images-1.medium.com/max/800/1*h4lHnciGC5rcla_2mCHO_g.png 1456w" sizes="100vw"><img src="https://cdn-images-1.medium.com/max/800/1*h4lHnciGC5rcla_2mCHO_g.png" data-attrs="{&quot;src&quot;:&quot;https://cdn-images-1.medium.com/max/800/1*h4lHnciGC5rcla_2mCHO_g.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:null,&quot;width&quot;:null,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://cdn-images-1.medium.com/max/800/1*h4lHnciGC5rcla_2mCHO_g.png 424w, https://cdn-images-1.medium.com/max/800/1*h4lHnciGC5rcla_2mCHO_g.png 848w, https://cdn-images-1.medium.com/max/800/1*h4lHnciGC5rcla_2mCHO_g.png 1272w, https://cdn-images-1.medium.com/max/800/1*h4lHnciGC5rcla_2mCHO_g.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Version history of the specification</figcaption></figure></div><h4>Specs &#8800; Design guidelines</h4><p>Specs are largely concerned with <em>how to make</em> a component, not <em>how to use</em> a component in practice. Therefore, I advise teams that design specs and <a href="https://medium.com/eightshapes-llc/component-design-guidelines-eca706100e7c">design guidelines</a> overlap yet have different audiences and intents. The overlapping content can take differing forms such as a spec&#8217;s Anatomy including far more detail than a similar, simpler Anatomy of design guidelines.</p><p><em>Takeaway</em>: Don&#8217;t get stuck delaying or complicating specs with guidelines; save design guideline production for later closer to release.</p><p>In closing, component specifications can include a wide range of in-depth details. While some facets can be automated, others require deliberate consideration and manual work to get the details right. As you consider the potential specs you could create, keep your reader in mind: usually, first and foremost, the people building what you&#8217;ve designed and also others who must understand how it&#8217;s built to use it in their work.</p>]]></content:encoded></item></channel></rss>