Guiding Interface Principles
Guidelines for working with the platform app.
Design System
- Use the luz design system for all components - it provides the "lego blocks" built on Tailwind
- Components should be reusable and composable
- Do not write Tailwind CSS directly in
webapplication components
Layout
- Layout components act as a "shell" around content
- Use slots for headers and sidebars
- Use query parameters for changing page values, not layout
- Use shallow linking with the
<Link>component where possible
Components
Server Components (Default)
- Use React Server Components wherever possible
- Use for rendering server-side data
Client Components
- Use only when small state updates are necessary
Data Fetching
- Use
use()and<Suspense>for data fetching where possible - Use
Promise.all()to fetch data in parallel for better performance
State Management
| Tool | Use Case |
|---|---|
| React Query | Mutations, error handling, optimistic updates |
| Zustand | Small pieces of client state where useState isn't appropriate |
Prop drilling should never be necessary. If you find yourself prop drilling, revisit your component composition.
Testing
Unit Testing
- Use Vitest for unit tests
- Use React Testing Library for component tests
- Test behavior, not implementation details
- Co-locate test files with components (
component.test.tsx)
What to Test
| Test Type | Examples |
|---|---|
| User interactions | Click handlers, form submissions, keyboard navigation |
| Conditional rendering | Loading states, error states, empty states |
| Data transformations | Formatting functions, filters, calculations |
| Accessibility | ARIA attributes, keyboard support, screen reader text |
Snapshot Tests
Use snapshots only for:
- Serialized data structures - API responses, configuration objects, GraphQL queries
- Generated output - Email templates, exported data formats, structured logs
Do not use snapshots for:
- UI components (too brittle, changes are hard to review meaningfully)
- Large objects (diffs become unreadable)
What NOT to Do
- Don't test implementation details - Avoid testing internal state, private methods, or component internals
- Don't test third-party libraries - Trust that React Query, Zustand, etc. work correctly
- Don't mock everything - Over-mocking leads to tests that pass but don't catch real bugs
- Don't test trivial code - Simple pass-through components or obvious logic don't need tests
- Don't use
getByTestIdas a first choice - Prefer accessible queries:getByRole,getByLabelText,getByText
Integration Testing
- Use Playwright for end-to-end tests
- Test critical user flows (authentication, core features)
- Run against a real or realistic test environment