android-clean-architecture — for Claude Code android-clean-architecture, everything-claude-code, official, for Claude Code, ide skills, Android Clean Architecture, Kotlin Multiplatform, Modular Design, UseCase Pattern, Repository Pattern, Claude Code

Verified
v1.0.0
GitHub

About this Skill

Perfect for Android Development Agents needing advanced architecture patterns and clean code organization. android-clean-architecture is a skill that implements Clean Architecture patterns for Android and Kotlin Multiplatform projects, covering module structure, dependency rules, and data layer design.

Features

Implementing UseCases and Repositories using Kotlin
Designing data flow between layers with Room and SQLDelight
Setting up dependency injection with Koin or Hilt
Structuring Android or KMP project modules for efficiency
Working with Ktor for network operations
Creating modular architecture with feature modules

# Core Topics

affaan-m affaan-m
[105.8k]
[13742]
Updated: 3/25/2026

Agent Capability Analysis

The android-clean-architecture skill by affaan-m is an open-source official AI agent skill for Claude Code and other IDE workflows, helping agents execute tasks with better context, repeatability, and domain-specific guidance. Optimized for for Claude Code, Android Clean Architecture, Kotlin Multiplatform.

Ideal Agent Persona

Perfect for Android Development Agents needing advanced architecture patterns and clean code organization.

Core Value

Empowers agents to design and implement modular, scalable, and maintainable Android applications using Clean Architecture patterns, with a focus on Kotlin Multiplatform projects, Room, SQLDelight, and Ktor, while enforcing dependency inversion and separation of concerns.

Capabilities Granted for android-clean-architecture

Structuring Android projects with modular, layered architecture
Implementing UseCases and Repositories for data access and manipulation
Designing data flow between domain, data, and presentation layers

! Prerequisites & Limits

  • Requires Kotlin programming language
  • Android or Kotlin Multiplatform project setup necessary
  • Familiarity with dependency injection frameworks like Koin or Hilt recommended
Labs Demo

Browser Sandbox Environment

⚡️ Ready to unleash?

Experience this Agent in a zero-setup browser environment powered by WebContainers. No installation required.

Boot Container Sandbox

android-clean-architecture

Streamline Android and Kotlin Multiplatform projects with Clean Architecture patterns. Activate this AI agent skill to simplify module structure, dependency...

SKILL.md
Readonly

Android Clean Architecture

Clean Architecture patterns for Android and KMP projects. Covers module boundaries, dependency inversion, UseCase/Repository patterns, and data layer design with Room, SQLDelight, and Ktor.

When to Activate

  • Structuring Android or KMP project modules
  • Implementing UseCases, Repositories, or DataSources
  • Designing data flow between layers (domain, data, presentation)
  • Setting up dependency injection with Koin or Hilt
  • Working with Room, SQLDelight, or Ktor in a layered architecture

Module Structure

project/
├── app/                  # Android entry point, DI wiring, Application class
├── core/                 # Shared utilities, base classes, error types
├── domain/               # UseCases, domain models, repository interfaces (pure Kotlin)
├── data/                 # Repository implementations, DataSources, DB, network
├── presentation/         # Screens, ViewModels, UI models, navigation
├── design-system/        # Reusable Compose components, theme, typography
└── feature/              # Feature modules (optional, for larger projects)
    ├── auth/
    ├── settings/
    └── profile/

Dependency Rules

app → presentation, domain, data, core
presentation → domain, design-system, core
data → domain, core
domain → core (or no dependencies)
core → (nothing)

Critical: domain must NEVER depend on data, presentation, or any framework. It contains pure Kotlin only.

Domain Layer

UseCase Pattern

Each UseCase represents one business operation. Use operator fun invoke for clean call sites:

kotlin
1class GetItemsByCategoryUseCase( 2 private val repository: ItemRepository 3) { 4 suspend operator fun invoke(category: String): Result<List<Item>> { 5 return repository.getItemsByCategory(category) 6 } 7} 8 9// Flow-based UseCase for reactive streams 10class ObserveUserProgressUseCase( 11 private val repository: UserRepository 12) { 13 operator fun invoke(userId: String): Flow<UserProgress> { 14 return repository.observeProgress(userId) 15 } 16}

Domain Models

Domain models are plain Kotlin data classes — no framework annotations:

kotlin
1data class Item( 2 val id: String, 3 val title: String, 4 val description: String, 5 val tags: List<String>, 6 val status: Status, 7 val category: String 8) 9 10enum class Status { DRAFT, ACTIVE, ARCHIVED }

Repository Interfaces

Defined in domain, implemented in data:

kotlin
1interface ItemRepository { 2 suspend fun getItemsByCategory(category: String): Result<List<Item>> 3 suspend fun saveItem(item: Item): Result<Unit> 4 fun observeItems(): Flow<List<Item>> 5}

Data Layer

Repository Implementation

Coordinates between local and remote data sources:

kotlin
1class ItemRepositoryImpl( 2 private val localDataSource: ItemLocalDataSource, 3 private val remoteDataSource: ItemRemoteDataSource 4) : ItemRepository { 5 6 override suspend fun getItemsByCategory(category: String): Result<List<Item>> { 7 return runCatching { 8 val remote = remoteDataSource.fetchItems(category) 9 localDataSource.insertItems(remote.map { it.toEntity() }) 10 localDataSource.getItemsByCategory(category).map { it.toDomain() } 11 } 12 } 13 14 override suspend fun saveItem(item: Item): Result<Unit> { 15 return runCatching { 16 localDataSource.insertItems(listOf(item.toEntity())) 17 } 18 } 19 20 override fun observeItems(): Flow<List<Item>> { 21 return localDataSource.observeAll().map { entities -> 22 entities.map { it.toDomain() } 23 } 24 } 25}

Mapper Pattern

Keep mappers as extension functions near the data models:

kotlin
1// In data layer 2fun ItemEntity.toDomain() = Item( 3 id = id, 4 title = title, 5 description = description, 6 tags = tags.split("|"), 7 status = Status.valueOf(status), 8 category = category 9) 10 11fun ItemDto.toEntity() = ItemEntity( 12 id = id, 13 title = title, 14 description = description, 15 tags = tags.joinToString("|"), 16 status = status, 17 category = category 18)

Room Database (Android)

kotlin
1@Entity(tableName = "items") 2data class ItemEntity( 3 @PrimaryKey val id: String, 4 val title: String, 5 val description: String, 6 val tags: String, 7 val status: String, 8 val category: String 9) 10 11@Dao 12interface ItemDao { 13 @Query("SELECT * FROM items WHERE category = :category") 14 suspend fun getByCategory(category: String): List<ItemEntity> 15 16 @Upsert 17 suspend fun upsert(items: List<ItemEntity>) 18 19 @Query("SELECT * FROM items") 20 fun observeAll(): Flow<List<ItemEntity>> 21}

SQLDelight (KMP)

sql
1-- Item.sq 2CREATE TABLE ItemEntity ( 3 id TEXT NOT NULL PRIMARY KEY, 4 title TEXT NOT NULL, 5 description TEXT NOT NULL, 6 tags TEXT NOT NULL, 7 status TEXT NOT NULL, 8 category TEXT NOT NULL 9); 10 11getByCategory: 12SELECT * FROM ItemEntity WHERE category = ?; 13 14upsert: 15INSERT OR REPLACE INTO ItemEntity (id, title, description, tags, status, category) 16VALUES (?, ?, ?, ?, ?, ?); 17 18observeAll: 19SELECT * FROM ItemEntity;

Ktor Network Client (KMP)

kotlin
1class ItemRemoteDataSource(private val client: HttpClient) { 2 3 suspend fun fetchItems(category: String): List<ItemDto> { 4 return client.get("api/items") { 5 parameter("category", category) 6 }.body() 7 } 8} 9 10// HttpClient setup with content negotiation 11val httpClient = HttpClient { 12 install(ContentNegotiation) { json(Json { ignoreUnknownKeys = true }) } 13 install(Logging) { level = LogLevel.HEADERS } 14 defaultRequest { url("https://api.example.com/") } 15}

Dependency Injection

Koin (KMP-friendly)

kotlin
1// Domain module 2val domainModule = module { 3 factory { GetItemsByCategoryUseCase(get()) } 4 factory { ObserveUserProgressUseCase(get()) } 5} 6 7// Data module 8val dataModule = module { 9 single<ItemRepository> { ItemRepositoryImpl(get(), get()) } 10 single { ItemLocalDataSource(get()) } 11 single { ItemRemoteDataSource(get()) } 12} 13 14// Presentation module 15val presentationModule = module { 16 viewModelOf(::ItemListViewModel) 17 viewModelOf(::DashboardViewModel) 18}

Hilt (Android-only)

kotlin
1@Module 2@InstallIn(SingletonComponent::class) 3abstract class RepositoryModule { 4 @Binds 5 abstract fun bindItemRepository(impl: ItemRepositoryImpl): ItemRepository 6} 7 8@HiltViewModel 9class ItemListViewModel @Inject constructor( 10 private val getItems: GetItemsByCategoryUseCase 11) : ViewModel()

Error Handling

Result/Try Pattern

Use Result<T> or a custom sealed type for error propagation:

kotlin
1sealed interface Try<out T> { 2 data class Success<T>(val value: T) : Try<T> 3 data class Failure(val error: AppError) : Try<Nothing> 4} 5 6sealed interface AppError { 7 data class Network(val message: String) : AppError 8 data class Database(val message: String) : AppError 9 data object Unauthorized : AppError 10} 11 12// In ViewModel — map to UI state 13viewModelScope.launch { 14 when (val result = getItems(category)) { 15 is Try.Success -> _state.update { it.copy(items = result.value, isLoading = false) } 16 is Try.Failure -> _state.update { it.copy(error = result.error.toMessage(), isLoading = false) } 17 } 18}

Convention Plugins (Gradle)

For KMP projects, use convention plugins to reduce build file duplication:

kotlin
1// build-logic/src/main/kotlin/kmp-library.gradle.kts 2plugins { 3 id("org.jetbrains.kotlin.multiplatform") 4} 5 6kotlin { 7 androidTarget() 8 iosX64(); iosArm64(); iosSimulatorArm64() 9 sourceSets { 10 commonMain.dependencies { /* shared deps */ } 11 commonTest.dependencies { implementation(kotlin("test")) } 12 } 13}

Apply in modules:

kotlin
1// domain/build.gradle.kts 2plugins { id("kmp-library") }

Anti-Patterns to Avoid

  • Importing Android framework classes in domain — keep it pure Kotlin
  • Exposing database entities or DTOs to the UI layer — always map to domain models
  • Putting business logic in ViewModels — extract to UseCases
  • Using GlobalScope or unstructured coroutines — use viewModelScope or structured concurrency
  • Fat repository implementations — split into focused DataSources
  • Circular module dependencies — if A depends on B, B must not depend on A

References

See skill: compose-multiplatform-patterns for UI patterns. See skill: kotlin-coroutines-flows for async patterns.

FAQ & Installation Steps

These questions and steps mirror the structured data on this page for better search understanding.

? Frequently Asked Questions

What is android-clean-architecture?

Perfect for Android Development Agents needing advanced architecture patterns and clean code organization. android-clean-architecture is a skill that implements Clean Architecture patterns for Android and Kotlin Multiplatform projects, covering module structure, dependency rules, and data layer design.

How do I install android-clean-architecture?

Run the command: npx killer-skills add affaan-m/everything-claude-code/android-clean-architecture. It works with Cursor, Windsurf, VS Code, Claude Code, and 19+ other IDEs.

What are the use cases for android-clean-architecture?

Key use cases include: Structuring Android projects with modular, layered architecture, Implementing UseCases and Repositories for data access and manipulation, Designing data flow between domain, data, and presentation layers.

Which IDEs are compatible with android-clean-architecture?

This skill is compatible with Cursor, Windsurf, VS Code, Trae, Claude Code, OpenClaw, Aider, Codex, OpenCode, Goose, Cline, Roo Code, Kiro, Augment Code, Continue, GitHub Copilot, Sourcegraph Cody, and Amazon Q Developer. Use the Killer-Skills CLI for universal one-command installation.

Are there any limitations for android-clean-architecture?

Requires Kotlin programming language. Android or Kotlin Multiplatform project setup necessary. Familiarity with dependency injection frameworks like Koin or Hilt recommended.

How To Install

  1. 1. Open your terminal

    Open the terminal or command line in your project directory.

  2. 2. Run the install command

    Run: npx killer-skills add affaan-m/everything-claude-code/android-clean-architecture. The CLI will automatically detect your IDE or AI agent and configure the skill.

  3. 3. Start using the skill

    The skill is now active. Your AI agent can use android-clean-architecture immediately in the current project.

Related Skills

Looking for an alternative to android-clean-architecture or another official skill for your workflow? Explore these related open-source skills.

View All

flags

Logo of facebook
facebook

Use when you need to check feature flag states, compare channels, or debug why a feature behaves differently across release channels.

243.6k
0
Developer

extract-errors

Logo of facebook
facebook

Use when adding new error messages to React, or seeing unknown error code warnings.

243.6k
0
Developer

fix

Logo of facebook
facebook

Use when you have lint errors, formatting issues, or before committing code to ensure it passes CI.

243.6k
0
Developer

flow

Logo of facebook
facebook

Use when you need to run Flow type checking, or when seeing Flow type errors in React code.

243.6k
0
Developer