This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
LTX Desktop is an Electron app for AI video generation using LTX models. Three-layer architecture:
- Frontend (
frontend/): React 18 + TypeScript + Tailwind CSS renderer - Electron (
electron/): Main process managing app lifecycle, IPC, Python backend process, ffmpeg export - Backend (
backend/): Python FastAPI server (port 8000) handling ML model orchestration and generation
| Command | Purpose |
|---|---|
pnpm dev |
Start dev server (Vite + Electron + Python backend) |
pnpm dev:debug |
Dev with Electron inspector + Python debugpy |
pnpm typecheck |
Run TypeScript (tsc --noEmit) and Python (pyright) type checks |
pnpm typecheck:ts |
TypeScript only |
pnpm typecheck:py |
Python pyright only |
pnpm backend:test |
Run Python pytest tests |
pnpm build:frontend |
Vite frontend build only |
pnpm build |
Full platform build (auto-detects platform) |
pnpm setup:dev |
One-time dev environment setup (auto-detects platform) |
Run a single backend test file via pnpm: pnpm backend:test -- tests/test_ic_lora.py
PRs must pass: pnpm typecheck + pnpm backend:test + frontend Vite build.
- Path alias:
@/*maps tofrontend/* - State management: React contexts only (
ProjectContext,AppSettingsContext,KeyboardShortcutsContext) — no Redux/Zustand - Routing: View-based via
ProjectContextwith views:home,project - IPC bridge: All Electron communication through
window.electronAPI(defined inelectron/preload.ts) - Backend calls: Always use
backendFetchfromfrontend/lib/backend.tsfor app backend HTTP requests (it attaches auth/session details). Do not callfetchdirectly for backend endpoints. - Styling: Tailwind with custom semantic color tokens via CSS variables; utilities from
class-variance-authority+clsx+tailwind-merge - No frontend tests currently exist
Request flow: _routes/* (thin) → AppHandler → handlers/* (logic) → services/* (side effects) + state/* (mutations)
Key patterns:
- Routes (
_routes/): Thin plumbing only — parse input, call handler, return typed output. No business logic. - AppHandler (
app_handler.py): Single composition root owning all sub-handlers, state, and lock - State (
state/): CentralizedAppStateusing discriminated union types for state machines (e.g.,GenerationState = GenerationRunning | GenerationComplete | GenerationError | GenerationCancelled) - Services (
services/): Protocol interfaces with real implementations and fake test implementations. The test boundary for heavy side effects (GPU, network). - Concurrency: Thread pool with shared
RLock. Pattern: lock→read/validate→unlock→heavy work→lock→write. Never hold lock during heavy compute/IO. - Exception handling: Boundary-owned traceback policy. Handlers raise
HTTPErrorwithfrom excchaining;app_factory.pyowns logging. Don'tlogger.exception()then rethrow. - Naming:
*Payloadfor DTOs/TypedDicts,*Likefor structural wrappers,Fake*for test implementations
- Integration-first using Starlette
TestClientagainst real FastAPI app - No mocks:
test_no_mock_usage.pyenforces nounittest.mock. Swap services viaServiceBundlefakes only. - Fakes live in
tests/fakes/;conftest.pywires freshAppHandlerper test - Pyright strict mode is also enforced as a test (
test_pyright.py)
- Define request/response models in
api_types.py - Add endpoint in
_routes/<domain>.pydelegating to handler - Implement logic in
handlers/<domain>_handler.pywith lock-aware state transitions - If new heavy side effect needed, add service in
services/with Protocol + real + fake implementations - Add integration test in
tests/using fake services
- Strict mode with
noUnusedLocals,noUnusedParameters - Frontend: ES2020 target, React JSX
- Electron main process: ESNext, compiled to
dist-electron/ - Preload script must be CommonJS
- Python 3.13+ (per
.python-version), managed withuv - Pyright strict mode (
backend/pyrightconfig.json) - Dependencies in
backend/pyproject.toml
- Backend architecture doc:
backend/architecture.md - Default app settings schema:
settings.json - Electron builder config:
electron-builder.yml - Video editor (largest frontend file):
frontend/views/VideoEditor.tsx - Project types:
frontend/types/project.ts