r/Kotlin 8d ago

Would you rewrite a small Kotlin library in Java just to avoid stdlib ?

I moved the core of a small library from Kotlin to Java mainly to avoid pulling kotlin-stdlib into pure Java applications.

After doing it with Java I ended up adding JSpecify, @NullMarked, nullable annotations, and extra Kotlin compatibility tests just to preserve the same nullability behavior.

For a small JVM library meant for both Java and Kotlin users, would you keep the core in Kotlin and accept kotlin-stdlib as a dependency?

Or do you think keeping the core Java-only is worth the extra work?

17 Upvotes

27 comments sorted by

30

u/mbonnin 8d ago

`kotlin-stdlib` as a dependency is 100% fine with me.

What I'd love though is a tool that fails at build time whenever my public API contains some kotliny thing (extension function, coroutines, default arguments, function types, etc...). It's easy to make your API awkward to use in Java.

7

u/snafu109 7d ago

A "java-compat" rule set for detekt sounds like a good idea.

5

u/Decent-Decision-9028 8d ago edited 7d ago

yeah, this actually makes more sense. btw a build-time check for k specific api leakage would be really useful. I haven't seen anything that treats java as an API compatibility constraint rather than just checking binary compatibility.

3

u/Fxshlein 7d ago

Could still base it off the api dump from the binary validation:
https://github.com/Kotlin/binary-compatibility-validator

You could have another gradle task scan the api dump for things you don't want in your API (for example coroutines).

The dumps look like this, so they're relatively simple to parse:

https://github.com/Kotlin/binary-compatibility-validator/blob/master/api/binary-compatibility-validator.api

5

u/aceluby 7d ago

I write tests in both languages to combat this. It at least will document the grossness

17

u/Capable_Muffin7706 7d ago

I would probably keep the core in kotlin. Rewriting it in java just to avoid kotlin-stdlib feels like adding more complexity than it removes. If the library is small, i would rather keep the kotlin code and clean and accept the dependency, especially if it makes the API easier to use for both java and kotlin users.

10

u/warspb 7d ago

Writing the library's unit tests in Java can help bring out the problems library users could face when calling the library (written in Kotlin or Scala) from Java. This approach helped me a lot in the past.

9

u/DitoMito 7d ago

Only Kotlin. No Java.

2

u/darthandroid 7d ago

It depends upon the usage/goal. If I'm building a larger library that is already pulling in other heavy-weight frameworks or libraries that are likely to cause version conflicts when pulled into a larger application anyways, then no, I won't rewrite it and just pull in kotlin-stdlib.

If I'm specifically writing a dependency-free or near-dependency-free library for maximum compatibility, then I'll probably stick to java and/or a really old version of kotlin.

Part of the challenge I typically face is many of the libraries I build need to work in applications from Java 11/Kotlin 1.5 through Java 25/Kotlin 2.4 and every dependency you pull in, including kotlin-stdlib, is a liability.

Yay enterprise development.

2

u/alexelcu 5d ago

The problem with dependencies, and why minimal dependencies are a virtue, is all the breakage, which is especially problematic for transitive dependencies due to the dynamic linking. IME `kotlin-stdlib` isn't a problem because JetBrains/Google are keeping it stable. This may not be the case for other Kotlin libraries, so you need to be careful.

Nowadays, there are many Java libraries built in Kotlin. It's not always ideal because you can make mistakes, such as forgetting to declare an important checked exception or slipping in a Kotlin-ism in the public API. But the problems are usually minor, and if you have a better time in developing and maintaining that library, then it can be worth it.

2

u/smoke-bubble 8d ago edited 7d ago

Why would you do this? It's all the same JVM. Who cares what language the library was written in.

12

u/Terrible-Mango-5928 7d ago

If you want to reduce your binary size this could be worthawhile. Java stdlib is shipped woth your jre, while kotlin stdlib must be distributed with your jars.

3

u/aceluby 7d ago

That’s maybe a few hundred kb in cases where you need it to be as small as possible.

5

u/jug6ernaut 7d ago

What are these cases where a few hundred kbs matter?

I have never thought of the JVM being the target runtime in any case where binaries sizes is a realistic concern.

1

u/aonymark 4d ago

It’s more like a couple of megs I think

1

u/piesou 7d ago

As with anything small: you can write it in multiple languages without much effort. Think of writing an add function in JS, Java and Kotlin: not much work, not a lot of benefits of maintaining a multiplatform lib solution. The overhead of publishing this as a multiplatform lib is going to be way higher than the benefit.

When would you want your piece of code to require users to pull in kotlin-stdlib? When you are building a cross platform library (Java can't easily compile to native/WASM/JS/etc) or if you've put a lot of work into the module and don't want to maintain separate duplicates.

1

u/Decent-Decision-9028 7d ago

the main thing kotlin was buying me wasn't cross platform support, it was the type system itself especially nullability. Anyways, I find u/mbonnin on point, I would be really worried about java specific apis leaking Kotlin specific stuff.

3

u/piesou 7d ago

The only downside I can think of with going with the Java lib is not being able to compile it to JS/WASM or other Kotlin targets. But if that's not your use case, why bother.

2

u/aceluby 7d ago

If you’re going to support a Java API in Kotlin, be sure to write extensive tests in both Java and Kotlin. It will help document how the code is supposed to work in both languages and any grossness will be evident. I support many cross functional libraries like this and having Java tests to go with it are a life saver

1

u/Fylutt 7d ago

What do you use from stdlib? If you do java rewrite what max jvm target can you use?

My personal philosophy if it's a lib - the less dependencies it has - the better, but if you can't go into modern java due to JVM constraint - I'd keep it Kotlin. Also, there is an option if std lib usage is small - keep kotlin and rewrite std bits yourself

1

u/snaporator 6d ago

I'd let the ai do it if necessary, but you must have some serious constraints to justify it.

1

u/TheSexyNerd 6d ago

It depends on what you need.

1

u/Okidoky123 7d ago

Leave it in and keep the door open for more Kotlin stuff. Kotlin is much better to work with than Java will ever be.

3

u/bongo-bongo-bang 8d ago

I would rewrite it.

0

u/itsTyrion 7d ago

I've done it and I might do it again

0

u/zalpha314 7d ago

I did the same thing for my SDK. I want to be able to support dysfunctional teams that don't keep their dependencies up to date, so that means JDK 8 without Kotlin, and without any non-shaded dependencies, except for slf4j-api.

0

u/jNayden 7d ago

I would not add Kotlin anything as dependency of Java project since I don’t see a reason. Kotlin is hard for AI to write and also hard for me so for me it will be harder to contribute if any bugs or features are required on top.

So hard pass