Utils

SkillMonitoring & ops

Pure Kotlin helpers on the KMP Starter Template — the starter/utils module (no Compose). Variable/string/int/bool extensions, time & kotlinx-datetime, JSON, FieldState/ComparableState, IntentUtils, Log, DataStore delegates, StarterFileManager, EnumException, ExperimentalStarterApi.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Utils skill

What this skill tells your AI

The instructions your AI receives, as published by devatrii/kmp-starter-template in .agents/skills/kmp-starter/utils/SKILL.md and read by ahel’s review.

Reuse Starter's non-UI helpers. Do not write a Kotlin utility if starter/utils already ships one.

Accessor: projects.starter.utils. Package root com.kmpstarter.utils.*. No Compose — safe in ViewModels, repositories, and domain logic.

Variables

  • String: onEmpty(action), onNotEmpty(action), takeIfEmpty(action), takeIfNotEmpty(action), isEmail().
  • Int: safeDec() (won't go below 1).
  • Boolean: ifTrue(value|action), ifFalse(value|action), toggle().
  • Generic: T?.elze(value) — null-coalescing (this ?: value).

Data & time

  • ByteArray.toBase64().
  • currentMillis (property) / epochMillis() / hoursToMillis(hour).

kotlinx-datetime

  • LocalDate.today(), LocalDate.fromLong(millis), LocalDate.millis(), LocalDate.toLocalDateTime(...).
  • Clock.System.localDateTime(), Clock.System.currentInstant().
  • Month.length(year) — days in month, leap-year aware.
  • fromLong/millis take timeZone (default system); use TimeZone.UTC with Material 3 DatePicker.

Serialization

  • Any?.toJsonElement() — recursive conversion to JsonElement (nulls, maps, iterables, arrays, sequences, primitives; fallback .toString()).

Data classes

  • FieldState(value, error)@Serializable; helpers isEmpty(), isValid(), updateValue(), updateError(), reset().
  • ComparableState<T>(value, initialValue)hasChanges, updateValue(), reset(), updateAndReset(), updateAndResetIfNotError(isError, isSaving, newValue). Build with T.asComparableState().

Other

  • EnumException(reason)IllegalStateException carrying an enum for when-exhaustive errors.
  • @ExperimentalStarterApi — opt in at call site (@OptIn(ExperimentalStarterApi::class)).
  • IntentUtilsopenUrl, openAccessibility, shareText, writeToClipboard, readFromClipboard, sendEmail, printNativeView.
  • Log object — Log.d/i/w/e(tag?, message) (tag null[KMP_STARTER]).
  • DataStore delegates — AppDataStore.stringDataStore/intDataStore/longDataStore/booleanDataStore/floatDataStore/doubleDataStore/stringSetDataStore/byteArrayDataStore/serializableDataStore (API: flow, get(), set(value), clear(); set(null) removes key). See data skill.
  • StarterFileManager + StarterFile — cross-platform file API (see data skill).
  • utilsModule — Koin module (includes commonUtilsModule + platformUtilsModule).

Rules

  • Search starter/utils first — before writing any string/int/bool extension, date helper, JSON util, or form state class.
  • FieldState + ComparableState are the form-state primitives; use them, don't invent equivalents.
  • Opt in to @ExperimentalStarterApi where the compiler requires it.
  • Color parsing lives in ui/utils (Color.fromHex), not here.

Reference

  • Docs (live site): https://starter.atherio.dev/utils/
  • Source: starter/utils/src/commonMain/kotlin/com/kmpstarter/utils/**

Signals

GitHub stars
162
Forks
28
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
kmp-starter-utils
Source
github.com/devatrii/kmp-starter-template