Skip to content

Project Structure

Jon Imms edited this page Jun 25, 2026 · 1 revision

Project Structure

A guided tour of the two trees you will work with: the anatomy of a generated theme and the layout of the StrataWP monorepo.

This page maps every directory and file to its purpose, and tells you when you actually touch it. For conceptual background, see Core Concepts; for the commands that scaffold these files, see the CLI Reference.

Note The examples below mirror the bundled Basic Theme (examples/basic-theme), which is the template npx create-stratawp copies for new projects. The Advanced and Store themes share the same skeleton and add their own directories — see Example Themes.


1. Anatomy of a generated theme

When you run npx create-stratawp my-theme and pick the Basic template, you get a WordPress block theme (FSE) wired for TypeScript and Vite. Here is the full tree with annotations.

my-theme/
├── functions.php          # Theme entry point. Checks PHP >= 8.1, loads the Composer
│                          #   autoloader, boots a StrataWP\Theme with its component
│                          #   array, and injects the Vite dev client in local dev.
│                          #   You edit this to add/remove components.
├── style.css              # WordPress theme header (Name, Version, Text Domain, Tags).
│                          #   Intentionally minimal — real styles load via Vite.
├── theme.json             # FSE configuration: color palette, typography, spacing,
│                          #   layout, and template-part areas. The source of truth
│                          #   for editor presets. Edit constantly while designing.
├── composer.json          # PHP dependencies (requires stratawp/core) + PSR-4
│                          #   autoload mapping ("StrataBasic\\": "inc/").
├── package.json           # Node deps + scripts: dev, build, preview, typecheck.
├── tsconfig.json          # TypeScript config (extends repo root; WordPress JSX runtime).
├── tsconfig.typecheck.json # Stricter TS config used by the `typecheck` script.
├── vite.config.ts         # Vite + @stratawp/vite-plugin setup: block auto-register,
│                          #   PHP HMR watch globs, WordPress asset manifest, dev port.
│
├── index.php              # Minimal PHP fallback required by WordPress.
├── header.php             # Classic PHP header (used by parts that opt into PHP markup).
├── footer.php             # Classic PHP footer counterpart.
│
├── inc/                   # PHP source (PSR-4 autoloaded, namespace from composer.json).
│   ├── Components/        # Theme-specific PHP components you author.
│   │   ├── Navigation.php #   Each implements ComponentInterface (get_slug + initialize).
│   │   └── Customizer.php
│   ├── blocks-generated.php       # AUTO-GENERATED block registration. Do not edit —
│   │                              #   regenerated by the Vite plugin from block.json files.
│   ├── lazy-loading-generated.php # AUTO-GENERATED performance helper. Do not edit.
│   └── preload-generated.php      # AUTO-GENERATED resource-hint helper. Do not edit.
│
├── src/                   # TypeScript / React / styles — the build source Vite compiles.
│   ├── blocks/            # Gutenberg blocks. One folder per block (auto-discovered).
│   │   └── hero/
│   │       ├── block.json          # Block metadata (apiVersion 3, name, attributes,
│   │       │                       #   render/editorScript/style file refs).
│   │       ├── block-attributes.ts # Typed attribute definitions (shared TS types).
│   │       ├── edit.tsx            # React edit component (editor UI).
│   │       ├── render.php          # Server-side render for dynamic blocks (frontend).
│   │       └── style.css           # Block styles.
│   ├── js/                # JS/TS entry points referenced by vite.config.ts.
│   │   ├── main.ts        #   Frontend bundle entry.
│   │   └── editor.ts      #   Block-editor bundle entry.
│   ├── css/               # Plain-CSS entries (main.css, editor.css).
│   ├── scss/              # Sass partials compiled into the theme stylesheet.
│   │   ├── main.scss      #   Imports the partials below.
│   │   ├── _variables.scss  _reset.scss  _typography.scss  _header.scss
│   │   ├── _navigation.scss _content.scss _footer.scss _forms.scss
│   │   └── _utilities.scss
│   └── icons/             # Icon-font workspace (see `stratawp icons:*` commands).
│       ├── README.md
│       └── fonts/         # Generated icon-font output lands here.
│
├── patterns/             # Block patterns as PHP files (register on init).
│   ├── header-default.php  footer-default.php  ...
│   └── *-dark.php         # Dark-mode variants live alongside light ones.
│
├── parts/                # Template parts referenced by templates.
│   ├── header.html       #   Block-markup parts (preferred for FSE).
│   ├── footer.html
│   ├── content.php       #   PHP parts when dynamic logic is needed.
│   └── content-none.php
│
├── templates/            # FSE templates (HTML block markup, edited in the Site Editor).
│   ├── index.html  home.html  single.html  page.html  archive.html
│   └── search.html  404.html  blank.html  no-title.html
│
├── __tests__/            # Vitest unit tests (example-block.test.tsx).
├── e2e/                  # Playwright E2E + accessibility specs.
│   ├── block-editor.spec.ts
│   └── a11y/frontend.spec.ts
│
├── playwright.a11y.config.ts  # Accessibility test runner config.
├── phpcs.xml.dist             # PHP_CodeSniffer ruleset.
└── screenshot.png             # Theme screenshot shown in WordPress → Themes.

Note After installing dependencies you also get vendor/ (Composer) and node_modules/ (pnpm). Both are generated and git-ignored.

Which files do you actually touch?

When you want to… Edit…
Add or remove a theme feature functions.php (the new Theme([...]) component array)
Define colors, fonts, spacing, layout theme.json
Build a custom block src/blocks/<name>/ (scaffold with stratawp block:new)
Add PHP logic / a component inc/Components/ (scaffold with stratawp component:new)
Style the theme src/scss/ (and per-block style.css)
Add a reusable layout patterns/ (PHP files)
Add a page/post/archive template templates/ (scaffold with stratawp template:new)
Add a header/footer/sidebar part parts/ (scaffold with stratawp part:new)
Change build inputs, ports, HMR globs vite.config.ts
Update the theme header (name, version) style.css

Warning Never hand-edit inc/*-generated.php. Files named *-generated.php are produced by @stratawp/vite-plugin from your block.json files and configuration, and are overwritten on the next build or dev run. Each begins with a "Do not edit this file manually" banner.

Key files in detail

functions.php — the boot file. It first guards on PHP_VERSION (requiring 8.1 or higher via version_compare / wp_die), then loads vendor/autoload.php, constructs a StrataWP\Theme with an array of components, and calls $theme->initialize() on after_setup_theme. Built-in components used by the Basic Theme are Setup, Assets, Blocks, Performance, Accessibility, ConditionalStyles, CriticalCss, Fonts, Icons, and Updates, plus theme-local Navigation and Customizer. The Updates component is constructed with the GitHub repo slug and release asset (new Updates( 'JonImmsWordpressDev/strataWP', 'strata-basic.zip' )) to enable self-hosted theme updates. The file also injects the Vite client into wp_head during local development, dequeues compiled assets while the dev server is running, and registers this theme's block-pattern categories on init.

vite.config.ts — the build brain. It registers @vitejs/plugin-react and the strataWP() plugin, which controls three things you may tune:

strataWP({
  blocks: { dir: 'src/blocks', autoRegister: true, namespace: 'strata-basic' },
  phpHmr: { enabled: true, watch: ['**/*.php', 'theme.json', 'templates/**/*', 'parts/**/*'] },
  manifest: { enabled: true, wordpress: true },
})

The dev server runs on port 3000 (strictPort: true). See Architecture & Packages for how the plugin generates the WordPress asset manifest.

src/blocks/<name>/block.json — block metadata using apiVersion: 3. The render, editorScript, and style fields point at sibling files (render.php, edit.tsx, style.css). Because autoRegister is on, dropping a new block.json here is enough for the plugin to discover and register the block — no manual PHP wiring.

theme.json — the FSE settings/styles document. When you run stratawp design-system:setup tailwind (or unocss), your design tokens are mapped into WordPress presets here. See Blocks, Patterns & Design Systems.

Tip Block patterns in patterns/ are PHP templates, not live references: once inserted into a page, their evaluated HTML is copied into the post. Editing the pattern file later does not update pages that already used it — re-insert the pattern to refresh.


2. The StrataWP monorepo layout

If you cloned the repository to contribute (or to read the source), this is what you are looking at. It is a Turborepo + pnpm workspaces monorepo; the workspace globs are packages/* and examples/* (see pnpm-workspace.yaml).

StrataWP/                      # root package: @stratawpji/root (private, v2.0.0)
├── package.json               # Root scripts (turbo dev/build/test/typecheck, lint,
│                              #   format, release via Changesets, contracts:* checks).
├── pnpm-workspace.yaml        # Declares the packages/* and examples/* workspaces.
├── turbo.json                 # Turborepo task pipeline (build, dev, test, lint, ...).
├── tsconfig.json              # Base TS config inherited by packages and examples.
├── eslint.config.js           # Flat ESLint config (ESLint 9).
├── .prettierrc                # Prettier formatting rules.
├── .lighthouserc.cjs          # Lighthouse CI config (used by `pnpm test:perf`).
│
├── packages/                  # Published + internal framework packages.
│   ├── core/                  # @stratawp/core — PHP framework (Composer: stratawp/core).
│   │                          #   ComponentInterface, StrataWP\Theme, built-in components.
│   ├── cli/                   # @stratawp/cli (v2.0.0) — provides the `stratawp` bin;
│   │                          #   scaffolding, deploy, sync, design-system, icons, etc.
│   ├── create-stratawp/       # create-stratawp (v0.5.2) — `npx` project bootstrapper.
│   ├── vite-plugin/           # @stratawp/vite-plugin (v0.2.0) — HMR, block auto-discovery,
│   │                          #   PHP watch/reload, WordPress asset manifest.
│   ├── explorer/              # @stratawp/explorer (v0.7.0) — component browser
│   │                          #   (Storybook-style) with REST API + WebSocket.
│   ├── headless/              # @stratawp/headless (v0.8.0) — REST client, React hooks,
│   │                          #   Next.js integration. Subpath exports ./react, ./next.
│   ├── sync/                  # @stratawp/sync (v0.1.0) — DB dump/restore, URL replace,
│   │                          #   snapshots, diff engine, rollback.
│   ├── testing/               # @stratawp/testing (v0.1.0) — Vitest + Playwright helpers,
│   │                          #   WordPress mocks, custom matchers, shared configs.
│   └── mcp/                   # @stratawp/mcp (v0.1.0) — MCP server exposing generators
│                              #   and the component catalog to AI agents.
│
├── examples/                  # Reference themes (also dev fixtures for the packages).
│   ├── basic-theme/           # General purpose (blogs, portfolios, business).
│   ├── advanced-theme/        # Custom post types and extended functionality.
│   └── store-theme/           # WooCommerce-optimized store theme.
│
├── docs/                      # Canonical in-repo documentation.
│   ├── deployment/            # getting-started.md, ADVANCED-DEPLOYMENT.md
│   ├── agent-skills/          # Bundled WordPress agent skills (README + guides).
│   ├── fonts.md               # Typography / Google Fonts guide.
│   ├── assets/                # Doc images.
│   ├── plans/  superpowers/   # Planning + workflow notes.
│
├── scripts/                   # Repo maintenance scripts (Node ESM).
│   ├── lint-php.mjs           # `pnpm lint:php`
│   ├── extract-critical.mjs   # Critical-CSS extraction (`pnpm extract:critical`)
│   ├── check-contracts.mjs    validate-contracts.mjs  check-types-drift.mjs
│   └── wait-for-http.mjs
│
├── README.md  GETTING_STARTED.md  CHEAT_SHEET.md  CHANGELOG.md
├── CONTRIBUTING.md  ROADMAP.md  CLAUDE.md  LICENSE
└── .github/                   # CI workflows and repo config.

Note Package versions shown above are read from each package's package.json. @stratawp/core is a Composer package (stratawp/core) with no semver in a Node manifest. The "Published Packages" list in the README covers cli, vite-plugin, sync, testing, headless, and explorer; core and mcp ship with the repo.

Where to look when…

You are… Start in…
Adding a CLI command or generator packages/cli/
Changing how blocks/assets are built packages/vite-plugin/
Working on the PHP theme runtime packages/core/
Improving the component browser packages/explorer/
Building headless/Next.js features packages/headless/
Touching deploy / DB sync / rollback packages/sync/ and packages/cli/
Exposing tools to AI agents packages/mcp/
Reproducing a bug against a real theme examples/basic-theme/
Writing docs docs/

Running things across the monorepo

From the repo root, Turborepo fans tasks out across workspaces:

pnpm install     # install all workspace dependencies
pnpm dev         # turbo dev — run every package in watch mode
pnpm build       # turbo build — build all packages (respects ^build order)
pnpm test        # turbo test
pnpm lint        # eslint .

To work inside a single example theme:

cd examples/basic-theme
pnpm dev         # Vite dev server on http://localhost:3000 with HMR

Tip Releases are managed with Changesets (pnpm changeset, pnpm version-packages, pnpm release). See Contributing & Releases for the full workflow, and Architecture & Packages for how the packages depend on one another.


Related pages

Clone this wiki locally