Librechat-Mobile/CONTRIBUTING.md

3.5 KiB

Contributing to LibreChat Native KMP

Prerequisites

Tool Version
JDK 17+
Android Studio Latest stable
Xcode 15+ (iOS development)
Gradle 8.11.1 (via wrapper)
Kotlin 2.1.20

Getting Started

# Clone with submodules (upstream LibreChat server reference)
git clone --recursive https://github.com/garfiec/Librechat-Mobile.git
cd Librechat-Mobile

Android

./gradlew assembleDebug

Open the project in Android Studio and run on an emulator or device. Debug APK output: app/build/outputs/apk/debug/app-debug.apk.

iOS

# Build the shared KMP framework
./gradlew :shared:linkDebugFrameworkIosSimulatorArm64

Open iosApp/iosApp.xcodeproj in Xcode and run on an iOS simulator. The shared framework must be rebuilt whenever shared code changes.

Project Structure

The project is a Kotlin Multiplatform (KMP) app with shared business logic and platform-specific UI layers.

Modules

app/                   -> Android entry point, adaptive navigation (phone/tablet)
shared/                -> KMP umbrella module (commonMain, androidMain, iosMain)
core/common/           -> Result type, dispatcher DI, coroutine scopes, extensions
core/model/            -> @Serializable data classes (pure Kotlin)
core/network/          -> Ktor client, API services, SSE client, auth interceptor
core/data/             -> Room DB, DataStore, repositories
core/ui/               -> Material 3 theme, shared composables
feature/auth/          -> Login, Register, 2FA, OAuth, Forgot Password
feature/chat/          -> Real-time chat with SSE streaming, message rendering
feature/conversations/ -> Paginated list, CRUD, tags, search, export/import
feature/settings/      -> Account, appearance, about
feature/agents/        -> Agent marketplace with search and categories
feature/files/         -> File upload, management, image viewer

Source sets: commonMain = shared code, androidMain / iosMain = platform-specific implementations.

Convention Plugins

build-logic/convention/ contains 13 convention plugins (8 Android + 5 KMP) that standardize module configuration. See CLAUDE.md for details.

Adding a New Feature Module

  1. Create the module directory under feature/
  2. Apply the librechat.kmp.feature convention plugin in build.gradle.kts
  3. Create di/<Feature>Module.kt with a Koin module { } containing viewModelOf(::YourViewModel) definitions
  4. Register the module in the application startup Koin configuration
  5. Use koinViewModel() in screen composables to inject ViewModels

Code Style

  • Follow Kotlin coding conventions
  • ViewModels live in commonMain only — no platform-specific ViewModels
  • Handle platform differences via expect/actual declarations or delegate factories
  • Use Kermit for logging (co.touchlab.kermit.Logger), not println, Log.d, or NSLog
  • Feature modules depend on :core:* only, never on each other

Testing

  • Unit tests go in commonTest or androidUnitTest
  • Maestro flows for E2E testing (8 existing flows in .maestro/)
  • Run tests before submitting:
./gradlew test

Architecture Rules

  • Feature modules depend on :core:* only, never on each other
  • Unidirectional data flow: UI -> ViewModel -> Repository -> API/Room
  • Room is a read-through cache; server is source of truth
  • Custom SSE parser over raw ByteReadChannel (not Ktor SSE plugin)

See CLAUDE.md for the full architecture overview and backend quirks.