Monorepo & Shared UI Architecture
Relevant source files
The following files were used as context for generating this wiki page:
The Monorepo & Shared UI Architecture of the tldw_server project is designed to maintain feature parity between the browser extension and the web user interface. By centralizing core logic, components, and state management in a shared package, the project ensures that research-oriented tools and media analysis features remain consistent across different platforms.
The architecture utilizes a bun workspace monorepo where the core UI logic resides in packages/ui, while platform-specific applications like extension and tldw-frontend serve as thin wrappers or consumer apps for this shared logic.
Sources: apps/DEVELOPMENT.md:8-12, apps/extension/CLAUDE.md:7-14, Docs/Architecture.md:21-25
Core Monorepo Structure
The monorepo is organized into three primary areas: the shared UI package, the browser extension, and the Next.js web application. This structure allows developers to write code once and deploy it to both the web and the extension environments.
The diagram shows the hierarchical relationship where the shared package provides the core functionality to both the Web UI and the Browser Extension.
Directory Layout
The following table describes the primary directories within the apps/ workspace:
| Directory | Purpose | Primary Technologies |
|---|---|---|
packages/ui/src/ | Shared Core: Contains the business logic, UI components, hooks, and state management. | React, TypeScript, Zustand, TailwindCSS |
apps/tldw-frontend/ | Web UI: A Next.js application that serves as the primary web client. | Next.js, React, TailwindCSS |
apps/extension/ | Browser Extension: WXT-based extension for Chrome/Firefox/Edge. | WXT, Vite, React |
Sources: apps/DEVELOPMENT.md:30-51, apps/extension/CLAUDE.md:40-61, Docs/Architecture.md:129-134
Shared UI Components and Logic
The shared UI package (packages/ui/src/) is the engine of the frontend. It is organized to promote reusability and platform-agnostic development.
Shared Services and State
Business logic and API calls are centralized in the services/ directory, while application state is managed using Zustand stores in store/.
- Zustand Stores: Manage state for options, chat models, and RAG (Retrieval-Augmented Generation) slices.
- TldwApiClient: A shared service used to interact with the FastAPI backend.
- Dexie/IndexedDB: Used for local database persistence, including model configurations and vector storage.
Sources: apps/extension/CLAUDE.md:94-114, Docs/Product/WebUI/Workspace_Playground_Redesign.md:27-30
Logic Localization Rules
To maintain the integrity of the shared architecture, developers follow a specific decision tree for code placement:
- Extension Specific? (e.g.,
browser.*APIs): Placed inpackages/ui/src/entries/or specific services with platform detection. - Web/Next.js Specific? (e.g., JWT session management): Placed in
apps/tldw-frontend/. - Otherwise: All shared logic, components, and hooks go into
packages/ui/src/.
Sources: apps/DEVELOPMENT.md:75-84
Platform Adaptation & Shims
Because the Web UI and Browser Extension operate in different environments, the architecture employs shims and aliasing to provide a consistent API for shared code.
Browser API Abstraction
The extension uses real browser.* APIs via the WXT framework. For the web, a shim located at tldw-frontend/extension/shims/wxt-browser.ts provides a implementation based on localStorage.
Routing and Storage
Routing and storage also utilize abstraction patterns to ensure compatibility:
| Feature | Extension Implementation | Web Implementation | Shared Solution |
|---|---|---|---|
| Routing | React Router | Next.js Router | React Router with Web Shim |
| Storage | browser.storage + Dexie | localStorage + Dexie | Zustand with Persistence |
| Auth | API Key (Extension Storage) | JWT (Session Management) | Shared fetchWithAuth Service |
Sources: apps/DEVELOPMENT.md:139-183
Workspace Playground Architecture
A key feature implemented using this shared architecture is the Workspace Playground, which utilizes a three-pane research interface.
The diagram illustrates the data flow within the Workspace Playground, where sources inform chat context and studio output generation.
Workspace State Structure
The workspace state is managed by the workspace.ts store, which tracks source selection and generated artifacts (summaries, quizzes, flashcards).
- Sources: Tracked by
mediaIdandtype(PDF, video, audio, etc.). - Artifacts: Managed with statuses like
pending,generating, orcompleted. - Tagging: Uses a keyword-based strategy (
workspace:<slug>) to filter media items on the server.
Sources: Docs/Product/WebUI/Workspace_Playground_Redesign.md:65-112, Docs/Product/WebUI/Workspace_Playground_Redesign.md:162-166
Development Workflow and Feature Parity
The development workflow requires testing features on both platforms to ensure parity. Developers use specific commands to run dev servers for both the extension and the web UI.
# Extension development
bun run --cwd extension dev
# Web development
bun run --cwd tldw-frontend dev
SSR Considerations
A critical constraint of the shared architecture is that all shared UI code must be imported with SSR (Server-Side Rendering) disabled in Next.js. This is because browser-specific APIs (like Dexie or Extension shims) do not exist in the Node.js environment.
Sources: apps/DEVELOPMENT.md:213-228, apps/DEVELOPMENT.md:275-288
Conclusion
The Monorepo & Shared UI Architecture provides a robust framework for delivering complex media analysis tools across multiple platforms. By leveraging a centralized logic core (packages/ui) and employing sophisticated shimming for platform-specific APIs, the tldw_server project minimizes code duplication and ensures that users receive a consistent experience whether they are using the browser extension or the full web interface.