Skip to content

Project structure

A freshly scaffolded theme is a standard Vite + React Router 7 project:

my-theme/
├── app/
│ ├── root.tsx # App shell (layout, meta, error boundary)
│ ├── routes.ts # The route map
│ ├── routes/
│ │ ├── home.tsx # Shop + product grid
│ │ ├── product.tsx # PDP with variant selection
│ │ ├── collection.tsx # Collection page
│ │ ├── collections-index.tsx
│ │ ├── localization.tsx
│ │ └── $.tsx # Catch-all (404)
│ ├── sections/
│ │ └── hero.tsx # Example settings-as-data section (typed `schema` export)
│ ├── graphql/
│ │ └── queries.ts # Storefront API queries (#graphql documents)
│ └── entry.server.tsx
├── workers/
│ └── app.ts # Cloudflare Worker entry — builds the per-request Kotao context
├── kotao.theme.json # Theme manifest (validated by the platform build)
├── .dev.vars # Local credentials (gitignored; see .dev.vars.example)
├── react-router.config.ts
├── vite.config.ts
└── wrangler.jsonc

workers/app.ts is the entry the platform runs. It builds the per-request Kotao context — your route loaders reach the Storefront API through context.storefront (the SDK client) and geo data through context.geo.

app/routes/*.tsx are ordinary React Router routes. Loaders fetch data through context.storefront; the product page uses getProductOptions / getSelectedVariant from @kotao/storefront/product for variant selection.

app/sections/hero.tsx shows the settings-as-data pattern: a section component exporting a typed schema that merchants can configure in the Workspace editor.

app/graphql/queries.ts holds your #graphql documents. bun run codegen generates typed results from your Storefront API (app/graphql/storefrontapi.generated.d.ts).

kotao.theme.json is the theme manifest. The platform’s build validates it on every deploy — keep it committed.

Command What it does
bun run dev Local dev server in workerd (vite dev).
bun run build Production build (vite build).
bun run codegen Typed GraphQL from your #graphql documents.
bun run publish Package committed source + publish to your selected storefront.
bun run typecheck React Router typegen + tsc.