Configurator Architecture Principles

Overview of framework-agnostic design and organization patterns for interactive configurators.
Published: 7/20/2026

Interactive 3D configurator frontends require clean separation of spatial bindings, application state, and domain pricing logic.

Establishing unified architecture patterns ensures applications remain maintainable and scalable, regardless of the underlying web UI framework (React, Vue, or Vanilla JS).

Configurator Project Directory Layout#

Defines the canonical directory organization for generated Aircada configurator frontends.

A consistent directory layout prevents project bloat, ensures code is discoverable, and enables reliable code-generation steps.

Regardless of the framework used, projects must structure files into logical concern directories to avoid nesting conflicts.

Example Directory Hierarchy

Below is a gold-standard directory structure of a completed Aircada React customization overlay application. Use this layout as a reference when scaffolding projects or generating new files.

text
src/
├── App.tsx                    # Router & provider entry point
├── index.css                  # Tailwind import & CSS theme variables
├── store.config.ts            # Aircada store initial state configuration
├── components/                # Visual UI components, selectors, and steps
│   ├── UIOverlay.tsx          # Absolute layout page containing viewport & controls
│   ├── OptionSwatch.tsx       # Color/material selector circular swatches
│   ├── PriceDisplay.tsx       # Dynamic live pricing tag with active delta
│   ├── StepPanel.tsx          # Multi-step configurator wizard controller
│   └── ViewportControls.tsx   # Overlaid viewport controls (e.g. resets)
├── hooks/                     # Custom hook subscriptions and state wrappers
│   ├── useOption.ts           # Hook wrapping OptionsRegistry sets
│   └── usePrice.ts            # Hook reading dynamic checkout calculations
├── registry/                  # CLI generated type registries
│   ├── media.generated.ts     # Dataset row types and cloud IDs
│   └── options.generated.ts   # Option sets models definitions
└── styles/                    # Global token styling parameters
    └── theme.css              # Custom font rules and typography classes
  • /components: All visual UI elements, option selectors, layout panels, and overlays (e.g. Swatch.tsx, UIOverlay.tsx).
  • /hooks or /composables: Custom hooks/composables for subscribing to options, state, or scene operators.
  • /lib: Core library instantiations, API connectors, client initializations, and utilities.
  • /types: Canonical types and interfaces, typically derived or generated from schemas.
  • /styles: Root styles, design token files, and framework-specific utility theme sheets.
note
STRICT PROHIBITION: Do not place pricing rules, transaction calculations, or 3D scene bindings directly inside UI components. UI components must remain purely representational, obtaining state via hooks.

Configurator Separation of Concerns#

Defines the boundaries between UI presentation, application state, 3D scene bindings, and business/pricing logic.

Interactive 3D configurators must maintain clean separation between layers. Blending state management, 3D manipulation, and UI rendering into single files leads to massive, unmaintainable structures.

LayerResponsibilitiesAllowed ImportsProhibitions
UI LayerRender layout, option buttons, pricing text, and UI states.Store hooks, types, configuration metadata.Directly modifying 3D viewport, local state mirrors, executing transactions.
State LayerRead/write application options, price, and active settings.SDK store APIs, schema enums, generated option registries.Direct DOM manipulation, styling definitions, viewport instances.
Scene BindingSynchronize store options with 3D models, materials, and animations.SDK scene APIs, store events, property definitions.Rendering DOM UI overlays, managing shopping cart items.
Pricing/Domain LogicCalculate complex rules, cart discounts, and option combinations.Apex schemas, datasets, purchaser plugins.Subscribing to UI component lifecycles or viewport canvas events.

Configurator Option State Source of Truth#

Mandates that all option and configuration state lives solely in the SDK store, preventing parallel local UI state mirrors.

In Aircada configurators, the global SDK store is the single source of truth for option states. Storing options in local component state (useState) and attempting to sync them with the store leads to synchronization lag, double renders, and cart valuation errors.

  • Store is Truth: All options must be read directly from the store, and changes must write directly to the store via standard patch triggers.
  • Exceptions: Transient UI-only states (e.g., hover effects, keyboard focus, loading spin states) are permitted to live in component-local state.
  • 3D Synchronization: The store state automatically drives the 3D scene engine and purchaser operations. Bypassing the store breaks scene-object updates.
typescript
// ❌ INCORRECT: Mirroring option state in local useState
function BadOptionSelector() {
    const [selectedColor, setSelectedColor] = useState(storeState.bodyColor);
    
    const handleChange = (newColor) => {
        setSelectedColor(newColor); // Parallel local state
        patchStore({ bodyColor: newColor });
    };
}

// 🟢 CORRECT: Reading and updating option directly from store
function GoodOptionSelector() {
    const selectedColor = useOption("bodyColor");
    
    const handleChange = (newColor) => {
        patchStore({ bodyColor: newColor }); // Direct write, updates UI via store listener
    };
}
Correct vs Incorrect Option State Management

UI Component Boundaries#

Provides decision heuristics for when to extract a block of UI into its own file vs. keeping it inline.

Keeping a balance between monolithic components (e.g. 1000 lines of inline code) and over-fragmentation (e.g. one component per wrapper div) is essential for code readability and compiler efficiency.

  • Extract when: The component is reused across multiple files.
  • Extract when: The component carries its own internal UI-only state or complex event handlers.
  • Extract when: An inline JSX block exceeds approximately 40-50 lines of code.
  • Extract when: The component corresponds 1:1 to a configurator primitive defined in the design system.
  • Anti-pattern: Do not define helper components inside another component's file. Maintain the one-component-one-file rule.
  • Anti-pattern: Do not create single-use abstractions that add wrapper overhead without logic isolation.
SEO Title: Configurator Architecture Principles
SEO Description: Agnostic architectural guidelines for structuring interactive 3D configurators with clear state and concern separation.
Index Alternates:frontend layoutconfigurator setupfolder structure