Project Structure

What Thunder UI manages, what belongs to you, and why src/core/ must never be edited.

Inside a Thunder Framework project the app lives at public/app/, and the SDK it links to at public/www/sdk@<version>/.

Thunder UI draws one clear line through the app: src/core/ is managed, everything else is yours. Understanding that line is the difference between an app that updates cleanly and one that loses work on every sync.

router.tsx
protected.tsx
types.ts
registry.ts
icons.tsx
layouts.ts
routes.tsx
index.css
App.tsx
main.tsx
i18n.ts
.env
.env.example
capacitor.config.ts

Managed by Thunder UI

PathContents
src/core/router.tsxBuilds every route from SDK metadata
src/core/protected.tsxAuth gate (OIDC or cookie session)
src/core/types.tsThe override contracts
src/core/crud/ListPage, FormPage, ViewPage, filters, field renderers
src/core/layouts/The navbar, sidebar, mobile and native shells, plus registry.ts
src/core/custom/Composite components (RefSelect, Datatable, …)
src/core/lib/jsonSchemaToFields, utils, feature flags, constants
src/core/locals/Thunder UI's own translations
src/core/pages/Built-in pages (overview, wallet, users, notifications)
src/core/styles/Mechanics only: keyframes, utilities, fonts

Yours

PathContents
src/overrides/Registries that replace generated screens, icons, layouts and routes
src/pages/Your pages
src/components/Your components plus the shadcn/ui primitives
src/hooks/, src/lib/Your hooks and helpers
src/locals/Your translations, merged over core's
src/index.cssYour theme tokens
src/App.tsxRoute tree and layout wiring
src/main.tsx, src/i18n.tsApp entry and i18next setup

Also in the repository: android/ and ios/ (the committed Capacitor projects) and capacitor.config.ts.

www/ is the web build output and is gitignored - it is a build artifact, produced by generate:app on install and by npm run build afterwards. The .env files, by contrast, are committed deliberately.

Never Edit src/core/

src/core/ is replaced wholesale when a developer runs:

deno task generate:app --forceSync

That command swaps in the latest Thunder UI and leaves everything else untouched. It is how fixes and security patches reach an existing project without discarding your work - and it is why any manual change inside src/core/ will be lost, every time, with no warning and no prompt.

The only time editing src/core/ is acceptable is while experimenting or debugging locally. Treat such edits as throwaway.

Build on top instead:

  • Add pages in src/pages/, components in src/components/, helpers in src/lib/.
  • Register replacements for generated screens in src/overrides/.
  • Wrap or compose core utilities in your own modules.

Everything outside src/core/ survives every update.

The Same Split, in CSS

The ownership boundary repeats itself in the stylesheets:

  • src/index.css is yours - OKLCH colour variables, radii and font stacks.
  • src/core/styles/index.css is core's - mechanics only: @property declarations, keyframes, scroll-mask utilities. No tokens.

Restyle freely; core still ships new utilities; neither side loses work on sync. See Layouts & Theming.


On this page