Modularizing with Intent: Finding the Right Module Naming Convention

Kotlin module naming convention: [group-]domain-layer[-contexts]. Flat, flexible, KMP-friendly—read on!

Modularizing with Intent: Finding the Right Module Naming Convention

Naming modules is a recurring puzzle I face in my coding journey. As my projects expand, I naturally split them into feature modules—neatly separated by purpose, encapsulated, and easy to test and understand. But the challenge always creeps up: what’s the best way to name and group them? Should I organize by domain? Split UI from APIs and databases? How granular should I get? And how do I avoid duplicating code while sharing it across features? These questions drove me to craft a naming convention that’s become my go-to. It’s a flexible approach—[group-]domain-layer[-contexts]—designed to group related components intuitively and streamline code sharing, and I’m working to make it a consistent habit in my projects.

TLDR

This convention keeps my projects organized and scalable. It groups features (e.g., feature-support-ui), centers on domains (e.g., support), and supports shared code (e.g., -shared, -client, -server). Benefits: clear grouping, KMP-friendly, flat structure, and flexibility.

The Convention

[group-]domain-layer[-contexts]

Imagine a flat module list that’s easy to scan, groups related functionality, and works seamlessly with Kotlin Multiplatform (KMP). Here’s how it breaks down:

  • Group (optional): A prefix like feature- to cluster related modules (e.g., user-facing features).
  • Domain: The core focus—what the module serves (e.g., support, settings, auth).
  • Layer: Its role in the stack (e.g., ui, api, data).
  • Contexts (optional): Zero, one, or more variation suffixes for "sharedness" or specifics (e.g., -shared, -client, -server).

Examples

Examples from a typical project might look like:

  • feature-support-ui: Ticket submission UI.
  • feature-support-api-shared: Shared API models for tickets.
  • feature-support-api-client: Client-side API calls.
  • feature-support-api-server: Server-side ticket handling.
  • feature-settings-ui: Settings screen UI.
  • data-core: Core and shared data logic.
  • app-shared: The shared application module.
  • app-android: The Android application module.

In settings.gradle.kts, it’s a clean list:

include(
    ":feature-support-ui",
    ":feature-support-api-shared",
    ":feature-support-api-client",
    ":feature-support-api-server",
    ":feature-settings-ui",
    ":data-core",
    ":app-shared",
    ":app-android"
)

Try It Out

Give it a try in your next Kotlin multiplatform project. The standard is not set in stone, but I have been shaping it over time and gravitating towards this approach for awhile. It gives my projects some consistency and I think it makes the code easy to understand at a quick glance. Let me know what you think and if you have any ideas for refinements!