You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Over the holidays while things were quiet, I rewrote our Shopify CLI plugin for theme components from scratch, after spending over 2 years on the previous version. The following line stuck with me while immersed in my coding hole:
“Progress is good. Complexity is a bridge. Simplicity is the destination.” — DHH (source)
The complexity we wrestled with has served as a necessary bridge to reach a simpler, more elegant solution. The latest version of our CLI plugin is mostly just a refactor to best reflect the simplicity of our approach to reusable theme components. We've introduced a few refinements to our approach, but it still ultimately delivers on the same vision we've always had.
Let's take a look at how we got here!
The Bridge of Complexity
We’ve explored component-based approaches for Shopify themes for a while. Our goal is to package UI chunks for reuse across multiple theme projects, reducing duplication, enforcing consistency, improving quality, and accelerating development. Although this approach is standard in many parts of the web, we learned that achieving simplicity we’re seeking is not so simple.
Presentation vs. State
Our first source of complexity was clarifying what belongs in a Shopify Liquid theme component and what does not. Should global, section, or block setting schemas go in the component? What about translation locales? Section files? Initially, we grouped all these related pieces to what felt right inside a directory.
We later discovered that truely reusable component require separating presentation (how content looks) from state (how data is managed and passed).
State can come from anywhere. In themes, it’s typically from theme editor settings, translation locales, metafields, and store configuration (products, blogs, navigation). Components simply consume that state, which can be passed any number of ways, to display content.
Themes own state. Components own presentation. With this clear line, components can work independently of any single theme or store. For details, see our document on separating presentation from state.
Shopify CLI Plugin
Our mission wasn’t just to stitch components together in a single theme; we also wanted their Liquid, CSS, and JavaScript assets to exist outside a theme’s boundaries. True reusability across projects requires the freedom to develop and manage components in isolation.
We initially built a standalone CLI to facilitate the workflows between components and themes. Later, we discovered Shopify CLI’s OClif plugin architecture, which let us integrate directly into official tooling and streamline the install steps rather than reinventing the wheel.
Complexity grew as we adapted our CLI to the work with oclif. It worked, but our plugin was becoming so complex we actually started dreading to work on it. No bueno.
File Transformations
At first, we believed we needed a build step to bundle JavaScript and CSS. Our CLI scanned chosen components, calculated dependencies, and bundled them. Over time, we found more “vanilla” solutions:
JavaScript: By adopting island architecture and using import maps, we eliminated the need for JS bundling.
CSS: Individual component CSS files are either inlined and loaded async, resulting in faster page speed than a single bundle. See our post on NoBuild CSS for details.
Although these practices felt radical at first, they're working and have simplified our approach even further. Meanwhile, the complexity of more iterations continued to show in our CLI plugin.
Embracing Simplicity
Years of refining our approach in pursuit of simplicity left our CLI plugin bloated with unneeded complexity. Ultimately, we only required a tool to:
Identify the snippets and assets to include in a theme
Copy those files into a theme project
Remove any files no longer being used
Bonus: Generate an import map JSON for each JavaScript file in the theme’s asset folder because we like ES modules
These steps save time by automating repetitive tasks. You could perform them manually, but doing so would be error-prone and slow.
After nearly two years of learning, we rewrote the CLI plugin in four days, incorporating our best insights:
Full TypeScript for clarity and robustness
Comprehensive Tests to prevent regressions
New Features such as support for multiple component collections and simple JS import-map generation
No Build approach without any bundling or compilers. Harness the full potential of the modern web browser platform.
We distilled two years of exploration into a clean, powerful tool aligned with Shopify theme development’s future. For more details, check out our January 2025 update.
Build for the long term
We started Devkit with an ambitious goal—set the standard for reusable components for Shopify themes. We’ve emerged with a simple approach with a low learning curve and easy to integrate into any theme project.
Taking the time to refactor, simplify and clean up behind us is an act of building for the long term. Progress is good. Complexity is a bridge. Simplicity is the destination. 🥂
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Over the holidays while things were quiet, I rewrote our Shopify CLI plugin for theme components from scratch, after spending over 2 years on the previous version. The following line stuck with me while immersed in my coding hole:
The complexity we wrestled with has served as a necessary bridge to reach a simpler, more elegant solution. The latest version of our CLI plugin is mostly just a refactor to best reflect the simplicity of our approach to reusable theme components. We've introduced a few refinements to our approach, but it still ultimately delivers on the same vision we've always had.
Let's take a look at how we got here!
The Bridge of Complexity
We’ve explored component-based approaches for Shopify themes for a while. Our goal is to package UI chunks for reuse across multiple theme projects, reducing duplication, enforcing consistency, improving quality, and accelerating development. Although this approach is standard in many parts of the web, we learned that achieving simplicity we’re seeking is not so simple.
Presentation vs. State
Our first source of complexity was clarifying what belongs in a Shopify Liquid theme component and what does not. Should global, section, or block setting schemas go in the component? What about translation locales? Section files? Initially, we grouped all these related pieces to what felt right inside a directory.
We later discovered that truely reusable component require separating presentation (how content looks) from state (how data is managed and passed).
State can come from anywhere. In themes, it’s typically from theme editor settings, translation locales, metafields, and store configuration (products, blogs, navigation). Components simply consume that state, which can be passed any number of ways, to display content.
Themes own state. Components own presentation. With this clear line, components can work independently of any single theme or store. For details, see our document on separating presentation from state.
Shopify CLI Plugin
Our mission wasn’t just to stitch components together in a single theme; we also wanted their Liquid, CSS, and JavaScript assets to exist outside a theme’s boundaries. True reusability across projects requires the freedom to develop and manage components in isolation.
We initially built a standalone CLI to facilitate the workflows between components and themes. Later, we discovered Shopify CLI’s OClif plugin architecture, which let us integrate directly into official tooling and streamline the install steps rather than reinventing the wheel.
Complexity grew as we adapted our CLI to the work with oclif. It worked, but our plugin was becoming so complex we actually started dreading to work on it. No bueno.
File Transformations
At first, we believed we needed a build step to bundle JavaScript and CSS. Our CLI scanned chosen components, calculated dependencies, and bundled them. Over time, we found more “vanilla” solutions:
Although these practices felt radical at first, they're working and have simplified our approach even further. Meanwhile, the complexity of more iterations continued to show in our CLI plugin.
Embracing Simplicity
Years of refining our approach in pursuit of simplicity left our CLI plugin bloated with unneeded complexity. Ultimately, we only required a tool to:
These steps save time by automating repetitive tasks. You could perform them manually, but doing so would be error-prone and slow.
After nearly two years of learning, we rewrote the CLI plugin in four days, incorporating our best insights:
We distilled two years of exploration into a clean, powerful tool aligned with Shopify theme development’s future. For more details, check out our January 2025 update.
Build for the long term
We started Devkit with an ambitious goal—set the standard for reusable components for Shopify themes. We’ve emerged with a simple approach with a low learning curve and easy to integrate into any theme project.
Taking the time to refactor, simplify and clean up behind us is an act of building for the long term. Progress is good. Complexity is a bridge. Simplicity is the destination. 🥂
Beta Was this translation helpful? Give feedback.
All reactions