android-clean-architecture
Makes your agent organize Android projects efficiently. It structures the code to make maintenance and new feature development easier.
What it does
This skill helps organize the code for Android apps and other platforms. It defines how different parts of the program should communicate, ensuring the code is easier to understand and maintain.
When to use it
- ✓When starting a new Android project.
- ✓When organizing different parts of an existing app.
- ✓When the app's code is becoming confusing.
Example of what to ask your AI
“How can I structure my Android code using Clean Architecture?”
Want more? Open the sections below.
How to use
The easiest way: copy the message below and paste it into Claude, ChatGPT, Cursor or any AI. It reads the skill and follows the instructions.
Skill link
Ready-to-paste message
How it works
It divides code into logical layers, like 'domain' (business rules) and 'data' (where information is stored). Rules ensure the domain layer never depends on others, keeping it pure.
Installation
Easiest way: copy the skill link and paste it into Claude, ChatGPT or Cursor asking it to follow the instructions.
In the terminal (Claude Code, Codex, Cursor), in your project folder:
npx skills add affaan-m/ECC --skill android-clean-architectureOr download just the file:
curl -L https://raw.githubusercontent.com/affaan-m/ECC/main/pi/core/skills/android-clean-architecture/SKILL.md -o SKILL.mdTechnical content (original SKILL.md)
Original text by the author, straight from GitHub.
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
Recommended Layout
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:
class GetItemsByCategoryUseCase(
private val repository: ItemRepository
) {
suspend operator fun invoke(category: String): Result<List<Item>> {
return repository.getItemsByCategory(category)
}
}
// Flow-based UseCase for reactive streams
class ObserveUserProgressUseCase(
private val repository: UserRepository
) {
operator fun invoke(userId: String): Flow<UserProgress> {
return repository.observeProgress(userId)
}
}
Domain Models
Domain models are plain Kotlin data classes — no framework annotations:
data class Item(
val id: String,
val title: String,
val description: String,
val tags: List<String>,
val status: Status,
val category: String
)
enum class Status { DRAFT, ACTIVE, ARCHIVED }
Repository Interfaces
Defined in domain, implemented in data:
interface ItemRepository {
suspend fun getItemsByCategory(category: String): Result<List<Item>>
suspend fun saveItem(item: Item): Result<Unit>
fun observeItems(): Flow<List<Item>>
}
Data Layer
Repository Implementation
Coordinates between local and remote data sources:
class ItemRepositoryImpl(
private val localDataSource: ItemLocalDataSource,
private val remoteDataSource: ItemRemoteDataSource
) : ItemRepository {
override suspend fun getItemsByCategory(category: String): Result<List<Item>> {
return runCatching {
val remote = remoteDataSource.fetchItems(category)
localDataSource.insertItems(remote.map { it.toEntity() })
localDataSource.getItemsByCategory(category).map { it.toDomain() }
}
}
override suspend fun saveItem(item: Item): Result<Unit> {
return runCatching {
localDataSource.insertItems(listOf(item.toEntity()))
}
}
override fun observeItems(): Flow<List<Item>> {
return localDataSource.observeAll().map { entities ->
entities.map { it.toDomain() }
}
}
}
Mapper Pattern
Keep mappers as extension functions near the data models:
// In data layer
fun ItemEntity.toDomain() = Item(
id = id,
title = title,
description = description,
tags = tags.split("|"),
status = Status.valueOf(status),
category = category
)
fun ItemDto.toEntity() = ItemEntity(
id = id,
title = title,
description = description,
tags = tags.joinToString("|"),
status = status,
category = category
)
Room Database (Android)
@Entity(tableName = "items")
data class ItemEntity(
@PrimaryKey val id: String,
val title: String,
val description: String,
val tags: String,
val status: String,
val category: String
)
@Dao
interface ItemDao {
@Query("SELECT * FROM items WHERE category = :category")
…
FAQ
What is 'domain'?
It's the part of the code containing your app's core rules, without worrying about technical details like where data is saved.
What is a 'Use Case'?
It's a specific action the app can perform, like 'fetch items' or 'save user'.
Why can't 'domain' depend on 'data'?
So that business rules can be used in different contexts (like Android, web, etc.) without needing changes, and to keep the code more organized and testable.
Details
Original description by the author
Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.
repo: affaan-m/ECC
Popularity
- GitHub stars
- 280k
- Ranking position
- #10
- License
- MIT
- Updated
- 10/15/2026
Comments
- …
More skills from this repository
accessibility
Helps your agent create interfaces that everyone can use. Ensures websites and apps work well for people with disabilities, like those who are blind or have reduced mobility.
affaan-m/ECC
agent-architecture-audit
Makes your agent check if everything is working correctly. It finds and fixes problems in AI systems, ensuring they perform as expected.
affaan-m/ECC
agent-eval
Helps your agent compare different AI coding tools. It measures which one is faster, cheaper, and more reliable for specific tasks.
affaan-m/ECC
agent-harness-construction
Makes your agent better understand how to perform tasks. It optimizes the tools and instructions the agent uses to increase its chances of success.
affaan-m/ECC
Similar skills
flutter-animating-apps
Lets your agent add animated effects and transitions in Flutter apps. It's useful for creating motion and visual design in iOS and Android apps.
nexu-io/open-design
add-app-clip
Lets your agent add an iOS App Clip to an Expo app. It's useful for creating lightweight app versions opened by links.
sickn33/agentic-awesome-skills
android-dev
Helps develop Android applications. It covers different ways to create apps, native or cross-platform.
sickn33/agentic-awesome-skills