Skill: Kotlin Multiplatform Layout

SkillDev tools

Guidance on where to place different types of code in this Kotlin Multiplatform project.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Skill: Kotlin Multiplatform Layout skill

What this skill tells your AI

The instructions your AI receives, as published by championswimmer/twofac in .agents/skills/kmp-modules/SKILL.md and read by ahel’s review.

This repository follows standard Kotlin Multiplatform source-set conventions, organized into distinct modules, each serving a specific purpose.

Project Modules

The project is divided into three primary modules. Understanding their responsibilities and dependencies is key to placing code in the correct location.

1. sharedLib (Shared Logic)

This is the core module containing all business logic, data models, state management, and storage mechanisms.

  • Purpose: Centralizes the common logic so it can be reused across different user interfaces (CLI and GUI).
  • Dependencies: It is completely independent and does not depend on cliApp or composeApp.
  • What goes here:
    • OTP generation algorithms (e.g., HOTP, TOTP).
    • Data storage operations, database schemas, and repository patterns.
    • Core domain models and use cases/interactors.
    • Platform-specific implementations for storage or cryptography via expect/actual declarations.

2. composeApp (GUI Library)

This module contains most of the common Graphical User Interface (GUI) application code, built using Compose Multiplatform.

  • Purpose: Provides the visual interface for the application (Desktop, Android library, iOS, Web/Wasm).
  • Dependencies: Depends heavily on sharedLib to fetch data, observe state, and trigger actions.
  • What goes here:
    • UI components, screens, and visual layouts written in Jetpack/Compose Multiplatform.
    • ViewModels or UI state holders that bridge the UI with the sharedLib.
    • Platform-specific shared code (e.g., Android DI modules, biometric session, wear sync) within respective <platform>Main source sets.
    • Platform-specific GUI bootstrapping for desktop (main window) and iOS (framework) within their source sets.

3. androidApp (Android App Entry Point)

This is a thin wrapper module that hosts the Android application entry point.

  • Purpose: Contains only the Android Application class, Activity, manifest, and app-level resources (icons, strings).
  • Dependencies: Depends on composeApp which provides all the shared UI and business logic.
  • What goes here:
    • TwoFacApplication (Application class) and MainActivity (Activity).
    • AndroidManifest.xml with application/activity declarations.
    • App-level resources (launcher icons, app name string).
    • Do not put shared Android code here — that belongs in composeApp/androidMain.

4. cliApp (Command Line Interface)

This module contains code specifically related to the Command Line Interface application.

  • Purpose: Provides a terminal-based interface for interacting with the application.
  • Dependencies: Depends on sharedLib to perform corresponding operations without needing a graphical interface.
  • What goes here:
    • Command-line argument parsing and routing.
    • Terminal UI (TUI) drawing and dynamic text layouts (e.g., using libraries like mordant).
    • Terminal-specific interactive components (prompts, tables, secure input for secrets).

Source-Set Mapping (within modules)

Within each Kotlin Multiplatform module (especially sharedLib and composeApp), the code is further organized by source sets:

  • commonMain: Shared production code that is platform-agnostic. Most of the code should live here.
  • commonTest: Shared tests for testing code in commonMain.
  • <platform>Main (e.g., jvmMain, iosMain, androidMain): Platform-specific implementations. Place code here when you need to access platform APIs (e.g., java.io.File on JVM, NSUserDefaults on iOS) that are not available in the common standard library.
  • <platform>Test: Platform-specific tests.

Practical Reminders

  • When adding new features, always start by implementing the core logic in sharedLib/src/commonMain.
  • Expose APIs from sharedLib that are easy to consume for both declarative reactive UIs (composeApp) and procedural/terminal UIs (cliApp).
  • Keep function signatures in common code and push only unavoidable platform differences into platform source sets using Kotlin's expect/actual mechanism.

Signals

GitHub stars
125
Forks
8
Last commit
Jun 2026
Advanced
Catalog kind
skill
Gateway key
kmp-modules
Source
github.com/championswimmer/twofac