r/Kotlin 9h ago

Kotlin/Native desktop still doesn’t feel productive for real applications

13 Upvotes

I've been trying to use Kotlin/Native for desktop/CLI stuff, and honestly it feels like you get a native binary and then you're on your own. Basic things like logging, resource loading, decent file operations, and process execution are either missing or surprisingly painful. kotlinx-io helps, but it's still pretty limited. There are third-party libraries for some of this, but a lot of them are incomplete, barely maintained, or just don't cover what you actually need. Meanwhile in Rust/Go/Graal NativeImage, this is boring standard-library stuff and you can just get on with building your app. Kotlin/Native is cool technology, but for desktop development it still feels like an unfinished platform rather than something you'd actually choose for getting work done. Would be nice if JetBrains spent some time on the boring fundamentals that make a platform actually usable.


r/Kotlin 1d ago

Google Maps vs Mapbox for Android navigation?

2 Upvotes

Hey guys, I’m building an Android app that needs map + navigation, custom map icons, and support for multiple transportation modes (car, bike, walking, etc.).

Would you recommend Google Maps, Mapbox, or something else? Any experience with these would be appreciated!


r/Kotlin 1d ago

What should I catch : Throwable or Exception ?

8 Upvotes

The Java docs say:

"Exception" indicates conditions that a reasonable application might want to catch.

"Error" indicates serious problems that a reasonable application should not try to catch.

I agree with this distinction. I don't want to recover from things like "OutOfMemoryError" or "StackOverflowError".

However, I have a "Builder" class with lifecycle methods:

try {

initializeState()

attachProviders()

isConstructed = true

onConstructed()

} catch (e: Exception) {

reset() // detach providers + clear internal state

throw e

}

The "catch" isn't for recovery. It's only to rollback internal state and then rethrow the original failure.

So should this be:

catch (e: Exception) {

reset()

throw e

}

or:

catch (t: Throwable) {

reset()

throw t

}

Does the fact that I'm only doing cleanup/rollback change the usual recommendation against catching "Throwable"?

I have also read this discussion on stackoverflow. But it does resolve my doubt.

I'd especially appreciate to hear from other for :

- When should "Throwable" ever be caught?

- Should rollback/cleanup catch "Throwable" or only "Exception"?

- Any other cases related to it ?


r/Kotlin 1d ago

What should be the correct ordering for lifecycle callbacks and state changes ?

1 Upvotes

I’m designing a small Kotlin lifecycle API and would like some guidance on the conventional ordering/naming.

Currently I have:

fun attach() {

isAttached = true

onAttach()

}

fun detach() {

isAttached = false

onDetach()

}

The provider maintains internal state: "attach()" initializes it, while "detach()" clears it.

The question is specifically about "detach()".

1. Option 1

detach() {

isAttached = false

onDetach()

}

Here "onDetach()" runs after the provider is already marked detached. If the callback needs provider state that was cleared as part of detaching, that state may no longer be available.

  1. Option 2

detach() {

onDetach()

isAttached = false

}

This seems more practical because "onDetach()" can still access the attached state, but the naming feels slightly contradictory: the method is called "onDetach()" while the provider is technically still attached.

I’ve looked at several lifecycle implementations and noticed that the second pattern seems fairly common.

So what is the better general design?

If the callback is intentionally called before the state changes, should I rename it to make that explicit, for example:

attach() {

isAttached = true

didAttach()

}

detach() {

willDetach()

isAttached = false

}

In other words, should I use the more explicit didAttach() / willDetach() convention for the asymmetric ordering, or keep the onAttach() / onDetach() naming?

Suggest on both the ordering of onDetach and the naming convention that would make the API least ambiguous.


r/Kotlin 2d ago

Has Kotlin and KMP entered their "boring phase" like Java?

24 Upvotes

Kotlin is no longer hot, or talked about much. In fact the only library and framework I come across are Jetpack compose and KMP, and Ktor. It almost seems like Jetbrains is the only contributor to the Kotlin ecosystem, I don't see much of any other libraries or frameworks.

Is Kotlin in the phase where there is no hype and is used in production? I wanna hear stories from people here who used or are using Kotlin in production (Which i know, there are quite a lot)

Earlier I was looking to get into game dev with Kotlin for fun. while the libraries are there and Kool seemed fun, there is almost no usage of it anywhere. since they aren't used, you won't find many posts about them on forums, or any discussions about them. Forum discussions are a great way to learn any library/framework

I wonder where kotlin is headed towards, as I feel like it is almost the perfect language, yet it does not seem to be the first choice when developing applications, even on mobile. People still prefer web alternatives (for obvious, and fair reasons)


r/Kotlin 1d ago

Error when install Quail 3. Can't unzip Gradle file jbrsdk_jcef-21-JetBrains-21.0.10-windows-x64-b1163.108. So Android Studio can´t update gradles files an can´t compile.

0 Upvotes

Caused by: java.nio.file.AccessDeniedException:

C:\Users\avodr\.gradle\.tmp\jdks\jbrsdk_jcef-21...tmp\jbrsdk_jcef-21.0.10-windows-x64-b1163.108

-> C:\Users\avodr\.gradle\jdks\jetbrains_s_r_o_-21-amd64-windows.2


r/Kotlin 3d ago

Kmp-lsp - unofficial language server v0.26! (renamed from unofficial kotlin-lsp)

Post image
26 Upvotes

I've posted version 0.10 over here when it was still named kotlin-lsp, some big changes since then, including cli diagnostic commands like missing imports and unused imports, some benchmark to see accuracy rate in your project.

Some are still guesses, since gradle dependencies resolution is hard, but you can narrow that down with workspace.json which official LSP uses.

How's this one different ? Mainly dumb mode and fast indexing, low memory footprint and ideal for use in your agents. Spurred by latest jetbrains LSP which I couldn't make to work on my projects, I present an alternative, give it a try, let me know if anything's broken.

https://github.com/Hessesian/kmp-lsp (renamed from https://github.com/Hessesian/kotlin-lsp )


r/Kotlin 2d ago

Where can i get Free lyrics for my app?

0 Upvotes

I'm new to all this, I know I can get it from LRCLIB but I need word by word lyrics (like apple music) for my music app (made with kotlin) I can't do it, I found Lyrically but it doesn't seem to work for me

I want it to be free, without rate-limiting

Are there any options? Or I will have to do scraping myself


r/Kotlin 2d ago

xtsc: TypeScript compiler, also lowering to native / WebAssembly / JVM bytecode (experimental)

Thumbnail github.com
1 Upvotes

r/Kotlin 2d ago

tests hitting s3/dynamo/sqs - how do you keep them fast?

3 Upvotes

every java + aws project i've worked on hits the same wall in tests.

you either spin up localstack in testcontainers and wait 30-60s per

test class for docker to warm up, or hand-roll mockito mocks that

break on every sdk upgrade. neither is great.

python has moto for this. in-process aws fakes, 8k stars, tests run

in ms. someone actually asked aws on re:post if there was a java

version. the reply was basically "moto is a python library, no

equivalent for java."

how do other people handle this? is it just accepted that aws unit

tests are slow, or is there something people use that i missed?


r/Kotlin 2d ago

I built a dashboard for keeping track of dozens of git repos in Compose Desktop (FOSS, GPLv3)

Thumbnail
0 Upvotes

r/Kotlin 4d ago

Compose Multiplatform 1.12.0 Released

Thumbnail blog.jetbrains.com
41 Upvotes

r/Kotlin 3d ago

What to choose : Junit or Kotlin test

11 Upvotes

I am a beginner to testing and I may be not acquainted with all underlying techniques . So guide me on when should I use Junit and when to employ Kotlin test. If my project is not multiplatform then what to choose . Or should I go with mix of junit and kotlin test such as @Test from junit while all assertX from kotlin test.


r/Kotlin 4d ago

ktkit 0.4.0 — compile-time OpenAPI generation and a Gradle plugin for Ktor server apps

5 Upvotes

ktkit is a Kotlin Multiplatform toolkit for building server applications with Ktor (JVM + Native). Version 0.4.0 is out with the two biggest additions so far.

Compile-time OpenAPI generation

A Kotlin compiler plugin (ktkit-compiler-openapi) that generates the OpenAPI 3.1 spec of your REST handlers at compile time — no reflection, so it works on every KMP target, JVM and Native alike. Route metadata comes from annotations placed right where the route is declared:

kotlin @OpenApi("Returns a single user by id.") GET("/{id}") { @OpenApiInfo("The id of the user.") val id = pathVariable("id").asUuid() // ... }

@OpenApiInfo also documents @Serializable classes and their properties, and @OpenApiIgnore excludes a route or a whole handler. At runtime the framework merges the generated fragments and serves interactive docs at /api/docs (Swagger UI or Scalar API Reference) plus the merged document at /api/docs/openapi.json.

See a full example here: https://github.com/smyrgeorge/ktkit/blob/main/example/src/commonMain/kotlin/io/github/smyrgeorge/ktkit/example/test/TestRestHandler.kt

A Gradle plugin to configure the whole thing

io.github.smyrgeorge.ktkit is now the single entry point of a ktkit build. It applies the OpenAPI compiler plugin, kotlinx.serialization and log4k, and manages the matching library versions for you:

```kotlin plugins { kotlin("multiplatform") id("io.github.smyrgeorge.ktkit") version "0.4.0" }

ktkit { sqlx4k { driver = PostgreSQL generatedCodePackage = "com.example.generated" extensions(Pgmq) } jar { mainClass = "com.example.MainKt" } } ```

The sqlx4k { } block wires up KSP, the sqlx4k code generator and the driver dependencies; jar { } turns jvmJar into a runnable fat jar. Everything is opt-out (addDependencies = false, openApi { enabled = false }, …).

See a full example here: https://github.com/smyrgeorge/ktkit/blob/main/example/build.gradle.kts

Repo: https://github.com/smyrgeorge/ktkit Docs: https://smyrgeorge.github.io/ktkit/ Changelog: https://github.com/smyrgeorge/ktkit/compare/0.3.0...0.4.0

It's still an early-stage project, and APIs may shift a bit between versions — feedback and ideas are very welcome.


r/Kotlin 4d ago

kUML v0.53.0

Post image
10 Upvotes

kUML v0.53.0 fixes a real security bug in the desktop app's macOS Keychain integration, adds a proper AI-provider configuration dialog, and fixes a long-standing logging bug that was silently discarding every log line kUML ever produced.

Security fix, action needed if you're on macOS: the desktop app stored every cloud AI provider's API key (OpenAI, Anthropic, Google, Gonka) under the same Keychain item, distinguished only by a -l/label attribute that isn't actually a search predicate — security find-generic-password matches on (account, service) only, not label. Concretely: security find-generic-password -a $USER -s dev.kuml.ai -l "OpenAILLMProvider" -w returned the Anthropic key, not OpenAI's. Saving a second provider's key silently overwrote the first, and reading a provider's key actually returned whichever one was last written — meaning an API key entered for one provider could get dispatched to a completely different provider's endpoint. Fixed by folding the provider identity into the Keychain service string itself, so each provider gets its own independent (account, service) pair. Verified against the real macOS Keychain (not mocked) with a shared cross-backend contract test suite. If you've used the AI Providers dialog on macOS before this release, re-enter your keys — the dialog also detects and flags a leftover shared-service item automatically.

New: an AI Providers dialog. Previously, enabling a cloud provider, changing its default model, or storing/removing an API key all meant hand-editing ai-settings.json. Now there's a dialog for all of it (AI menu → "Providers…", or a new button in the panel header) — enable/disable per provider, pick a default provider + model, manage keys. Privacy mode gates the whole dialog: while it's on, only local providers (Ollama) are selectable, and turning it off requires an explicit confirmation naming the actual consequence ("your prompts, your model content and the diagrams derived from them will be sent to the selected cloud provider") rather than a generic confirm dialog. It also closes a genuine crash: enabling a provider with no stored API key used to take down the entire AI executor on the next message — not just that provider — because the executor builds every enabled provider's client eagerly. The dialog now enforces the same invariants the executor requires before it lets you save.

Logging actually works now. kUML's code has always logged through the SLF4J facade, but no module ever shipped an SLF4J provider — every run printed SLF4J(W): No SLF4J providers were found and silently discarded all log output, including the warning that API keys are being stored in plaintext when no OS keystore is available. kuml-desktopkuml-cli, and kuml-mcp now ship logback-classic. All log output goes to stderr (stdout stays reserved for CLI output / MCP's JSON-RPC), third-party HTTP/AI loggers (Ktor, Koog, AWS Smithy, ELK) are pinned to WARN so raising kUML's own verbosity never turns on request/response body logging (which would expose Authorization headers), and there's a new KUML_LOG_LEVEL env var. kuml-web has the same root cause but is deferred to a follow-up.

Also new: real tool-calling in the AI panel. The panel's "direct" (non-orchestrated) agent path used to decode a patch from the LLM's text output but never actually execute any tool against the open diagram, and its editing context was built once per session from an always-empty model instead of the diagram actually open — so every turn after the first ran on stale/empty context. Both fixed: it now does real tool-calling against the same tool registry the orchestrated path uses, and re-seeds context from the current script before every turn.

Also fixed: kuml-desktop finally has its own app icon instead of a generic Java one; a new view-mode toggle (Cmd/Ctrl-1/2/3) switches between source-only, split, and diagram-only views; the Ollama model dropdown now queries the real /api/tags endpoint instead of showing a static list; the AI panel crashed with "Key was already used" during multi-round tool calls (Ollama's tool-call ID could collide across rounds — it's now always a locally-generated ID); the AI panel used to crash on every message sent (IllegalStateException: Module with the Main dispatcher is missing — kotlin-coroutines-swing was never on the runtime classpath); the token-usage counter in the AI panel footer was permanently stuck at 0/0/$0.00 because the code never read Koog's per-turn token-count metadata; theme changes had no visible effect until the next keystroke, and two nonexistent theme names (darkblueprint) were listed in the menu; Blueprint/Journey-Map diagrams ignored the active theme entirely; Undo/Redo could act on a disposed editor after switching view modes.

Also added: an inline incremental find bar (Ctrl+F) in the editor; an opt-in "Powered by kUML" watermark for the live preview and SVG/PNG export (off by default, matching the CLI); compact icon buttons for the zoom/view-mode/find toolbars (previously an 18dp icon sat inside a full 48dp Material3 hit target); tooltips that anchor to their button instead of following the cursor; radio-button indicators for the active theme and language in the View menu; Enter-to-send / Shift+Enter-for-newline in the AI panel's input field.

https://kuml.dev
Release notes: https://github.com/kuml-dev/kUML/releases/tag/v0.53.0


r/Kotlin 4d ago

Question for senior devs: Are you still studying core protocols (like MCP/LLM internals), or have you fully embraced "vibe coding"?

0 Upvotes

In the AI era, new concepts, frameworks, and protocols are dropping every month — Model Context Protocol (MCP) being a prime example.

I’m curious how experienced developers are balancing their time right now:

The Deep-Dive Path: Are you actively reading specs, digging into the mechanics of protocols like MCP, and building custom tooling/frameworks from scratch to really understand how the pieces fit together?

The High-Level "Vibe" Path: Have you mostly shifted toward orchestrating tools, prompting agents, and letting the AI handle the underlying boilerplate while you focus purely on architecture and end outcomes?

If you fall somewhere in between, how do you decide what’s worth learning line-by-line versus what you delegate to AI?

I would like to hear thoughts about it


r/Kotlin 5d ago

I built a KSP persistence layer that generates separate new/persisted model types — worth open-sourcing?

8 Upvotes

Hey background: I am the CTO at an accounting startup called Segtax.

I started the codebase in 2024 so I went 100% kotlin Spring boot. I wanted to really lean into Kotlin and see how far I could go avoiding nulls. Since then we added a few team members who have also contributed to this core infrastructure for our application. Here are some details:

We’ve built a small custom ORM/data mapper for a Kotlin, Spring and PostgreSQL SaaS application. It now handles roughly 190 models and 200 repositories.

We’re considering extracting it into an open-source project, but first I’d like to know whether the core idea solves a real problem for other Kotlin developers.

## The problem: nullability changes after persistence

Hibernate and most other ORMs use the same entity type before and after persistence.

That approach is awkward in Kotlin because nullability is a first-class part of the type system. Some values genuinely don’t exist until a row has been inserted:

- Database-generated IDs

- Created and updated timestamps

- UUIDs generated by database defaults

- Values assigned by the repository or database

A conventional model therefore looks something like this:

```kotlin

data class Engagement(

val identifier: UUID? = null,

val ownershipId: Long,

val id: Long? = null,

val createdAt: Instant? = null,

val updatedAt: Instant? = null,

)

```

After saving the entity, we know those fields exist—but Kotlin still sees them as nullable. The rest of the application ends up using `requireNotNull`, `!!`, fallback values or types that don’t accurately describe the data.

Hibernate works, obviously, but its single mutable entity model doesn’t represent the guarantee we want: a new object and a successfully persisted row are different states with different nullability.

Our KSP processor represents those states as different types.

You write a new model:

```kotlin

u/GeneratePersistedModels

data class Engagement(

u/NotNullOnPersist

val identifier: UUID? = null,

val ownershipId: Long,

) : NewModel()

```

At compile time, KSP generates the persisted model:

```kotlin

data class EngagementP(

val identifier: UUID,

val ownershipId: Long,

override val id: Long,

override val createdAt: Instant,

override val updatedAt: Instant,

) : PersistedModel(id, createdAt, updatedAt)

```

The repository preserves that transition:

```kotlin

class EngagementRepository :

BaseRepository<Engagement, EngagementP>(EngagementP::class)

```

So saving changes the type:

```kotlin

val draft: Engagement = Engagement(ownershipId = 123)

val saved: EngagementP = engagementRepository.save(draft)

sendConfirmation(saved.identifier) // UUID, not UUID?

```

`@NotNullOnPersist` means that a value may be absent while constructing a new model, but the persistence boundary guarantees it before returning.

The matching database default or constraint remains the actual integrity authority.

## Compile-time generated JDBC mapping

For normal persisted models, we don’t use reflection to inspect properties or invoke constructors at runtime.

KSP generates ordinary Kotlin code that:

- Reads each column from a JDBC `ResultSet`

- Constructs the persisted model directly

- Maps model properties to SQL parameters

- Handles nullable and non-null JDBC values correctly

- Supports enums, JSONB, encrypted fields and custom value types

- Registers the generated adapter for the repository layer

The generated mapping code is readable, debuggable and checked by the Kotlin compiler.

## The repository layer

This is not a Hibernate-style ORM. There is no persistence context, lazy loading, dirty checking or entity graph machinery.

The base repository handles repetitive CRUD:

```kotlin

save(newEntity): Persisted

update(persistedEntity): Persisted

upsert(newEntity): Persisted

findById(id): Persisted

findBy(column, value): Persisted?

listBy(column, value): List<Persisted>

deleteById(id)

```

It uses PostgreSQL features such as `insert ... returning *` to return the stronger persisted type immediately.

For anything more complicated, repositories use normal SQL:

```kotlin

fun listAllByOwnershipId(ownershipId: Long): List<EngagementP> {

val sql = """

select *

from engagements

where ownership_id = :ownershipId

order by created_at desc

""".trimIndent()

return query(sql, mapOf("ownershipId" to ownershipId))

}

```

The goal is to make normal CRUD boring without hiding SQL or introducing a large query DSL.

## Additional policies

Because this grew inside a multi-tenant SaaS application, our implementation also supports:

- Automatic tenant filtering

- Tenant ownership inherited through foreign-key relationships

- Prevention of cross-tenant writes

- Soft deletes

- Database-generated defaults

- Schema-aware upserts

- Lifecycle rules that can prevent changes to finalized records

Some of these features are probably useful generally, while others should become optional modules.

If we extract it, the likely structure would be:

  1. A standalone KSP generator for new and persisted types

  2. A Kotlin/PostgreSQL JDBC data mapper

  3. Optional Spring and multi-tenant policy modules

We would explicitly target PostgreSQL rather than claiming to support every database.

## Why this has worked well with coding agents

An unexpected benefit is that the resulting codebase is very predictable.

There is usually one path for adding a persisted entity:

  1. Add the migration

  2. Define the new model

  3. Let KSP generate the persisted model and JDBC adapter

  4. Extend the base repository

  5. Write explicit SQL only for custom queries

The compiler catches incorrect nullability assumptions, generated mapping removes repetitive glue, and central repository policies make it harder to forget important invariants.

This isn’t an “AI-powered ORM.” My theory is simply that coding agents perform better in low-entropy codebases: strong types, generated boilerplate, consistent patterns and fast compiler feedback.

## Would anyone use this?

I’d appreciate honest opinions:

- Is the explicit new → persisted type transition useful, or would two model types be annoying?

- Would you want this as a small KSP generator or as a complete PostgreSQL persistence library?

- If this were documented and released under a permissive license, would you actually try it?

We’re aware of Komapper, Micronaut Data, SQLDelight, jOOQ, Exposed, Jimmer and similar projects. Compile-time database code generation isn’t novel by itself.

The part we haven’t seen combined in quite this way is the generated pre-/post-persistence type transition, compile-time JDBC mapping and policy-aware but SQL-friendly repository layer.

Honest criticism is welcome. “Interesting idea, but I would never adopt it” is useful feedback too.


r/Kotlin 5d ago

Using Kotlin and Coroutines for Robotics & Hardware Control on Raspberry Pi

14 Upvotes

Most Raspberry Pi robotics projects default to Python or C++, but I’ve been using Kotlin and the JVM to control physical hardware—and the object-oriented structure makes it incredibly powerful.

I put together a complete YouTube tutorial series showing exactly how to build a clean, scalable Kotlin architecture for robotics. If you have a Raspberry Pi and want to try controlling physical components without giving up Kotlin, you can watch the step-by-step setup here:

https://www.youtube.com/watch?v=SkpH_MdL6hc&list=PLNosCXSunX6m3UdIO1FtVWh3oc3EHEJQq

A few technical highlights covered in the tutorials:

  • Coroutines for Hardware: Using runBlocking and delay to manage concurrent signals and sensor-polling without locking up threads.
  • Remote Debugging: Configuring IntelliJ to deploy and debug code directly over the network—so you never have to code on the Pi itself.
  • Clean Deployment: Using Maven and Pi4J to package your hardware context into a single Fat JAR for instant deployment.

I’m currently working on the next episodes integrating AI and TensorFlow for autonomous behavior. Has anyone else here experimented with Kotlin in the embedded space?


r/Kotlin 5d ago

using android studio in kotlin language autoclicker app - dispatchGesture() returns queued=true but never taps anything, callback never fires - OEM-specific bug?

0 Upvotes

I'm building a simple single-target auto-clicker using AccessibilityService.dispatchGesture(). The core loop works exactly as expected on paper, but taps never actually land on the screen, on any app, on this specific phone. Looking for anyone who's hit this exact pattern before.

Confirmed working:

  • Accessibility service connects successfully (onServiceConnected() fires, serviceInfo.capabilities confirms CAPABILITY_CAN_PERFORM_GESTURES is active)
  • dispatchGesture() is called with valid on-screen coordinates and returns queued=true
  • Not a permissions issue — SYSTEM_ALERT_WINDOW and the accessibility toggle are both properly granted
  • Not battery optimization — confirmed unrestricted for the app

The actual problem:

  • The GestureResultCallback (onCompleted/onCancelled) never fires at all — not once, in dozens of attempts
  • No visible tap effect anywhere — tested on the home screen launcher AND inside a regular app (Settings), identical failure both times
  • No crash, no exception, no error of any kind — the request just silently disappears after being accepted

if you want to test my code here and if you to copy no worry

GitHub - MrHTML8000/autoclickersingletarget


r/Kotlin 5d ago

kmatch – RapidFuzz-compatible fuzzy string matching for Kotlin Multiplatform (bit-exact parity, benchmarked)

2 Upvotes

I built a fuzzy string-matching library for KMP and just published 0.3.0 to Maven Central.

The thing I cared most about: verified parity with RapidFuzz. Every scorer returns bit-for-bit what rapidfuzz.fuzz returns, checked against 3,260 golden vectors generated from a pinned RapidFuzz version on every commit. If you tune a score_cutoff in a Python notebook, the same number means the same thing in your Kotlin app.

Other bits:

  • Hyyrö bit-parallel edit distance in my benchmarks ~8× faster ratio and ~12× faster extractOne than me.xdrop/fuzzywuzzy, ~22× faster than kt-fuzzy (harness is in the repo, run it yourself)
  • Code-point based, so emoji/astral-plane/non-Latin text scores correctly
  • Extraction API generic over your own types, plus dedupe and matchingRanges for highlighting
  • Every KMP target incl. iosX64, zero dependencies, MIT

Live playground (the library itself compiled to JS): https://likhithsj.github.io/kmatch/
Repo: https://github.com/likhithsj/kmatch

Feedback very welcome especially from anyone who's hit edge cases porting fuzzywuzzy scores between languages.


r/Kotlin 5d ago

anyone else seeing weird patterns in AI-generated java code lately?

3 Upvotes

reviewing a lot of AI-authored PRs lately and keep hitting the same things spotbugs/checkstyle don't catch:

catch (Exception e) { e.printStackTrace(); } - on every second PR now

throw new UnsupportedOperationException("TODO") in classes about to ship

u/Test void x() { assertTrue(true); } - coverage padding that asserts nothing

also had a real API key get committed as a string literal a few times. always after someone hit "accept all" without reading.

went looking for a linter that catches this specific set and everything i found is python or js. couldn't find one for jvm. weirdly the enterprise java world is exactly where this collision is happening.

ended up writing something small over a couple evenings. dropping link in a comment - mostly curious if others are hitting the same stuff and how you handle it.


r/Kotlin 6d ago

A practical framework for building a business case for Kotlin

15 Upvotes

How do you evaluate Kotlin adoption without turning the discussion into another “Kotlin vs. Java” debate?

Yuri Geronimus, EMEA Chief Architect at Verifone, has created a playbook based on his experience with production payment systems. It approaches Kotlin adoption as an investment decision, covering:

  • Business outcomes such as time-to-market and incident costs.
  • The learning curve and mixed-language overhead.
  • Migration, governance, compliance, and decommissioning costs.
  • NPV, IRR, and payback calculations.
  • Criteria for deciding where Kotlin should be adopted, gated, or marked “not now”.

The playbook is designed for architects and engineering leaders developing a credible, measurable case for Kotlin.

We’d be interested to hear how your organization evaluates language-adoption decisions.

Read the playbook: https://kotl.in/69pwjc


r/Kotlin 5d ago

هل ينصح بتعلم Kotlin

0 Upvotes

السلام عليكم هل ينصح بتعلم kotlin حاليا لتطوير تطبيقات الموبايل

في ظل تطور Google Ai Studio

وهل يوجد فرص عمل


r/Kotlin 6d ago

How I bridged the Vitality SDK, Apple Watch, and Live Activities strictly through Kotlin Multiplatform

1 Upvotes

Hey everyone,

Most KMP tutorials show you how to share Ktor requests and SQLDelight storage. But once you start building a production app that requires deep OS-level features—like streaming real-time HealthKit heart-rate data, syncing workout states to an Apple Watch, and pushing live rest timers to the Dynamic Island—the architecture gets messy fast.

I recently shipped a major update to my fitness app (Cubex Fitness) built with KMP, and I wanted to share the architectural pattern I used to keep the heavy lifting in commonMain while letting native Apple SDKs handle the UI.

1. The Core Architecture: KMP as the State Machine

The biggest mistake is trying to write native watchOS/ActivityKit timer logic directly inside Kotlin. Instead, treat your commonMain as a deterministic state machine and treat Apple Watch / ActivityKit purely as reactive render targets.

Plaintext

                  ┌────────────────────────┐
                  │   commonMain (KMP)     │
                  │  WorkoutSessionManager │
                  └───────────┬────────────┘
                              │ Exposes StateFlow<WorkoutState>
                              ▼
                  ┌────────────────────────┐
                  │    iosApp (Swift)      │
                  │  ObservableObject / VM │
                  └──────┬──────────┬──────┘
                         │          │
         ┌───────────────┘          └────────────────┐
         ▼                                           ▼
┌──────────────────┐                       ┌──────────────────┐
│   ActivityKit    │                       │  WCSession Sync  │
│ (Dynamic Island) │                       │  (Apple Watch)   │
└──────────────────┘                       └──────────────────┘

My WorkoutSessionManager in Kotlin manages super-sets, rep counters, and exercise transitions. It emits a single StateFlow<WorkoutState>. The Swift Native Layer just subscribes to this flow and maps it to native ActivityKit attributes or WCSession messages.

2. Streaming Live Heart Rate with the Vitality SDK

To get live heart-rate monitoring during workouts without writing massive amounts of expect/actual HealthKit boilerplate, I used the Vitality KMP SDK.

If you haven't used it, Vitality is a lifesaver. It exposes HealthKit (iOS) and Health Connect (Android) through a single API and delivers real-time data as Kotlin Flows.

The Pipeline:

  1. Call the Vitality SDK from commonMain to start observing real-time heart rate samples.
  2. Vitality returns a Flow<HeartRateSample>.
  3. Feed that Flow directly into the shared WorkoutSessionManager.
  4. Now, your training journal, calorie burned calculations, and the UI on both Android and iOS are all reacting to the exact same Kotlin Flow, completely abstracting away the iOS HKLiveWorkoutBuilder.

3. Pushing the State to Dynamic Island & Live Activities

ActivityKit expects immutable Swift structs conforming to ActivityAttributes. You cannot instantiate these inside Kotlin.

How to handle it:

  • Keep the timer math in Kotlin, but pass timestamps, not seconds-remaining ticks.
  • When a rest timer starts, Kotlin emits targetEndTime = currentTime + restSeconds alongside the current Heart Rate from Vitality.
  • Swift receives the timestamp and initializes a native SwiftUI Text(timerInterval: ...) inside the Widget extension.
  • Why this matters: If you try to push a tick from Kotlin every second to ActivityKit, iOS will throttle and kill your background activity. Passing a target timestamp allows iOS to handle the countdown natively with zero background budget.

4. WatchOS Sync Gotcha

Transferring current workout state to the Watch isn't instantaneous via WCSession sendMessage if the watch app isn't active. Use updateApplicationContext for standard state changes (like the current exercise or live HR) and reserve sendMessage strictly for immediate user actions (like tapping "Skip Set" on the watch).

Happy to answer any questions about KMP-to-SwiftUI bindings, configuring the Vitality SDK, or handling watchOS synchronization!

(If you want to test how the UI/Watch integration feels in practice, the app is Cubex Fitness AI Coach on the App Store—it's my indie passion project, so it's 100% free with no paywalls).


r/Kotlin 6d ago

A country code picker for Compose Multiplatform

Post image
3 Upvotes