# Contributing to Jan Web App [← Back to Main Contributing Guide](../CONTRIBUTING.md) React frontend using TypeScript, TanStack Router, Radix UI, and Tailwind CSS. State is managed by React State and Zustand. ## Key Directories - **`/src/components/ui`** - UI components (buttons, dialogs, inputs) - **`/src/containers`** - Complex feature components (ChatInput, ThreadContent) - **`/src/hooks`** - Custom React hooks (useChat, useThreads, useAppState) - **`/src/routes`** - TanStack Router pages - **`/src/services`** - API layer for backend communication - **`/src/types`** - TypeScript definitions ## Development ### Component Example ```tsx interface Props { title: string onAction?: () => void } export const MyComponent: React.FC = ({ title, onAction }) => { return (

{title}

) } ``` ### Routing ```tsx export const Route = createFileRoute('/settings/general')({ component: GeneralSettings }) ``` ### Building & Testing ```bash # Development yarn dev yarn build yarn test ``` ### State Management ```tsx // Local state const [value, setValue] = useState('') // Global state (Zustand) export const useAppState = create((set) => ({ data: null, setData: (data) => set({ data }) })) ``` ### Tauri Integration ```tsx import { invoke } from '@tauri-apps/api/tauri' const result = await invoke('command_name', { param: 'value' }) ``` ## Performance Tips ```tsx // Use React.memo for expensive components const ExpensiveComponent = React.memo(({ data }) => { return
{processData(data)}
}) // Debounce frequent updates const debouncedValue = useDebounce(searchTerm, 300) // Virtual scrolling for large lists import { VariableSizeList } from 'react-window' ``` ## Debugging ```bash # React DevTools # Install browser extension, then: # - Inspect component tree # - Debug hooks and state # - Profile performance # Debug Tauri commands console.log(await window.__TAURI__.invoke('command_name')) # Check for console errors # Press F12 → Console tab ``` ## Accessibility Guidelines - Use semantic HTML (`