Project Layout
Kona separates Shopify theme files from build tooling by placing all theme source in a theme/ subdirectory. This keeps the project root clean and makes it clear which files are deployed to Shopify versus which files are part of the development environment.
Directory Tree
kona-theme/
├── theme/ Shopify theme (deployed to store)
│ ├── assets/ Built output + static assets
│ ├── blocks/ 24 Shopify theme blocks
│ ├── config/
│ │ ├── settings_schema.json Theme settings definitions
│ │ └── settings_data.json Current setting values
│ ├── layout/
│ │ └── theme.liquid Main layout template
│ ├── locales/ 60 locale files (30 languages x 2 types)
│ │ ├── en.default.json English storefront translations
│ │ ├── en.default.schema.json English theme editor translations
│ │ ├── fr.json French storefront translations
│ │ ├── fr.schema.json French theme editor translations
│ │ └── ... 28 more languages
│ ├── sections/ 24 Liquid section files
│ ├── snippets/ Reusable Liquid partials + icons
│ │ ├── vite-tag.liquid AUTO-GENERATED by vite-plugin-shopify
│ │ ├── importmap.liquid AUTO-GENERATED by vite-plugin-shopify-import-maps
│ │ ├── header-drawer.liquid Component snippets
│ │ ├── cart-drawer.liquid
│ │ ├── icon-*.liquid SVG icon snippets
│ │ └── ...
│ ├── templates/ 12 JSON templates + 1 Liquid template
│ │ ├── index.json
│ │ ├── product.json
│ │ ├── collection.json
│ │ ├── gift_card.liquid Only Liquid template (Shopify requirement)
│ │ └── ...
│ └── frontend/ Source code (NOT deployed to Shopify)
│ ├── entrypoints/
│ │ ├── theme.js Main JS entry point
│ │ └── theme.css Main CSS entry point
│ ├── islands/ 24 Web Component files
│ │ ├── cart-drawer.js
│ │ ├── header-drawer.js
│ │ ├── product-form.js
│ │ ├── sticky-header.js
│ │ ├── variant-radios.js
│ │ └── ...
│ ├── lib/ Shared utilities
│ │ ├── a11y.js Focus trap, disclosure widget helpers
│ │ ├── events.js Event type constants and helpers
│ │ ├── utils.js debounce, fetchConfig, shared helpers
│ │ └── island-demo.js Demo utilities
│ └── styles/
│ ├── theme.css Tailwind @theme design tokens
│ ├── base.css Base layer styles
│ ├── components.css Component layer styles
│ └── utilities.css Utility layer styles
├── scripts/
│ └── translate-locales.py Locale translation script
├── docs/ VitePress documentation site
│ ├── .vitepress/
│ │ └── config.js VitePress configuration
│ ├── architecture/ Architecture docs (this section)
│ └── ...
├── vite.config.js Vite build configuration
├── package.json Dependencies and scripts
├── jsconfig.json Path aliases for editor intellisense
├── eslint.config.js ESLint flat config
├── prettier.config.js Prettier config (Liquid + JS + CSS)
└── pnpm-lock.yaml Dependency lockfileWhy theme/ Subdirectory
Standard Shopify themes place assets/, sections/, templates/, etc. at the project root. Kona nests them under theme/ for several reasons:
- Separation of concerns -- Build tooling (
vite.config.js,eslint.config.js,node_modules/) stays at the root, Shopify theme files stay intheme/. - Cleaner root -- The project root is not cluttered with Shopify-specific directories alongside config files.
- Explicit deploy boundary -- Everything under
theme/(exceptfrontend/) is what gets deployed to Shopify. The Shopify CLI commands use--path themeto target this directory.
The themeRoot: './theme' option in the Vite plugins tells them where to find the Shopify theme structure.
Key Directories Explained
theme/frontend/
This is the source code directory. It contains all JavaScript, CSS, and Web Component files that Vite processes. It is not deployed to Shopify -- only its compiled output in theme/assets/ is deployed.
The sourceCodeDir: 'theme/frontend' option in vite-plugin-shopify tells the plugin where entry points and source files live.
theme/frontend/entrypoints/
Files in this directory become Vite entry points. Each file produces a corresponding output in theme/assets/:
| Source | Output |
|---|---|
entrypoints/theme.js | assets/theme.js |
entrypoints/theme.css | assets/theme.css |
theme/frontend/islands/
Each .js file defines one Web Component. The filename maps directly to the custom element tag name. See Islands Architecture for details.
theme/frontend/lib/
Shared modules imported by islands and entry points:
| Module | Exports |
|---|---|
a11y.js | trapFocus, removeTrapFocus, initDisclosureWidgets |
events.js | Events constants, createEvent, listen |
utils.js | debounce, fetchConfig |
theme/frontend/styles/
CSS files organized into Tailwind v4 layers:
| File | Layer | Purpose |
|---|---|---|
theme.css | (none) | @theme block with design tokens (colors, fonts, spacing) |
base.css | base | Element resets and defaults |
components.css | components | Reusable component styles |
utilities.css | utilities | Custom utility classes |
These are imported by entrypoints/theme.css in cascade order:
@import 'tailwindcss' source('../..');
@import '@/styles/theme.css';
@import '@/styles/base.css' layer(base);
@import '@/styles/components.css' layer(components);
@import '@/styles/utilities.css' layer(utilities);theme/locales/
Contains 60 locale files: 30 languages with both storefront translations (e.g., fr.json) and theme editor schema translations (e.g., fr.schema.json). The en.default.json and en.default.schema.json files are the source of truth; other languages are generated by the translation script.
theme/templates/
12 JSON templates and 1 Liquid template. JSON templates define which sections appear on each page type and are editable through Shopify's theme editor. The sole Liquid template (gift_card.liquid) exists because Shopify requires it for gift card pages.
Auto-Generated Files
Two snippet files are generated by Vite plugins and should never be edited manually:
| File | Generated By | Purpose |
|---|---|---|
theme/snippets/vite-tag.liquid | vite-plugin-shopify | Loads JS/CSS assets (dev server in dev, CDN URLs in prod) |
theme/snippets/importmap.liquid | vite-plugin-shopify-import-maps | ES module import map for bare specifiers |
These files are regenerated every time the dev server starts or a production build runs.
WARNING
Do not add these files to .gitignore. They need to be committed because Shopify reads them from the theme files when rendering pages. They are checked into version control but should not be manually modified.
Configuration Files
| File | Purpose |
|---|---|
vite.config.js | Vite plugins and build options. See Build Pipeline. |
jsconfig.json | Path alias definitions (@/ and ~/ to theme/frontend/) for editor support. |
eslint.config.js | ESLint flat config with @eslint/js recommended rules and Prettier compatibility. Ignores theme/assets/. |
prettier.config.js | Prettier with @shopify/prettier-plugin-liquid and prettier-plugin-tailwindcss. Liquid files use double quotes, semicolons, 120 char width. JS files use single quotes, no semicolons, 80 char width. |
package.json | All dependencies are devDependencies. Defines dev, build, deploy, lint, format, and docs:* scripts. Uses pnpm as the package manager. |