> kotlin-best-practices
Core patterns for robust Kotlin code (Scope Functions, Backing Properties). Use when writing Kotlin code using scope functions, extension functions, or data classes. (triggers: **/*.kt, apply, let, run, also, with, backing property, collection)
curl "https://skillshub.wtf/HoangNguyen0403/agent-skills-standard/kotlin-best-practices?format=md"Kotlin Best Practices
Priority: P1 (HIGH)
Engineering standards for clean, maintainable Kotlin systems.
Implementation Guidelines
- Scope Functions:
apply: Object configuration (returns object).also: Side effects validation/logging (returns object).let: Null checks (?.let) or mapping (returns result).run: Object configuration and mapping (returns result).with: Grouping multiple method calls on an object (returns result).
- Backing Properties: Use
_prop(private mutable) andprop(public immutable) pattern for encapsulation. - Collections: Expose
List/Map(read-only interfaces) publicly, keepMutableListinternal. - Single Expression: Use
runCatchingfor simple error handling overtry/catchblocks. - Visibility: Default to
privateorinternal. Minimizepublicsurface area. - Top-Level: Prefer top-level functions/constants over implementation-less
objectsingletons.
Anti-Patterns
- Nesting Scope Functions: Avoid nesting
let/applymore than 2 levels deep. It destroys readability. - Mutable Public Props: Avoid
public var. Useprivate setor backing properties. - Global Mutable State: Avoid top-level mutable variables.
Code
// Backing Property Pattern
class ViewModel {
private val _uiState = MutableStateFlow(UiState.Loading)
val uiState: StateFlow<UiState> = _uiState.asStateFlow() // Read-only
fun load() {
// apply for config
val user = User().apply {
name = "John"
age = 30
}
// runCatching
runCatching { api.fetch() }
.onSuccess { _uiState.value = UiState.Success(it) }
.onFailure { logger.error(it) }
}
}
Related Topics
language | coroutines
> related_skills --same-repo
> typescript-tooling
Development tools, linting, and build config for TypeScript. Use when configuring ESLint, Prettier, Jest, Vitest, tsconfig, or any TS build tooling. (triggers: tsconfig.json, .eslintrc.*, jest.config.*, package.json, eslint, prettier, jest, vitest, build, compile, lint)
> typescript-security
Secure coding practices for TypeScript. Use when validating input, handling auth tokens, sanitizing data, or managing secrets and sensitive configuration. (triggers: **/*.ts, **/*.tsx, validate, sanitize, xss, injection, auth, password, secret, token)
> typescript-language
Modern TypeScript standards for type safety and maintainability. Use when working with types, interfaces, generics, enums, unions, or tsconfig settings. (triggers: **/*.ts, **/*.tsx, tsconfig.json, type, interface, generic, enum, union, intersection, readonly, const, namespace)
> typescript-best-practices
Idiomatic TypeScript patterns for clean, maintainable code. Use when writing or refactoring TypeScript classes, functions, modules, or async logic. (triggers: **/*.ts, **/*.tsx, class, function, module, import, export, async, promise)