Skip to content

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 lockfile

Why theme/ Subdirectory

Standard Shopify themes place assets/, sections/, templates/, etc. at the project root. Kona nests them under theme/ for several reasons:

  1. Separation of concerns -- Build tooling (vite.config.js, eslint.config.js, node_modules/) stays at the root, Shopify theme files stay in theme/.
  2. Cleaner root -- The project root is not cluttered with Shopify-specific directories alongside config files.
  3. Explicit deploy boundary -- Everything under theme/ (except frontend/) is what gets deployed to Shopify. The Shopify CLI commands use --path theme to 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/:

SourceOutput
entrypoints/theme.jsassets/theme.js
entrypoints/theme.cssassets/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:

ModuleExports
a11y.jstrapFocus, removeTrapFocus, initDisclosureWidgets
events.jsEvents constants, createEvent, listen
utils.jsdebounce, fetchConfig

theme/frontend/styles/

CSS files organized into Tailwind v4 layers:

FileLayerPurpose
theme.css(none)@theme block with design tokens (colors, fonts, spacing)
base.cssbaseElement resets and defaults
components.csscomponentsReusable component styles
utilities.cssutilitiesCustom utility classes

These are imported by entrypoints/theme.css in cascade order:

css
@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:

FileGenerated ByPurpose
theme/snippets/vite-tag.liquidvite-plugin-shopifyLoads JS/CSS assets (dev server in dev, CDN URLs in prod)
theme/snippets/importmap.liquidvite-plugin-shopify-import-mapsES 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

FilePurpose
vite.config.jsVite plugins and build options. See Build Pipeline.
jsconfig.jsonPath alias definitions (@/ and ~/ to theme/frontend/) for editor support.
eslint.config.jsESLint flat config with @eslint/js recommended rules and Prettier compatibility. Ignores theme/assets/.
prettier.config.jsPrettier 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.jsonAll dependencies are devDependencies. Defines dev, build, deploy, lint, format, and docs:* scripts. Uses pnpm as the package manager.