Shopify 가 테마 구조를 다시 읽기 쉬운 코드로 전환하는 이유 — 그리고 이것이 개발자, 판매자, 그리고 에이전트에게 제공하는 것.
정확히 12년 전 오늘, 저는 첫 번째 Shopify 스토어를 구축하기 시작했습니다.
저는 엄밀히 말해 개발자는 아니었습니다. HTML, CSS, 그리고 약간 위험할 정도로만 jQuery를 다룰 줄 아는 기술에 능통한 디자이너였죠. 제가 원한 것은 제가 구축 중인 브랜드에 완전히 맞춤화된 스토어프론트였지만, 그걸 위해 전체 커머스 스택을 관리하고 싶지는 않았습니다.
그때 Shopify를 발견했습니다.
Timber를 다운로드하고, 컬렉션 템플릿을 열었을 때 모든 것이 이해되기 시작했습니다:
1{% for product in collection.products %}2 {% include 'product-grid-item' %}3{% endfor %}
전체 템플릿은 100줄의 코드였습니다. 코드를 읽기만 해도 어떻게 작동하는지 이해할 수 있었습니다. Mark Dunkley 의 치트 시트 외에는 문서가 거의 필요하지 않았습니다.
테마 개발자에게는 가독성의 황금기였습니다. 판매자에게는 전역 테마 설정만으로는 확실히 충분하지 않았습니다.
우리가 감수한 트레이드오프
테마 설정만으로는 한계가 있었습니다. 2016년, Shopify는 Sections을 도입했고, 세 가지가 동시에 변화했습니다.
- 판매자는 머천다이저가 되었습니다. 코딩을 할 줄 모르는 사람도 페이지를 구성하고 훨씬 풍부한 제품 스토리를 전달할 수 있게 되었습니다.
- 개발자는 컴포넌트 디자이너가 되었습니다. Sections은 모듈식이어야 하고, 유연해야 하며, 어떤 순서로든 작동해야 했습니다.
- 그리고 테마는 제품이 되었습니다. 개발자는 자신이 만드는 인터페이스에 대해 고민하고, 사용 편의성과 유연성 사이에서 신중한 트레이드오프를 해야 했습니다.
이러한 변화는 2016년 Dawn, 그리고 작년 Horizon과 함께 '블록'이 테마의 핵심 구성 가능 단위로 도입되면서 더욱 가속화되었습니다.
모든 템플릿에 걸쳐 섹션과 블록을 표현하기 위해 Shopify는 직렬화 형식이 필요했습니다. 템플릿은 JSON으로 전환되었습니다.
이 트레이드오프는 판매자에게 훨씬 더 많은 제어권을 주었지만, 개발자 경험 측면에서 비용이 발생했습니다: 더 이상 하나의 파일을 읽어서 페이지를 이해할 수 없게 된 것입니다. 페이지가 어떻게 작동하는지 재구성하기 위해 JSON, Liquid, 스키마, 설정, 섹션, 블록을 상호 참조해야 했습니다.
템플릿이 JSON이 되는 순간, 더 이상 훌륭한 개발자 표면이 아니게 되었습니다. 자동 저장된 출력물이 되었고, 우리는 개발자에게 수동으로 편집하지 말라고 경고하기까지 했습니다.
이는 "명령형 소프트웨어" 시대에는 합리적인 트레이드오프였습니다. 판매자가 버튼, 노브, 설정을 통해 무엇을 변경해야 하는지 정확히 지정하여 스토어를 구성하는 시대였죠.
AI가 이 방정식을 바꿉니다.
훌륭한 개발자 경험은 훌륭한 에이전트 경험입니다
Sidekick 에 테마 편집 기능을 부여했을 때, 온라인 스토어 편집기는 "선언형 소프트웨어" 시대에 접어들었습니다. 간단한 예로, 색상 선택기를 열고 \[#0000FF](https://x.com/search?q=%230000FF&src=hashtag_click)\를 선택하는 대신, 판매자는 "이것을 파란색으로 만들어 줘"라고 말하기만 하면 됩니다.
판매자는 올해 이미 2500만 번의 Sidekick 테마 편집을 수행했으며, 5명 중 1명의 판매자가 AI를 사용하여 테마를 편집하고 있습니다.
동시에, 개발자들은 점점 더 에이전트를 사용하여 코드를 작성하고 있습니다. 이는 Shopify 에게 두 가지 연결된 과제를 제시합니다:
- 에이전트에게 더 나은 지침을 제공하세요.
- 에이전트에게 더 나은 피드백을 제공하세요.
지침을 위해, 우리는 개선된 Liquid 스킬을 출시하고 있습니다. 테마는 \.agents\ 디렉토리를 통해 에이전트 지침을 전달할 수 있으며, \AGENTS.md\ 및 \DESIGN.md\와 같은 파일을 포함하여 코딩 에이전트가 코드를 작성하는 방법과 디자인을 브랜드에 맞게 유지하는 방법을 이해하도록 도울 수 있습니다.
피드백을 위해, 우리는 \{% doc %}\ 태그를 스니펫과 블록을 위한 타입화된 계약으로 확장했습니다. 매개변수는 문서화되고, 타입이 지정되며, Theme Check 에 의해 검증되고, 사용 방법에 대한 예제와 함께 제공될 수 있습니다.
1{% doc %}2 @param {string} [variant]3 @param {string} [tag]45 @example6 {% block 'text', tag: 'h1' %}7 Featured Collection8 {% endblock %}9{% enddoc %}
손으로 코드를 작성할 때 이는 실시간 피드백, 인텔리센스, 오류를 제공합니다. 또한 에이전트에게 유효한 매개변수를 발견하고, 좋은 출력이 어떤 모습인지 학습하며, 존재하지 않는 API를 환각(hallucinate)할 때 실행 가능한 피드백을 받을 수 있는 방법을 제공합니다.
또한 계약, 구조, 검증, 복잡성, 중첩 및 파일 크기 제한을 다루는 20개의 새로운 Theme Check 규칙을 추가했습니다.
에이전트 시대에 저와 같은 개발자에게 놀라운 점은 이것이 우리가 항상 원했던 것, 즉 가독성 있는 코드, 명시적인 계약, 그리고 빠른 피드백을 보상한다는 것입니다.
그래서 우리는 더 큰 질문을 던졌습니다: 이러한 특성을 핵심 원칙으로 삼는다면 이상적인 테마 아키텍처는 어떻게 생겼을까?
우리는 모든 아이디어를 하나로 모은 새로운 Shopify 기본 테마를 구축해 왔습니다.
(말씀드리자면… 이것은 코딩 에이전트를 최적화하기 위한 새로운 아키텍처이지만, 강제적인 재작성은 아닙니다. 기존 테마는 계속해서 영원히 작동할 것입니다; Liquid 는 항상 영원한 API 였고 앞으로도 그럴 것입니다.)
페이지 구조가 다시 읽을 수 있는 코드가 됩니다
새로운 테마에서 가장 먼저 눈에 띄는 것은 \templates\ 디렉토리를 열었을 때입니다. 템플릿이 다시 Liquid 파일입니다.
컬렉션 템플릿의 길이는 대략 Timber 와 비슷하며, 전체 테마는 Horizon 보다 코드 줄 수가 93% 적습니다. 이것은 Horizon 과 같은 모든 기능이 포함된 테마를 의미하는 것이 아닙니다. Shopify 의 모든 커머스 프리미티브를 사용하여 구축하기 쉽게 만들고 최상의 성능을 얻기 위한 기반을 마련하는 것이 목적이지만, 각 판매자의 스토어를 독특하게 만드는 모든 것을 구축하는 것은 여러분에게 맡깁니다.
페이지 구조를 다시 Liquid 로 옮기는 이유는 무엇일까요?
직렬화된 구성의 더 깊은 문제는 JSON 자체가 본질적으로 나쁘다는 것이 아닙니다. 구성이 제한된 어휘를 가지고 있다는 것입니다. 테마 개발자는 판매자가 원할 수 있는 구성을 예측해야 합니다.
버튼 하나를 포함하는 섹션을 상상해보세요. 판매자가 에이전트에게 그 옆에 두 번째 버튼을 추가하도록 요청합니다.
설정 기반 아키텍처에서 테마는 두 버튼을 모두 담을 수 있는 그룹 블록을 이미 노출해야 하거나, 개발자가 두 번째 버튼 설정을 예측했어야 합니다.
HTML에서는 다른 버튼을 추가하고 두 버튼을 \div\로 감쌉니다.
모든 주요 모델은 이미 HTML을 이해합니다. HTML은 표현력이 풍부하고, 지역적이며, 토큰 효율적입니다. 그리고 Shopify는 20년 넘게 이러한 표현력을 커머스와 결합하는 데 필요한 언어인 Liquid를 가지고 있었습니다.
블록과 HTML, 함께
새로운 아키텍처는 Liquid 템플릿 내에서 직접 사용할 수 있는 구성 가능한 \{% block %}\ 태그를 도입합니다.
1<div class="mb-8">2 {% block 'text',3 tag: 'h1',4 block.settings.variant: 'type-heading-xl',5 class: 'mb-2'6 %}7 {{ collection.title | escape }}8 {% endblock %}9</div>
블록은 명명된 매개변수를 허용합니다. 중첩된 콘텐츠를 포함할 수 있습니다. 해당 매개변수는 \{% doc %}\를 통해 타입을 지정할 수 있습니다. 블록은 판매자가 상호 작용할 수 있는 경계를 정의하고, 일반 HTML은 나머지를 처리합니다.
React 와 같은 컴포넌트 시스템을 사용해 본 적이 있다면 이 모델이 익숙하게 느껴질 것입니다. 매개변수는 props 처럼 동작하고, 중첩된 콘텐츠는 children 처럼 동작합니다. 하지만 여전히 Liquid로, 하나의 파일에서 위에서 아래로 읽기에 충분히 간단합니다.
이를 통해 모든 마크업 조각을 또 다른 섹션, 블록 또는 설정으로 만들지 않고도 명시적인 구성을 가능하게 합니다.
부분(partials)을 통한 세분화된 반응성
테마 개발자는 Section Rendering API 를 원래 설계 목적을 훨씬 넘어 확장해 왔습니다. 그것이 서버 기반 반응성을 위한 가장 좋은 도구였기 때문입니다.
우리는 더 정밀한 것을 원했습니다.
선언적 부분 업데이트에 대한 새로운 접근 방식에서 영감을 받아, 우리는 Liquid 에 부분(partials) 이라는 간단한 프리미티브를 도입합니다.
다시 렌더링할 수 있는 영역을 감싸세요:
1{% partial 'cart-count' %}2 <span>3 {{ 'cart.count' | t: count: cart.item_count }}4 </span>5{% endpartial %}
그런 다음 새 HTML을 가져와 필요한 곳에 적용합니다:
1const html = await partials.fetch('cart-items', 'cart-count');2partials.apply(html);
그게 전부입니다. 전체 섹션을 렌더링하거나 가상 DOM을 도입하지 않고도 세분화된 서버 렌더링 업데이트가 가능합니다.
장바구니에 추가하는 것은 몇 줄의 코드로 관련 장바구니 영역을 업데이트할 수 있습니다. 이 하나의 프리미티브를 통해 Horizon에서 수천 줄의 반응성 코드를 제거할 수 있을 것입니다.
표준 이벤트 및 액션
또한 일반적인 스토어프론트 상호 작용을 더 간단하고 상호 운용 가능하게 만들고 있습니다.
표준 액션(Standard Actions)은 장바구니 업데이트와 같은 작업에 대한 공유 계약을 제공합니다. 표준 이벤트(Standard Events)는 테마와 앱이 동일한 안정적인 어휘를 통해 반응할 수 있도록 합니다.
1const { cart } = await Shopify.actions.updateCart({2 lines: [{3 merchandiseId: variant.id,4 quantity: 1,5 }],6});
이는 개발자가 작성하기 더 쉽고, 앱이 통합하기 더 쉬우며, 에이전트가 이해하기 더 쉽습니다. 표준 액션은 오늘날 모든 Shopify 스토어에서 작동하며, WebMCP 지원은 브라우저 에이전트가 제품을 탐색하고 추가할 수 있는 의미론적 경로를 제공하는 동시에 스토어프론트가 해당 상호 작용에 응답합니다.
목표는 스토어프론트에 "AI 모드"를 덧붙이는 것이 아닙니다. 스토어프론트의 기능을 테마, 앱, 개발자 및 에이전트 등 모든 참여자에게 명확하고 구성 가능하게 만드는 것입니다.
Liquid 의 안전한 진화
Liquid 에 추가하고 싶었던 몇 가지 명백한 언어 기능도 있었습니다: 부울 표현식, 우선순위를 가진 중위 연산자, 리터럴 배열 및 객체입니다.
장애물은 의욕 부족이 아니었습니다. Liquid 의 기존 파서는 형식적으로 유효하지 않은 모호한 구문을 허용했습니다. 따라서 새로운 구문을 도입하면 기존 테마의 동작 방식이 변경될 수 있었습니다.
팀은 테마를 엄격한 파서로 안전하게 마이그레이션하기 위한 주요 작업을 수행했습니다. 이 작업은 이미 이에 의존하는 스토어프론트를 손상시키지 않으면서 Liquid 를 진화시킬 수 있는 여지를 제공합니다.
이는 더 간단하고 친숙한 표현식을 가능하게 합니다:
1{{ 1 + 1 }}2{{ false && false || true }}3{% assign products = ["shirt", "hat", "shoes"] %}
또한 개발자와 에이전트 모두에게 오류를 더 예측 가능하게 만듭니다.
한 가지 더: Tailwind
곧, 우리는 Liquid 테마에 Tailwind 지원을 제공할 예정입니다.
에이전트는 Tailwind 를 아주 잘 다룹니다. 개발자는 이미 이해하고 있습니다. 그리고 Tailwind 는 복잡한 빌드 시스템을 판매자에게 강요하지 않으면서 디자인 토큰을 중심으로 구축된 공유 스타일링 언어를 제공합니다.
이러한 공유 어휘는 중요합니다. 에이전트가 구조, 계약 및 스타일링 의도를 더 잘 이해할수록 개발자는 브랜드를 실제로 차별화하는 스토어프론트 부분에 더 집중할 수 있습니다.
미래로의 회귀
12년 전, 테마를 열고 코드를 읽고 스토어를 이해할 수 있었기 때문에 Shopify 가 저에게 와닿았습니다.
시간이 지나면서 우리는 테마를 판매자에게 훨씬 더 유연하게 만들었지만, 코드는 이해하기 더 어려워졌습니다.
에이전트는 이 두 가지, 즉 판매자에게 필요한 유연성과 개발자가 마땅히 누려야 할 가독성을 다시 결합할 기회를 제공합니다.
이것이 이 새로운 아키텍처의 방향입니다:
- 읽기 쉬운 페이지 구조로서의 Liquid 템플릿.
- 일반 HTML과 함께 사용되는 구성 가능하고 타입이 지정된 블록.
- 에이전트 스킬 및 저장소 수준의 지침.
- \
{% doc %}\및 Theme Check 를 통한 풍부한 피드백. - 부분(partials)을 통한 세분화된 반응성.
- 표준 이벤트 및 액션을 통한 공유 스토어프론트 계약.
- Liquid 가 안전하게 진화할 수 있도록 하는 엄격한 파서.
- 공통 스타일링 언어로서의 Tailwind.
개발자 프리뷰와 문서는 지금 바로 이용 가능합니다:
https://shopify.dev/docs/storefronts/themes/getting-started/developer-preview
한번 사용해보시고, 피드백을 보내주세요. 여러분이 무엇을 만들지 정말 기대됩니다!





![[메모] 성과가 낮은 부하 직원을 배제하는 상사들](https://youmind.club/__ym/cms-assets/media/1784827522698_408j7z_HN3Kb76awAAvvjF.jpg)