Two Paths, One Platform
Shopify offers two fundamentally different ways to build a storefront, and the choice you make has implications that ripple through your team, your budget, and your product roadmap for years. On one side: headless, where a React-based app (typically Hydrogen, Shopify's Remix-based framework) fetches data through the Storefront API and renders every pixel independently. On the other: hybrid, where Shopify's Liquid templating engine handles server rendering while JavaScript islands add interactivity where static HTML falls short.
Both approaches are officially supported by Shopify. Neither is universally correct. The right decision depends on your team's capabilities, your budget, your business model, and your content workflow, not which architecture sounds more modern at a conference talk.
What Headless Actually Means
Headless Shopify is a fully decoupled frontend. Your storefront is a React application, typically built with Hydrogen, Shopify's Remix-based framework, that fetches all product, collection, cart, and customer data through the Storefront API. Shopify becomes a pure commerce backend: inventory, checkout, payments, order management. Your app controls every pixel of the experience.
Deployment options are flexible. Oxygen is Shopify's own hosting platform, purpose-built for Hydrogen apps with edge rendering and built-in caching. But you can also deploy to Vercel, Cloudflare Workers, Netlify, or any platform that supports server-side rendering. The tradeoff is clear: you own the infrastructure, the build pipeline, and every deployment.
Here's what a typical Hydrogen product page component looks like, a Remix loader fetching from the Storefront API and a React component rendering the result:
import {useLoaderData} from '@remix-run/react';
import {json} from '@shopify/remix-oxygen';
export async function loader({params, context}) {
const {product} = await context.storefront.query(PRODUCT_QUERY, {
variables: {handle: params.handle},
});
if (!product) throw new Response(null, {status: 404});
return json({product});
}
export default function ProductPage() {
const {product} = useLoaderData();
return (
<div className="product-page">
<img src={product.featuredImage.url} alt={product.featuredImage.altText} />
<h1>{product.title}</h1>
<p>{product.descriptionHtml}</p>
<ProductForm product={product} />
</div>
);
}
const PRODUCT_QUERY = `#graphql
query Product($handle: String!) {
product(handle: $handle) {
id
title
descriptionHtml
featuredImage {
url
altText
}
variants(first: 50) {
nodes {
id
title
price {
amount
currencyCode
}
availableForSale
}
}
}
}
`;
The component follows Remix conventions: the loader function runs server-side, queries the Storefront API using Hydrogen's built-in client, and the component renders the response. The GraphQL query is colocated with the component, giving you full control over exactly what data you fetch and how you display it.
What Hybrid Actually Means
Hybrid Shopify keeps Liquid as the primary rendering layer and enhances it with JavaScript where interactivity is needed. The store lives on Shopify's CDN, uses the theme editor, and benefits from the full app ecosystem. JavaScript frameworks, Alpine.js, Vue, or React, power specific interactive components: variant selectors, cart drawers, filtering, real-time pricing. The rest of the page is server-rendered HTML, cached and fast by default.
The critical advantage is that the theme editor, app blocks, sections, and Shopify's 8,000+ app marketplace all still work. Merchants can update content, rearrange sections, and install apps without touching code. Here's the same product page as a hybrid Liquid template with a JavaScript island for the variant selector:
{%- comment -%} Server-rendered by Liquid, SEO-friendly, cached by CDN {%- endcomment -%}
<div class="product-page">
<img src="{{ product.featured_image | image_url: width: 1200 }}"
alt="{{ product.featured_image.alt | escape }}" />
<h1>{{ product.title }}</h1>
{{ product.description }}
{%- comment -%} JavaScript island, interactive variant selector {%- endcomment -%}
<div id="variant-selector"
data-product-json='{{ product | json }}'></div>
</div>
<script type="module" src="{{ 'variant-selector.js' | asset_url }}" defer></script>
The Liquid template handles the server-rendered HTML, SEO-friendly and CDN-cached, while the JavaScript module mounts only where interactivity is needed. The product JSON is serialized into a data attribute, giving the JavaScript component everything it needs without an additional API call.
The Real Cost Comparison
This is where architecture discussions get real. The cost difference between headless and hybrid isn't incremental, it's multiplicative. Here's what each approach actually costs for a mid-complexity store.
Headless (Hydrogen + Oxygen):
- Initial build: 400–800 developer hours (vs 100–300 for a theme)
- Monthly hosting: $0–300 on Oxygen (included with Shopify Plus, pay-per-use otherwise)
- App replacements: Many Shopify apps don't work headless, you rebuild or buy SaaS replacements for reviews, loyalty, wishlist, and SEO tools ($200–2,000/month)
- Content updates: Every text change requires a developer or a headless CMS ($50–500/month for Contentful, Sanity, etc.)
- Total Year 1: $80,000–250,000+
Hybrid (Liquid + JavaScript islands):
- Initial build: 100–300 developer hours
- Monthly hosting: $0 (included with any Shopify plan)
- App ecosystem: Full compatibility with 8,000+ Shopify apps
- Content updates: Theme editor, no developer needed for most changes
- Total Year 1: $15,000–60,000
The hidden cost of headless is maintenance. Every Storefront API update, every checkout change, every new Shopify feature requires your engineering team to evaluate and integrate. With Liquid themes, Shopify handles these updates automatically.
Performance: Myths vs Measurements
Performance is the most commonly cited reason to go headless, and it's also the most commonly misunderstood. Headless can be faster, but only with proper edge caching, image optimization, and code splitting. A stock Liquid theme on Shopify's CDN achieves sub-second TTFB globally with zero effort on your part.
Here's what real-world performance looks like across three common scenarios:
Well-optimized Liquid theme: TTFB 80–150ms (Shopify CDN), FCP 0.8–1.2s, LCP 1.0–2.0s
Hydrogen on Oxygen: TTFB 100–250ms (streaming SSR), FCP 0.6–1.0s, LCP 0.8–1.8s
Poorly built headless: TTFB 300–800ms (uncached API calls), FCP 2–4s, LCP 3–6s
The third scenario is more common than anyone in the headless ecosystem wants to admit. Teams underinvest in caching architecture, skip edge deployment, or load too much JavaScript upfront. The result is a storefront that's measurably slower than the Liquid theme it replaced.
A note on real-world results. The fastest Shopify stores I've worked on have been hybrid Liquid themes. Not because Liquid is inherently faster, but because the Shopify CDN does the performance work for you. Headless can match or beat this, but it requires intentional caching architecture that many teams skip.
The App Ecosystem Factor
This is often the deciding factor that teams discover too late. Shopify's app ecosystem, 8,000+ apps, is built for Liquid themes. Apps inject script tags, register app blocks, add snippets, and hook into the theme editor. Going headless means losing compatibility with most of these apps.
What you lose going headless:
- Product reviews (Judge.me, Loox, Stamped), need API integration or replacement
- Loyalty programs (Smile.io, LoyaltyLion), need custom integration
- SEO tools (Ahrefs, SEO Manager), largely incompatible
- Announcement bars, popups, chat widgets, need rebuilding
- Analytics beyond Shopify's built-in, need custom implementation
What you keep regardless of architecture: Shopify's checkout (always on Shopify's domain), payment processing, inventory management, order management, Shopify Functions, and Shopify Flow. The commerce engine is architecture-agnostic, only the storefront presentation layer changes.
Team Capability Assessment
Headless requires a fundamentally different skill set than theme development. Your team needs React and Remix proficiency, GraphQL expertise (the Storefront API is exclusively GraphQL), edge deployment and caching knowledge, CI/CD pipeline management, and performance optimization skills including bundle analysis and code splitting.
Hybrid requires a more traditional web development skill set: Liquid templating, basic JavaScript (or Alpine.js, Vue, or React for interactive islands), CSS and design implementation, and Shopify theme editor familiarity.
If your team is primarily Liquid developers, going headless means either retraining the entire team or hiring new developers. The migration period, where the team is learning headless while maintaining the existing theme, is expensive and risky. I've seen this transition take 6–12 months and cost more than the initial headless build itself.
Checkout and Shopify Plus Considerations
One architectural constant: regardless of whether you go headless or hybrid, checkout always lives on Shopify's domain. Shopify does not expose checkout rendering to headless storefronts. This means Checkout UI Extensions work identically in both architectures, and Shopify Functions (discounts, shipping, payment customization) are fully available regardless of your storefront choice.
Shopify Plus features like Checkout Extensibility, B2B, and multi-location inventory are available in both architectures. The architecture decision doesn't lock you out of any commerce features, only storefront presentation features. If someone tells you that you need headless to access advanced Shopify Plus capabilities, they're either misinformed or selling you a headless build.
When Headless Is the Right Choice
Headless is the right architecture when the constraints of Shopify's theme system are genuinely blocking your business goals. These are the specific scenarios where headless makes sense:
- Multi-brand storefronts sharing one Shopify backend
- Deeply integrated headless CMS content (Contentful, Sanity) where editorial workflows drive the experience
- Native-app-level interactions: 3D configurators, AR experiences, complex product builders
- Multi-commerce-backend setups where Shopify is one of several data sources
- Content-heavy editorial sites with commerce features bolted on, think a magazine with a shop, not a shop with a blog
- Teams already proficient in React and Remix who can maintain the stack long-term
The common thread: headless is justified when your storefront needs to do things that Liquid's rendering model fundamentally cannot support. If you're going headless because you want a nicer developer experience or because someone said it's "more modern," reconsider.
When Hybrid Is the Right Choice
Hybrid is the right architecture for the majority of Shopify stores. If any of these describe your situation, hybrid is almost certainly the better path:
- Most B2C and DTC brands with standard commerce flows
- Teams with existing Liquid expertise
- Stores relying on 5+ Shopify apps for core functionality
- Budget-conscious businesses that need to ship quickly
- Rapid iteration requirements, launch in weeks, not months
- Content teams who need the theme editor for day-to-day updates without developer involvement
The hybrid approach isn't a compromise, it's a deliberately pragmatic choice that leverages Shopify's infrastructure investments (global CDN, theme editor, app ecosystem) while giving you the freedom to build custom interactivity exactly where it adds value.
Migration Paths
You're not locked into either architecture permanently. Migration is possible in both directions, though the effort varies significantly.
Hybrid → Headless: Start by building one page, typically the PDP or collection page, in Hydrogen. Run it alongside the Liquid theme using Shopify's routing capabilities. Gradually migrate page by page, evaluating performance and development velocity at each step. This incremental approach lets you validate the architecture before committing fully.
Headless → Hybrid: Less common, but it happens, usually when teams realize the maintenance burden of headless outweighs its benefits. Extract the design system, rebuild the key templates in Liquid, and re-implement interactive components as JavaScript islands. The transition is typically faster than the original headless build because the design decisions are already made.
Build a proof of concept first. Before committing to either architecture, stand up a Hydrogen storefront or a hybrid theme with one complex feature and evaluate development velocity, deployment workflow, and content editing experience. The best architecture is the one your team can ship and maintain without heroics.
Key Takeaways
- Headless (Hydrogen + Oxygen) gives you total frontend control but costs 3–5x more to build and maintain than hybrid
- Hybrid (Liquid + JavaScript islands) leverages Shopify's CDN, theme editor, and app ecosystem while allowing custom interactivity where needed
- Performance differences are marginal when both approaches are well-implemented, and poorly-built headless is often slower than stock Liquid
- The app ecosystem is the hidden deciding factor: going headless means losing compatibility with most of Shopify's 8,000+ apps
- Team capability matters more than technology preference, headless requires React/Remix/GraphQL expertise
- Checkout, Shopify Functions, and Shopify Plus features work identically in both architectures
- Build a proof of concept before committing to either path
- For most stores, hybrid is the pragmatic choice, reserve headless for when Liquid's rendering model is genuinely insufficient
If your store needs an architecture assessment to determine whether headless or hybrid is the right path, I can help you evaluate the tradeoffs and build a proof of concept. Let's talk about what your commerce model actually needs.