Frontend Overview
GospeLib ships three frontend applications from a single monorepo. They share a cross-platform UI library (@gospelib/ui), a type-safe API SDK (@gospelib/sdk), and common design tokens.
Applications
| App | Stack | Port | Path |
|---|---|---|---|
| Web | Next.js 15, App Router, Tailwind v4, shadcn/ui | 3002 | apps/web |
| Mobile | Expo SDK 52, React Native 0.76, Expo Router | -- | apps/mobile |
| Docs | Docusaurus 3 | 3003 | apps/docs |
Web (apps/web)
The primary scripture reader and study tool. Uses Next.js 15 with the App Router, Server Components by default, and 'use client' only where state or browser APIs are needed. Route groups separate public marketing pages from the authenticated app shell:
(marketing)/-- landing, pricing, about (ISR)(app)/-- reader, study, settings (session-gated)
See Next.js App Router for routing conventions, Server vs Client Component rules, Tailwind v4 setup, and SDK usage.
Mobile (apps/mobile)
An Expo scaffold targeting iOS and Android. Offline-first via SQLite for content and MMKV for preferences. Uses the same @gospelib/ui components through React Native primitives.
See Mobile with Expo for Expo Router, offline sync strategy, and EAS build workflow.
Docs (apps/docs)
This documentation site, built with Docusaurus 3. Markdown and MDX pages organized by domain. No custom React components beyond Docusaurus built-ins.
Plugin Architecture
The web app uses a plugin system to isolate feature domains. Each plugin registers panels, toolbar actions, and state slices through a central host API. There are 10 core plugins (plus 6 infrastructure plugins listed below):
| Plugin | Responsibility |
|---|---|
core.reader | Scripture rendering, verse selection, infinite scroll |
core.lexicon | Strong's Hebrew/Greek word definitions and morphology |
core.interlinear | Word-aligned interlinear view |
core.commentary | Commentary panel and annotations |
core.crossrefs | Cross-reference navigation |
core.comparison | Side-by-side translation comparison |
core.witnesses | ELIMINATED. Witness concept removed; manuscripts are editions handled by the Translation pipeline |
core.annotations | User highlights and markings |
core.notes | Personal study notes |
core.journal | Structured journal entries |
core.pinboard | Pinned passages and resources |
core.study-map | Visual study map / graph explorer |
core.toolbar | Floating toolbar (verse/word actions) |
core.context-card | Contextual information cards |
core.ai | AI-assisted study features |
core.teach | Teaching and presentation mode |
Plugins interact with the app through GospeLibAPI.state rather than importing stores directly. This keeps plugin boundaries clean and makes plugins testable in isolation.
Shared UI Library
The @gospelib/ui package provides cross-platform React Native components (ScriptureText, WordToken, ManuscriptView, PassageCard, and more). Components use React Native primitives so they work on both web (via React Native Web) and mobile. Design tokens for colors, typography, and spacing live in theme/tokens.ts.
See Shared UI Library for the component catalog, design tokens, and how to add new components.
State Management
State is split across four layers, each with a distinct responsibility:
| Layer | Library | Purpose |
|---|---|---|
| FSMs | XState v5 | Modal UI flows with explicit states and transitions |
| Reactive UI | @xstate/store v3 | Panel layout, focus, and visibility |
| Preferences | Zustand v5 | Persisted user settings (font size, theme, sidebar) |
| Server data | TanStack Query v5 | All async API data with aggressive caching |
See State Management for the full layer boundary rules, when to use each library, and code patterns.
Design System
Brand colors, testament-specific palettes, typography scales, spacing tokens, and accessibility standards are documented in the design system section.
See Design System for foundations, components, patterns, and platform-specific guidance.
Key Conventions
- Server Components by default -- only add
'use client'when you need state, effects, or browser APIs - Never modify shadcn/ui components in place -- create wrapper components that compose them
- Use
@gospelib/sdkfor all API calls -- it wrapsopenapi-fetchwith full type safety from the OpenAPI spec - Plugins must not import stores directly -- use
GospeLibAPI.stateinstead - Never put server data in Zustand -- TanStack Query is the single source of truth for API responses
- React 18.3 compatibility -- the shared UI library must work with both React 19 (web) and React 18.3 (mobile/Expo 52)