Receber por email
← Voltar para o catálogo

standards-kotlin

Kotlin coding standards for modern applications. Includes naming conventions, coroutines, flows, modern Kotlin 2.3.0 features, and recommended tooling.

55estrelas
Atualizado há 5 meses

Ver no GitHub ↗ Licença: MIT

Como adicionar

/plugin marketplace add b33eep/claude-code-setup

O comando exato pode variar conforme o repositório. Confira o README no GitHub.

Para o autor da skill

Cole no README do seu repo

Mostra que sua skill está catalogada na Skillteca, gera backlink e tráfego rastreável.

[![Skillteca](https://www.skillteca.com.br/api/badge/standards-kotlin/svg)](https://www.skillteca.com.br/skills/standards-kotlin)

Skills relacionadas

Ver todas de Desenvolvimento →

Alerta por categoria

Receba novas skills de Desenvolvimento toda segunda

1 email curto, só com as skills novas de Desenvolvimento. 4 minutos de leitura, sem spam, cancela com 1 clique.

Você confirma o email no primeiro envio. Sem spam. Cancela com 1 clique.

Ler descrição completa

Kotlin Coding Standards

Core Principles

  1. Explicitness: Explicit code over implicit magic
  2. Readability: Readable code over clever tricks
  3. Null Safety: Embrace Kotlin's null safety system
  4. Immutability: Prefer val over var, immutable collections
  5. Expressiveness: Use Kotlin's expressive features (data classes, sealed classes)
  6. DRY: Don't Repeat Yourself - but keep it simple

General Rules

  • Prefer val over var: Immutability by default
  • Use data classes: For simple data holders
  • Sealed classes/interfaces: For type-safe state modeling
  • Early returns: Avoid deep nesting
  • Descriptive names: Clear, meaningful names
  • Minimal changes: Only change relevant code
  • No over-engineering: Keep it simple
  • Minimal comments: Self-explanatory code. Comments for "why", not "what"

Naming Conventions

| Element | Convention | Example | |---------|------------|---------| | Classes | PascalCase | UserService, OrderRepository | | Interfaces | PascalCase | UserRepository, PaymentProcessor | | Functions | camelCase | getUserById, calculateTotal | | Properties | camelCase | firstName, totalAmount | | Constants | UPPER_SNAKE_CASE | MAX_RETRY_COUNT, DEFAULT_TIMEOUT | | Packages | lowercase.dot.separated | com.example.service, com.example.repository | | Files | PascalCase.kt | UserService.kt, OrderRepository.kt | | Test Classes | ClassNameTest | UserServiceTest, OrderRepositoryTest | | Test Functions | backtick names | ` should return user when id exists ` |

Project Structure

Gradle Kotlin DSL Project (Recommended)

myproject/
├── build.gradle.kts
├── settings.gradle.kts
├── gradle.properties
├── src/
│   ├── main/
│   │   ├── kotlin/
│   │   │   └── com/example/myapp/
│   │   │       ├── Application.kt          # Main entry point
│   │   │       ├── config/
│   │   │       │   └── AppConfig.kt        # Configuration
│   │   │       ├── domain/
│   │   │       │   └── User.kt             # Domain models
│   │   │       ├── repository/
│   │   │       │   └── UserRepository.kt   # Data access
│   │   │       ├── service/
│   │   │       │   └── UserService.kt      # Business logic
│   │   │       └── api/
│   │   │           └── UserController.kt   # REST endpoints
│   │   └── resources/
│   │       ├── application.conf
│   │       └── logback.xml
│   └── test/
│       ├── kotlin/
│       │   └── com/example/myapp/
│       │       ├── service/
│       │       │   └── UserServiceTest.kt
│       │       └── repository/
│       │           └── UserRepositoryTest.kt
│       └── resources/
│           └── application-test.conf
└── README.md

Maven Project (Alternative)

myproject/
├── pom.xml
├── src/
│   ├── main/
│   │   └── kotlin/...      # Same structure as Gradle
│   └── test/
│       └── kotlin/...      # Same structure as Gradle
└── README.md

Modern Kotlin Features

Recommended: Use Kotlin 2.3.0 (latest LTS) for new projects with K2 compiler enabled by default.

K2 Compiler (Stable since 2.0)

The K2 compiler brings significant performance improvements and faster compilation times.

Features:

  • Faster compilation (up to 2x)
  • Better smart casts
  • Improved type inference
  • Unified architecture for all platforms

Enabled by default in Kotlin 2.3.0 - no configuration needed.

Data Classes

Use data classes for immutable data holders.

// Data class - automatic equals, hashCode, toString, copy, componentN
data class User(
    val id: String,
    val name: String,
    val email: String,
    val age: Int
)

// Usage
val user = User("1", "John Doe", "john@example.com", 30)

// Copy with changes
val updatedUser = user.copy(age = 31)

// Destructuring
val (id, name, email, age) = user
println("User: $name ($email)")

Sealed Classes/Interfaces (Exhaustive When)

Use sealed classes for type-safe state modeling with exhaustive when expressions.

// Sealed interface for result types
sealed interface Result<out T> {
    data class Success<T>(val data: T) : Result<T>
    data class Error(val message: String, val cause: Throwable? = null) : Result<Nothing>
    data object Loading : Result<Nothing>
}

// Exhaustive when - compiler ensures all cases are handled
fun <T> handleResult(result: Result<T>) {
    when (result) {
        is Result.Success -> println("Success: ${result.data}")
        is Result.Error -> println("Error: ${result.message}")
        Result.Loading -> println("Loading...")
        // No else needed - compiler knows all cases
    }
}

// Usage
val result: Result<User> = Result.Success(user)
handleResult(result)

Inline Value Classes (Zero-Cost Wrappers)

Use inline value classes for type-safe wrappers without runtime overhead.

// Inline value class - no boxing overhead
@JvmInline
value class UserId(val value: String)

@JvmInline
value class Email(val value: String) {
    init {
        require(value.contains("@")) { "Invalid email" }
    }
}

// Usage - type-safe, no runtime cost
fun getUserById(id: UserId): User = TODO()
fun sendEmail(email: Email): Unit = TODO()

val userId = UserId("123")
val email = Email("user@example.com")

Context Receivers (Experimental, 2.2+)

Context receivers allow implicit parameters for cleaner DSLs.

Enable with:

// build.gradle.kts
kotlin {
    compilerOptions {
        freeCompilerArgs.add("-Xcontext-receivers")
    }
}

Usage:

interface Logger {
    fun log(message: String)
}

// Function with context receiver
context(Logger)
fun processUser(user: User) {
    log("Processing user: ${user.name}")
    // ...
}

// Call with context
val logger = object : Logger {
    override fun log(message: String) = println(message)
}

with(logger) {
    processUser(user)
}

Explicit Backing Fields (Experimental, 2.3)

Simplifies backing property pattern - define implementation type within property scope.

Enable with:

// build.gradle.kts
kotlin {
    compilerOptions {
        freeCompilerArgs.add("-Xexplicit-backing-fields")
    }
}

Before:

private val _users = MutableStateFlow<List<User>>(emptyList())
val users: StateFlow<List<User>> = _users

After:

val users: StateFlow<List<User>> field = MutableStateFlow(emptyList())

UUID API (Experimental, 2.3)

Built-in UUID support without external dependencies.

Enable with:

@OptIn(ExperimentalUuidApi::class)

Usage:

import kotlin.uuid.Uuid
import kotlin.uuid.ExperimentalUuidApi

@OptIn(ExperimentalUuidApi::class)
fun generateUserId(): Uuid {
    return Uuid.generateV4()
}

@OptIn(ExperimentalUuidApi::class)
fun parseUserId(id: String): Uuid? {
    return Uuid.parseOrNull(id)
}

// V7 UUIDs (time-based, sortable)
@OptIn(ExperimentalUuidApi::class)
fun generateTimeBasedId(): Uuid {
    return Uuid.generateV7()
}

Coroutines & Concurrency

Structured Concurrency

Always use structured concurrency - never use GlobalScope.

import kotlinx.coroutines.*

// GOOD - Structured concurrency
suspend fun fetchUserData(userId: String): UserData = coroutineScope {
    val userDeferred = async { fetchUser(userId) }
    val ordersDeferred = async { fetchOrders(userId) }

    UserData(
        user = userDeferred.await(),
        orders = ordersDeferred.await()
    )
}

// BAD - GlobalScope leaks
fun fetchUserDataBad(userId: String) {
    GlobalScope.launch {  // Don't use GlobalScope!
        // ...
    }
}

Dispatchers

Use appropriate dispatchers for different workloads.

// Dispatchers.Default - CPU-intensive work
withContext(Dispatchers.Default) {
    // Heavy computation
    processLargeDataset(data)
}

// Dispatchers.IO - I/O operations (network, disk)
withContext(Dispatchers.IO) {
    // Network call
    apiClient.fetchData()
}

// Dispatchers.Main - UI updates (Android/Desktop)
withContext(Dispatchers.Main) {
    upd
Compartilhar X LinkedIn