Skip to content

Frontend Architecture

Overview

The frontend uses Inertia.js v3 with Svelte 5 for the public-facing site, and Filament v5 (server-rendered) for the admin panel. All Svelte code follows atomic design principles with a strict stores→services→api layering.

Technology Stack

TechnologyVersionPurpose
Svelte5Component framework (runes: $state, $derived, $effect)
Inertia.js3Server-driven SPA (no client-side routing)
Tailwind CSS4Utility-first styling
LucideLatestIcon library
VitestLatestUnit/integration testing
PlaywrightLatestE2E browser testing
TypeScript5Type safety

Folder Structure

resources/js/
├── components/
│   └── landing/              # Atomic design components
│       ├── atoms/             # Smallest building blocks (Button, Input, Badge, etc.)
│       ├── molecules/         # Composed atoms (Card, Navigation, Pagination, etc.)
│       └── organisms/         # Composed molecules (Form, HeroHeader, MockupPreview, etc.)
├── layouts/                   # Svelte layouts (landing, unauthorized, etc.)
├── lib/                       # Shared utilities
│   ├── i18n.svelte.ts         # Internationalization (i18next)
│   ├── styles/                # Tailwind class constants
│   ├── utils.ts               # Utility functions (cn, sanitize, etc.)
│   ├── state.ts               # StateContainer pattern definition
│   └── localization.ts        # Localized value resolution
├── modules/                   # Feature modules
│   └── landing/
│       ├── setup/             # Setup wizard module
│       └── .../               # Other feature modules
└── pages/                     # Inertia page components
    └── landing/               # Public pages

Atomic Design

atoms/        → Button, Input, Badge, Icon, Modal, Steps, Dropdown, etc.
molecules/    → Card, Navigation, Pagination, MainCard, Mockup, Timeline, etc.
organisms/    → Form, HeroHeader, MockupPreview, SelectorCard, etc.

Rules:

  • Atoms are presentational only — no business logic, no store imports
  • Molecules combine atoms — minimal logic, accept props/callbacks
  • Organisms combine molecules — still presentational, may have internal UI state only
  • Modules contain all business logic — stores, services, API calls

Store Pattern (stores→services→api)

Every data flow follows this chain:

Component (subscribe + call action)

Store (StateContainer<TData> — manages state)

Service (pure functions — business logic)

API (HTTP fetch — typed endpoints)

Module Structure

module/
├── Index.svelte          # Entry point — minimal, no logic
├── api/                  # API fetch functions
├── parts/                # Sub-components
├── services/             # Business logic
├── stores/               # State management
│   └── entry/            # Store groups with barrel index.ts
├── types/                # TypeScript interfaces
└── __tests__/            # Vitest tests

Key Conventions

ConventionRule
Store files<action>-<module>.stores.ts
Service files<module>.service.ts
API files<module>.api.ts
Naming (FE)camelCase (firstName)
Naming (API)snake_case (first_name)
State shapeStateContainer<TData> from @/types/state
ComponentsNO fetch(), NO SSE, NO business logic

Key Files

FilePurpose
resources/js/app.tsSvelte app entry point + Inertia setup
resources/js/lib/i18n.svelte.tsi18n initialization and t() function
resources/js/lib/state.tsStateContainer<TData> type definitions
resources/js/types/state.tsStateMeta, StateErrors, createState()
vite.config.tsVite + Inertia + Wayfinder configuration
tailwind.config.tsTailwind CSS v4 configuration