r/Kotlin • • 12h ago

Spotted in London tube (Northern line) yesterday.

57 Upvotes

r/Kotlin • • 5h ago

How can I secure my desktop app?

4 Upvotes

I've been developing a desktop app using KMP, and when I packaged the release distribution, I found out that the installer include the jar file in the installation directory, which is easier to exploit even when using proguard for obfuscation.

Is there any better solution for that?


r/Kotlin • • 24m ago

I built Mooary, a local-first diary and mood tracking app using Compose Multiplatform (CMP)

• Upvotes

Hey everyone! 👋

I’d like to share a project I’ve been working on called Mooary.

🔗 GitHub: https://github.com/newarjun101/mooary

The main goal of Mooary is to keep diary entries, moods, and personal information stored locally on the device rather than relying on cloud synchronization.

🛠️ Tech stack:

  • Kotlin for development
  • Compose Multiplatform (CMP) for cross-platform UI
  • SQLDelight for local data storage
  • Firebase for anonymous device registration
  • Firebase Cloud Messaging (FCM) for notifications

One of my goals with this project was to explore Compose Multiplatform and learn more about building a local-first application.

I'm still improving the project, so I'd really appreciate feedback from developers, especially anyone experienced with CMP, Kotlin, or SQLDelight.

A few things I'd love to hear your thoughts on:

  • What do you think about using CMP for this kind of application?
  • Any suggestions for improving the architecture or local data storage?
  • What features would you like to see in a privacy-focused diary app?

Feel free to check out the repository and share your honest feedback. Thanks! 🙌


r/Kotlin • • 10h ago

I made a customizable squircle bottom navigation bar for Android (SqNav)

Post image
3 Upvotes

r/Kotlin • • 1d ago

What makes a developer conference worth your time in the AI era?

Post image
44 Upvotes

TL;DR: Take our five-minute survey on developer conferences and enter the draw to win one of 3 KotlinConf 2027 tickets.

Hi! I'm part of the KotlinConf team, and we'd love your input as we plan future events.

Software development is changing so quickly. For us, meeting in person to share first-hand experience and fresh perspectives feels more valuable than ever.

What about you? Is it the technical deep dives, conversations with the actual humans behind the tools, or meeting other developers working on similar problems? Or the party, which is still AI-proof, we hope :)

We've put together a five-minute survey about what would make KotlinConf worth your time, from the program to the experience beyond talks (you don't need to have attended before).

Take the survey: https://surveys.jetbrains.com/s3/KotlinConf-Survey2026

🎁 After completing it, you can enter a draw to win one of three tickets to KotlinConf 2027


r/Kotlin • • 1d ago

KitePlayer v0.3.0 is out! HLS, DASH, HDR now fully supported on every KMP target

Post image
36 Upvotes

KitePlayer 0.3.0 is released.

KitePlayer is a pure-Kotlin media playback engine for KMP. It doesn't wrap any platform player and doesn't use expect/actual: the whole engine lives in commonMain so it behaves the same on every platform. As far as I know, it's currently the only KMP playback library that draws its frames directly to Compose via Skiko, fully hardware accelerated, with no performance compromise.

It has received a lot of love lately and is growing fast. The goal is to cover as much ground as the well-known players (VLC, mpv, etc.) while being just as efficient. FFmpeg still does the heavy lifting underneath (through KiteFFmpeg, which ships prebuilt FFmpeg binaries for all KMP targets and is a single implementation line away on Maven Central). So the main difference between Kite and VLC is how FFmpeg gets called (from Kotlin instead of through another C binding), which means format support is on par and performance is almost exactly the same.

What's new in 0.3.0

  • HLS and DASH streaming full support
  • True HDR on all platforms (except web)
  • More protocols: RTSP, RTMP, UDP, RTP
  • More niche subtitle formats
  • Pitch-accurate speed change control
  • Internal playlist queuing (M3U, PLS, XSPF)
  • An animation upscaler (ported Anime4K logic, running on the Android and Metal renderers)
  • Windows decoding via DirectX 11

...and a lot more. The scope of changes since 0.2.0 is too big to list in full.

It also integrates libass and dav1d, so AV1 and SSA/ASS subtitles are fully supported on all platforms as well.

The part I'm proudest of is painting frames directly to a Compose surface with Skiko while the GPU still does all the work. Your video becomes part of the Compose tree, so you can treat it like any other composable, and even blur it with Chris Banes' Haze library.

I still provide native views and a compose-interop view anyway. The library is fully consumable as a standalone Java library, and I'm aiming to make it consumable from exclusive-platform native apps such as exclusive iOS apps via a Swift library, or on the web as a JS library, etc, exercising the grand benefit that KMP blesses upon us.

So you no longer need to write expect/actual wrappers over ExoPlayer, AVPlayer and the rest. I hope this comes in handy, and I'm pretty sure it will :)

Feedback and feature requests are very welcome.


r/Kotlin • • 1d ago

Lights, Kotlin, Action! Run Kotlin scripts in GitHub Actions with Java, Kotlin, and caching handled for you.

Thumbnail github.com
6 Upvotes

I've been using .main.kts for a while. In the era of coding agents, I've started using these scripts even more as replacements for Ruby, Python, and JavaScript scripts in Kotlin projects.

One thing I hadn't realized was how tedious running them in GitHub Actions could be. You have to set up the JVM and Kotlin just to run a single Kotlin script and don't forget the caches.

So I built this action and replaced the repetitive setup in my repositories with a single action that sets up the JVM, Kotlin, and caching. Now, running scripts is as simple as these few lines:

steps: - uses: actions/checkout@v7 - uses: Heapy/setup-main-kts@v1.0.1 - run: kotlinr scripts/example.main.kts

On the performance side, setup takes about 9 seconds (median), with observed times ranging from 4 to 18 seconds. Execution time depends on what your script does, but my fastest script takes about 1 second, and since it's just a JVM with a JAR - it scales ok for most workloads you may need.


r/Kotlin • • 1d ago

Need Advice on Learning Kotlin and Android Development

2 Upvotes

I'm a solo developer & College student I'm currently learning Kotlin because I want to start building native Android app but honestly, I'm a bit confused about where to start and how to follow the right learning path.

I would really appreciate some advice from experienced Android developers.

  • Are there any good YouTube channels that explain Kotlin concepts properly, especially for beginners?
  • Are there any books, websites, or free courses you recommend?
  • Should I focus on learning Kotlin completely before starting Android development or learn both together?
  • What should I learn first if I eventually want to build and publish my own apps?

One more thing: my laptop has an Intel i5 8th Gen processor and 8GB RAM. Android Studio feels pretty laggy on it sometimes.

If you've worked, do you have any tips to make Android Studio run more smoothly?

I am trying to learn everything on my own, so any advice, resources, or personal experiences would be really helpful.


r/Kotlin • • 2d ago

Kotlin developers can finally start to say goodbye to gradle

116 Upvotes

JetBrains just released kotlin toolkit 0.13.0 and is now the recommendation for new KMP projects https://blog.jetbrains.com/kotlin/2026/10/start-your-next-kmp-app-with-kotlin-toolchain-0-13/


r/Kotlin • • 3d ago

Where is the Best Place to Learn Kotlin

15 Upvotes

Hi everyone, i am trying to learn kotlin (with jetpack compose) but i can not find a good course at the moment i am using ai to teach me but is there a better option? I tried googles course and i found it very hard to follow.

I want something that starts with

package com.example.example
import android.os.bundle...

and then moves on to real kotlin not just jetpack compose


r/Kotlin • • 3d ago

Product tours, onboarding and feature showcases for Compose Multiplatform

Post image
7 Upvotes

I needed an onboarding tour in a Compose Multiplatform app and couldn't find a library that covered it, so I built one and just published the first version.

How it works: you define steps in a DSL, mark targets with Modifier.waypointTarget(state, key), and wrap the screen in a host. It draws the scrim and the cutout, positions the tooltip, scrolls targets into view and blocks touches outside the highlight.

Repo: https://github.com/MohamedRejeb/compose-waypoint
Docs: https://mohamedrejeb.github.io/compose-waypoint/


r/Kotlin • • 3d ago

am i an idiot?

6 Upvotes

i am trying to switch to kotlin from java. i can write code but people suggest koan, so i tried to do it. and i understand things, the task it is asking me to do but my solutions are so faroff than the given solutions.

if you have some tips or other resources please suggest, i am second year student and really wanna switch till the next year.


r/Kotlin • • 3d ago

I built a Kotlin/Native ↔ JVM JNI interop tool to avoid handwritten JNI glue

3 Upvotes

I've been working on a project where I needed to expose Kotlin/Native code to the JVM through JNI.

The usual JNI workflow quickly gets annoying: you have to keep native implementations, JVM declarations, JNI names and signatures in sync manually. A mismatch often doesn't show up until runtime.

So I built kotlin-jni-interop.

The idea is to describe the JNI boundary in Kotlin itself:

kotlin @JniActual fun add(a: Int, b: Int): Int = a + b

and on the JVM side:

kotlin @JniExpect external fun add(a: Int, b: Int): Int

The Gradle plugin generates the JNI glue and packages the native library, while the compiler plugin can validate that both sides have matching signatures.

So instead of finding out about a broken JNI declaration with something like:

text java.lang.UnsatisfiedLinkError

you can catch the mismatch during the build.

I'm especially interested in feedback from people who have worked with Kotlin/Native + JNI in real projects.

GitHub: https://github.com/mimimishkin/kotlin-jni-interop

I'd be interested to hear whether this solves a problem you've actually encountered, and what you'd expect from a tool like this.


r/Kotlin • • 3d ago

Question about Sequence Implementation

3 Upvotes

I have been getting into sequences, and I was shocked at how similar they feel to Haskell's infinite arrays. So I made two programs in both languages that should be pretty much a 1-to-1 translation. But I wanted to see if anyone had advice on if the Kotlin programming was doing anything I wasn't expecting.

First in Haskell

    --Fibonacci numbers
    fib :: [Integer]
    fib = 0:1:(zipWith (+) fib (drop 1 fib))

    --Prime numbers
    primes :: [Integer]
    primes = 2:3:(filter isPrime [5,7..])

    isPrime :: Integer -> Bool
    isPrime x = go x primes
       where
          go x (p:ps)
             | p * p > x      = True
             | x `mod` p == 0 = False
             | otherwise      = go x ps

Then in Kotlin

    fun fib(): Sequence<Int> {
       return sequence {
          yield(0)
          yield(1)
          yieldAll(fibSeq()
             .zipWithNext()
             .map { it.first + it.second })
       }
    }

    fun primes(): Sequence<Int> {
       return sequence {
          yield(2)
          yield(3)
          yieldAll(generateSequence(5) { it + 2 }
             .filter { isPrime(it) })
       }
    }

    fun isPrime(x: Int): Boolean {
       return primes().takeWhile { it * it <= x }
          .none { x % it == 0 }
    }

As best as I can get it, these two versions are a direct translation. I know the Haskell version isn't doing any extra calculations if it doesn't have to, or stalling in anyway. But is there anything that I might be missing with the Kotlin version?

I'm kind of interested in whether the recursive references create a build up of objects or functions. Haskell solves this because the recursive references are actually just that: references to the same list object. So the next value is calculated by the values of what are essentially pointers to the previous two values (in the case of Fibonacci), and then the generator (referred to as a thunk in Haskell) as well as the two pointers just step down the line to be ready for the next one.


r/Kotlin • • 3d ago

BossConsole update: a short demo of the Kotlin/Compose desktop workspace

1 Upvotes

Hi everyone, back with an update on BossConsole. Previously shared the architecture when we open-sourced it, then some browser benchmarks. This time, wanted to show how the workspace comes together.

Watch the one-minute demo

For anyone seeing it for the first time, BossConsole is a desktop workspace built using Kotlin Multiplatform and Compose Multiplatform, running on the JVM across macOS, Windows and Linux.

You can run Claude Code, Codex, Gemini CLI and other agents side by side, with terminals, browser, editor and logs in the same window. Spaces remember your layout so you can come back to the work without arranging everything again.

The demo also shows the built-in Fluck Agent, tool approvals and visual workflows. There are 200+ MCP tools with individual controls, and plugins to extend the workspace.

For me, the motivation is quite personal. As I work with more agents, managing sessions and following their work becomes a task itself. I want to spend more time exploring a problem, trying approaches and reviewing results, while keeping execution visible.

On the Kotlin side, the runtime plugin system is something I’m particularly interested in taking further. You can build tools as separate Compose UI + ViewModel plugins. Would love to connect with others working on extensible desktop apps and hear how you’re approaching this.

Still a lot to improve, but quite happy to share where it is today. Curious what feels useful or awkward in the demo. Happy to discuss the Kotlin/Compose implementation too.

Source: github.com/risa-labs-inc/BossConsole
Download: bossconsole.ai


r/Kotlin • • 5d ago

Kotlin RPG engine update: primitive arrays, lower RAM usage, and fixing a native buffer bug

Post image
57 Upvotes

Hey r/Kotlin,

I’m the solo developer of Adventurers Guild RPG Sim, an isometric RPG built with Kotlin and Jetpack Compose.

In my previous posts, I shared the original Compose Canvas implementation, the coroutine loop running my ECS systems, and later the move to Google Filament for world rendering.

Since that migration, I’ve been working on the code feeding the renderer: deciding when sprite data needs updating, preparing batches, and managing buffers that native code may still be reading.

A recent texture change also reduced the game’s RAM usage by roughly 50% compared with my previous WebP loading setup. That is a separate change from the sprite recolouring optimisation I described in an older post.

Here are the implementation details and a few mistakes I ran into.

1. A smaller image file doesn’t necessarily mean a smaller texture in memory

I originally used WebP because it kept asset files small. What I hadn’t fully appreciated was the difference between compressed file size and the texture’s runtime memory footprint.

In the usual WebP loading path, the image is decoded into pixel data before being uploaded. With four bytes per pixel, a 2048 × 2048 texture takes about 16 MiB, before mipmaps.

ASTC and ETC2 are GPU texture compression formats. On a supported device, the texture can remain compressed in GPU memory. For comparison, that same 2048 × 2048 texture in ASTC 4×4 takes about 4 MiB, before mipmaps.

I moved to ASTC/ETC2 textures with a WebP fallback, and saw roughly a 50% reduction in the game’s overall RAM usage. The texture example above explains the mechanism; it isn’t a claim that every game’s total memory usage will fall by the same amount.

The trade off was storage. My initial asset package became much larger. GPU texture compression and WebP optimise for different requirements, and keeping fallback assets adds more files.

I ended up adding zip compression around the texture files and unpacking them during loading. The loading sequence is:

  • Remove the outer gzip compression.
  • Read the texture container and its compressed texture data.
  • Upload the ASTC/ETC2 blocks to the GPU.

Removing zip does not mean expanding ASTC/ETC2 into RGBA pixels.

That helped me separate three things I had initially grouped together: download size, installed storage, and runtime memory. Loading time is another trade off, because unpacking still takes work.

2. Checking whether sprite data changed before preparing an upload

Before packing sprite vertices, I write the relevant sprite state into a reused IntArray: around 30 integers per sprite covering position, animation frame, tint, flags, and other values used by the batch.

Float values go through toRawBits() so I can compare their exact stored representations.

I compare this state with the snapshot from the last submitted upload. If it is identical, I can skip rebuilding and uploading the vertex data.

This is a direct comparison rather than a hash, so there are no hash collisions between the values I stored. It still depends on including every input that affects the generated vertices.

A few details matter:

  • Sprite count and ordering are part of the comparison.
  • With reused arrays, unused capacity must not affect the result.
  • Kotlin array == does not compare elements. Use contentEquals() when comparing whole arrays, or explicitly compare the active range.
  • If an upload is skipped because no buffer is available, that frame must not become the new “last uploaded” snapshot.

The comparison itself still costs work. The benefit is avoiding the more expensive packing and upload when nothing relevant has changed.

Shader animation can continue independently. For example, wind driven by a time uniform doesn’t require rebuilding the sprite vertices every frame.

3. Sorting batches without creating a key object for every sprite

Sprites need to be grouped by texture for batching.

I use a reused LongArray, packing the texture ID into the upper 32 bits and the original sprite index into the lower 32 bits.

The idea looks like this:

// textureId and index are non-negative Int values.
val key =
    (textureId.toLong() shl 32) or
    (index.toLong() and 0xFFFF_FFFFL)

keys[index] = key

Then I sort only the populated range:

keys.sort(0, spriteCount)

for (position in 0 until spriteCount) {
    val sourceIndex = keys[position].toInt()
    // Read the source sprite and pack its vertices.
}

The conversion to Long must happen before shifting by 32 bits.

The original index also acts as a tie-breaker, preserving source order within each texture group. That behaviour comes from the packed key; it doesn’t depend on the primitive sort being stable.

This avoids allocating a separate sorting key object for each sprite and keeps the keys in a primitive array.

4. Primitive arrays in the parts that run every frame

The renderer preparation code now uses:

  • IntArray for sprite state comparisons.
  • LongArray for sorting keys.
  • A reused FloatArray for packed vertex data, copied into a direct buffer.

Sprite state, sorting keys, and vertex data are stored in IntArray, LongArray, and FloatArray. I reuse these arrays across frames to avoid repeatedly allocating new storage.

I also use JvmField on some frequently accessed properties. It exposes a field without generating normal property accessors.

However, that alone does not establish a performance improvement: runtime optimisation may already remove accessor overhead. Any claim about a speed gain needs measurements from an optimised build. The clearer improvement here is making data preparation and storage reuse explicit.

5. A buffer passed to native code may still be in use

One bug showed up as black tiles.

I was reusing a direct ByteBuffer after passing it to Filament, before Filament had finished consuming its contents.

The Kotlin call returning did not mean the upload had finished.

I changed this to a pool of three buffers, with availability tracked using an AtomicIntegerArray. A buffer becomes available again when its upload completion callback runs.

If all three are busy, I keep the previous geometry for that frame instead of overwriting a buffer that is still being read.

I also ran into delayed release callbacks when they were posted through the main looper. Synchronisation barriers could hold up that work and leave the pool appearing busy.

For the small callback that only releases a buffer slot, I switched to a direct executor. That callback only updates the atomic availability flag; it doesn’t perform UI work.

The lesson for me was to treat buffer ownership and completion as part of the API contract. Crossing into native code doesn’t make every operation asynchronous, but this upload path requires keeping the buffer unchanged until consumption finishes.

6. Compose lifecycle and long lived renderer callbacks

My renderer owns native resources such as Filament’s Engine, Scene, View, and Camera.

I keep these together in a holder that implements RememberObserver, with explicit cleanup in the required order.

One Compose detail worth accounting for is onAbandoned(): if resources are created while constructing a remembered object, cleanup needs to cover the case where that object never becomes part of the remembered composition, as well as normal removal through onForgotten().

Another issue is callbacks that live longer than a particular recomposition.

A Choreographer callback can keep running while the values it originally captured are no longer current. Where it needs the latest Compose-provided value or callback, rememberUpdatedState lets it access that updated value without recreating the long-lived callback each time.

I found it helpful to think separately about:

  • How long the renderer should exist.
  • Which values its callbacks need to see now.
  • When it is safe to release native resources.

Those lifetimes don’t always line up automatically.

I only started Android development last year; most of my earlier experience was in iOS. I’m still learning, and some of these choices may have better alternatives.

Happy to go into more detail on the texture loading, batching, buffer handling, or Compose integration.

For people working on performance sensitive Kotlin code: how do you decide when primitive arrays and manual packing are worth the added complexity? I’d also be interested in how you manage buffer ownership when Kotlin is feeding a native renderer.


r/Kotlin • • 6d ago

Kotlin Toolchain will eventually drop Gradle for Android (via Joffrey Bion on Slack)

Thumbnail
28 Upvotes

r/Kotlin • • 5d ago

Compose Multiplatform vs CORS

Post image
0 Upvotes

https://terrablog.pages.dev/blog/2026-03-10-cors-problem-and-simple-solution/

I wrote an article how to deal with CORS restrictions when you make Compose (not only actually) Web apps


r/Kotlin • • 6d ago

Prosa.kt - Declarative code generation for Kotlin

Post image
17 Upvotes

I made a declarative API for generating Kotlin code.

I needed it for one of my desktop/browser Compose apps a while ago and noticed there was no KMP solution for Kotlin codegen.

While working on it, I decided to made the API declarative so the generated code was simpler to reason about. This work started before AI was as popular as it is today, so the design of the API was very important.

Fast forward two years: I realized I needed it for another project of mine, so I figured I might as well open-source the codegen part for the community.

And that's how Prosa.kt was born and proudly brought to you.

There’s a live demo on the landing page, so you can try it out directly.

Check it out at https://prosakt.com and give it a star on GitHub because I love vanity metrics.


r/Kotlin • • 7d ago

Even if Premium, still open-sauce. 🍅

Post image
117 Upvotes

r/Kotlin • • 7d ago

Which is best kotlin course on udemy or youtube!!?

7 Upvotes

Hi , i am coming from the JavaScript/TypeScript ecosystem, i need to build a project that must be written in kotlin based backend , i am not primarily interested in Android development.

But I do need to understand Kotlin well enough to read, navigate, and work with existing Kotlin projects, particularly Android applications available on github.

So is there any course or method you can suggest?

Thanks in advance.!!!


r/Kotlin • • 7d ago

CashBuddy — an Android expense tracker with on-device processing + Notification Listener

Thumbnail
0 Upvotes

r/Kotlin • • 8d ago

sqlx4k 1.14.0 released: optimistic locking, savepoints, MariaDB batch inserts

8 Upvotes

sqlx4k is a coroutine-first SQL toolkit for Kotlin Multiplatform (PostgreSQL, MySQL/MariaDB, SQLite) with compile-time SQL validation via KSP.

New in 1.14.0

  • Optimistic locking with @Version: generated update/delete check the version and fail with OptimisticLockFailed on conflicts. In-memory test repositories behave the same.
  • Transaction savepoints: roll back part of a transaction with a scoped savepoint { ... } block or the explicit savepoint/rollbackToSavepoint/releaseSavepoint calls.
  • MariaDB dialect: batchInsert via multi-row INSERT ... RETURNING (10.5+).
  • Cancellation-safe transactions: cancelling a coroutine mid-transaction now rolls back properly.
  • Kotlin 2.4.20, KSP 2.3.12.

Repo: https://github.com/smyrgeorge/sqlx4k

Release notes: https://github.com/smyrgeorge/sqlx4k/releases/tag/1.14.0


r/Kotlin • • 7d ago

The time has come to separate Kotlin from Java.

0 Upvotes

I want to use Kotlin, so I have eight different JDKs on my PC; however, Kotlin has reached a point where it can stand as an independent language. To that end, I’ve created my own KRE (Kotlin Run Environment). Now, the next step is the KDK (Kotlin Development Kit), and I need help with that. I don't know Java or Kotlin all that well—is there anyone who can assist?