Out of curiosity, how many of you are using Kotlin for backend development? It seems that Java has caught up a bit, and the advantages of Kotlin (extension methods, better syntax, better null-checking) might not be enough to justify the risk of lock- in?
Personally, I quite like Kotlin, but I haven't been able to convince most of my greybeard colleagues to make the leap.
Tmpod · 1d ago
I think those features are quite good on their own, but Kotlin has many more worthy features, such as sealed hierarchies, import aliases, delegation, operator overloading, default arguments, named arguments, reified generics, inline value classes (though somewhat limited by JVM features still), a very nice stdlib (in part augmenting Java's stdlib), etc. Even newer stuff like context parameters are really interesting and have useful applications.
The language ends up being more complex, but I find it a joy to use; going "back" to Java projects always leaving me wishing I could use Kotlin instead :P
Yet it's true, Java has improved quite a lot in the last decade. It is ahead of Kotlin in a few things, like pattern matching (though not incredible, it's still better than the nigh nonexistent support in Kotlin).
Defletter · 17h ago
Kotlin can be fairly pleasant to write but it's so incredibly unpleasant to inspect. For example, Ktor is the Kotlin backend framework, but good luck figuring out how any of it works. It's a complete mess of "higher-order functions", extension methods, and other abstraction-hell as to make it extremely difficult to figure out what is executed when and under what circumstances. Basic Kotlin code is fine, great even, but once people stop writing Kotlin as Java developers, but as Kotlin developers, then it goes downhill fast.
Tmpod · 3h ago
Can't speak about Ktor in particular, but most DSLs I've used are essentially just syntax sugar for the builder pattern, stream-like APIs and so on.
I don't think it's bad per se, you just have to think a bit differently when you're inspecting code.
But again, could be wrong about Ktor specifically.
jackpeterfletch · 59m ago
Interesting. Coming from Spring to Ktor, being able to easily inspect the internal workings has been one of my favourite bits!
It’s ‘advanced’ kotlin in there for sure, and takes some learning of the internal plumbing, but having everything not hidden behind annotations has been great.
Just a CMD+click on whatever Ktor DSL/plugin API your using and you can immediately start to follow along / debug what it’s actually doing.
ragnese · 1d ago
EDIT: Forgot to confirm that I do, in fact, use Kotlin for a fairly large and moderately complex backend system (multiple deployed systems, including one HTTP REST-ish API).
I'm of two minds about it.
I started working with Kotlin back when Java was still a very ~~stagnant~~ stable language. I definitely find Kotlin's syntax to be much more comfortable, expressive, and in many ways much more simple than Java's.
But at this point, the only big technical features that still put Kotlin over Java for me is the handling of nulls by the type system (which is, admittedly, mitigated decently well in practice by Java tooling configurations and ugly annotations), and value types (zero heap-allocation wrapper classes).
Another thing to keep in mind is that now that Java is actually adding features again, the Kotlin developers will have to also play "catch-up" to Java in ways that it didn't have to when it first gained popularity. It puts Kotlin in an awkward spot when Java's implementation of sealed classes and interfaces was initially better and more flexible than Kotlin's, or when Java's `switch` is now more powerful than Kotlin's `when`, etc.
Kotlin is also betting heavily on their multi-platform stuff, which I'm skeptical about. It seems to me that it will further slow the ability to add useful features to the language if you have to cater to the lowest-common-denominator between Java and JavaScript (and Objective-C? -is that how it works for iOS?) runtimes. Instead of being the best language for a given platform, it'll just be a pretty good language for a few platforms. I wish them all the best in dethroning JavaScript from infecting every computing platform and domain, but I'm just skeptical.
So, honestly, I don't actually recommend people start new projects in Kotlin. I'd suggest going for Java, or something that's meaningfully different in semantics and philosophy like Clojure or Scala. I say this, but I'm not actually sure that I'd be able to follow my own advice, because I really don't want to have to stomach Java's syntax, idioms (way too many annotations), and stupid null handling.
vips7L · 1d ago
>but at this point, the only big technical features that still put Kotlin over Java for me is the handling of nulls by the type system
The one feature that keeps me in Java, albeit not popular, is checked exceptions. I far prefer checked errors over checked nulls if I have to make a choice.
ragnese · 1h ago
I'm with you when it comes to checked exceptions. I have several ranty comments on this site about how everyone has been wrong to cargo-cult hatred of the feature for the last decade or so.
But, I'd still rather have safe/correct null type checking, because at the end of the day, I can always write MY code to return a Result/Try/Either type instead of throwing unchecked exceptions for expected business logic "failure" paths.
It’s actually my #1 issue. I hate not knowing about error conditions and no one in Java uses checked exceptions because the language syntax for dealing with them sucks. Brian had a proposal for handling exceptions in switch but it seems to have died in the water.
Part of me secretly hopes Swift takes over the world because they have a typed throws that works and handling errors is a breeze.
Defletter · 14h ago
While I am certainly a fan of Swift's error handling and think it'd be an improvement to Java's current state of affairs, I do think that using null as an error analogue is... unwise. What happens when a function is throwable but also may return null? How do you determine whether the null is a coerced error or a valid return? Or rather, how do you do this without returning to the un-ergonomic try-catch? Zig solves this by having errors and nulls be separate parts of the type system which you can deal with separately and inline.
vips7L · 13h ago
You don't coerce it. You don't care in that situation. That's the whole point. You're saying you don't care and are going to use null. If you care, you don't use try! you do the more verbose catching:
let i: Int?
do {
y = try someThrowingFunc()
} catch SomeError.err {
y = nil
} catch SomeError.youCareAbout {
//
}
Defletter · 12h ago
You misunderstand. In the question given, we don't care about the error, only that an error having occurred is detectable. In Rust, this would be represented as: Result<Option<ExampleType>, ()>, whereas using try? would reinterpret the error as a null, so there's no way to tell the difference between an error-as-null and a returned-null.
This has consequences for config parsing, for example, where a particular subsection (sub-object? keyed struct?) may be optional, so it being missing is perfectly legal. But if you use try?, then there's no way to distinguish between it simply being missing and it being present but malformed. It unfortunately seems like the only other options in Swift is to propagate the error, or revert back to verbose try-catch blocks.
Whereas, in Zig, you can do inline catching and care about the error only as much as you want to, for example:
// This is equivalent to Swift's try
const i: ?i32 = try someThrowingFunc();
// This is equivalent to Swift's try?
const i: ?i32 = someThrowingFunc() catch null;
// This is a yielding inline catch block that does not care about the error
const i: ?i32 = someThrowingFunc() catch brk: {
logger.warn("Something went wrong!");
break :brk null;
}
It's not perfect, I don't love the block-label-break thing, but I much prefer this if only because then the variable can be defensively const, which I do not believe is possible with the kind of code snippet you provided. Also, instead of breaking out, it could capture and return the error or return a new error. It's incredibly versatile.
vips7L · 4h ago
I’m not misunderstanding. You weren’t making a point about _verbosity_ originally. You were talking about distinguishing errors you care about; which is perfectly possible, you don’t use the construct that says “I don’t care what error it is”.
ItsHarper · 12h ago
It's not compiling to Objective-C, it's compiling to machine code with a garbage collector packaged in, (similar to go, I think it would be fair to say).
esafak · 1d ago
I do, because the Java ecosystem (which includes its programmers) is always going to have one foot in Java 8; it's the prototypical enterprise language.
ragnese · 1d ago
That's a fair point. You don't have to write Java with giant graphs of objects-in-objects-in-objects and heavy mixing of (often mutable) data and logic in the same classes, but it's hard to deny that the culture, conventions, and idioms in the Java ecosystem can be quite different from the culture, conventions, and idioms in Kotlin.
On the other hand, when I see Kotlin code that's not written by JetBrains (especially on the backend), it often does just look like Java code with cleaner syntax...
clumsysmurf · 1d ago
I am also worried about the concurrency side of Kotlin. Since Roman Elizarov, the architect of the coroutine / flow implementation, left JetBrains two years ago, it seems to be stagnant. Looking through the tracker conversations I almost get the impression whoever inherited it doesn't know where to take it next.
ragnese · 1d ago
That's a whole huge can of worms, too. Coroutines and the suspend keyword were a great innovative feature at the time (very clever implementation on the JVM and good API design given the limitations of the implementation and syntax design constraints), but now that Java has so-called virtual threads, you don't "need" Kotlin for convenient(-ish), simple(-ish), scalable, structured concurrency like you used to, either.
One could rightly debate over whether Kotlin's coroutines design and APIs are better than Java's virtual threads for writing asynchronous code. But, at the core, the story used to be that Kotlin had coroutines and lightweight structured concurrency "built-in" (with a blessed first-party helper library for the actual concurrency part) and Java did not have anything that accomplished the same goals. Now it does.
No comments yet
gavinray · 1d ago
Vsevolod Tolstopyatov (https://github.com/qwwdfsad) is the other brain behind Coroutines, Concurrency, and Atomics in Kotlin, and he's still very much active.
Many larger companies in The Netherlands have moved away from Scala and Java and use Kotlin now. The switching costs are neglegible and the benefits are big.
The problem with Kotlin is, you don’t want to go back to Java.
litmus-pit-git · 12h ago
Hey. Do you folks have office in India or are you hiring remote for Kotlin? (esp. someone from Android bg but pretty decent at general Kotlin; and also at Java)
glasskaar · 1d ago
My workplace of ~3k employees has Kotlin as the golden path for our backend services. We previously mainly used Java, but I think it's been Kotlin for almost every new service since 2018. I think it works great for us.
simon_void · 9h ago
at the (semi-state owned) company (in Germany) I work at, Kotlin is a first-class language also for backend. It depends on the teams wheather they prefer Java or Kotlin. I'm firmly in the team-Kotlin camp and Java code that becomes my responsibility has the strong tendency to suddenly become Kotlin code. By the way, I never worked on Android, so all my Kotlin work (since 2019) was server-side Kotlin.
Java is getting better, so maybe in 10 years it'll be a less ergonomic Kotlin variant.
PSS: Jetbrains is actually working on an official Kotlin-lsp server: https://github.com/Kotlin/kotlin-lsp So devs in the near future won't be locked into the IntelliJ ecosystem, if that is a concern of yours.
kevinherron · 1d ago
We use it for (non-Spring) backend development. It's lovely and always my first choice over Java.
I like to avoid mixing Java/Kotlin within the same module when I can, but it still works, and parts of our codebase are mixed this way. (by module I mean e.g. the same Maven or Gradle module, i.e. try to avoid a situation where you have a `src/main/java` and `src/main/kotlin` next to each other)
selimco · 1d ago
You can put kotlin code in src/main/java
mx_03 · 1d ago
We use it for backend. F500 company.
There is almost no locking with Kotlin. You can stop writting Kotlin code any time and start writting Java code.
However I think it's not possible to call coroutine code from Java.
cogman10 · 1d ago
Exactly why we use it. Our java devs have been able to pickup and start writing kotlin. None of them have regretted it that I've seen.
It's extremely close to Java in terms of most concepts. That makes it an easy language to switch into and out of. It's java with a nicer syntax and more sugar.
jasonmarks_ · 1d ago
I do not have an opinion on if Kotlin is great as a backend for every project. Kotlin does excel as a pick for projects where you are also compiling for native mobile front ends.
Write a Kotlin multiplatform client side business logic module in tandem with your Kotlin backend. The multiplatform module compiles for both your Android and Apple environments and for extra flexibility you are able to quickly port code from the client business logic module to the backend (or vice versa).
stefs · 1d ago
i use kotlin at work mainly for frontend development, but i choose it for almost all projects i have control over (i.e. personal projects which are usually backend development and smaller scratch-an-itch tools at work). that said, i haven't re-evaluated pure java in a long time, but i'm pretty sure i'd still miss many of kotlins features.
RamblingCTO · 1d ago
We did and it's awesome. Normal SaaS startup-sized codebase. Migrated from java maybe 4 years back. Was so perfect that you could migrate file by file. Later on we split up the codebase via gradle modules. Very very happy with that! Java will never get where kotlin is. It's a perpetual catch up game.
dzonga · 12h ago
kotlin is nice for backend development if you're using quarkus or springboot.
don't use ktor etc where some people wanna take their scala religion and put into kotlin.
kotlin is nice is you keep is super simple. use it the same way as you do Golang and you will find it pleasurable.
simon_void · 6h ago
i've used ktor for 2 small-ish microservices. It's fine. I was curious about corouitnes. I know SpringBoot has support for corouitnes as well, but in ktor it's front and center. (Disclaimer: I never used Scala)
killingtime74 · 1d ago
Atlassian uses Kotlin extensively. Thousands of developers working on JIRA, Confluence and other associated products.
rileymichael · 1d ago
i've been writing kotlin since 1.0 (2016) and my past few jobs have been at startups using kotlin entirely on the backend. it's really enjoyable, there isn't another language with as good of a development experience due to Jetbrains controlling both sides.
coroutines are the biggest downside imo. they're great for android and other environments, but now that we've got loom on the jvm they're needlessly complex (accidental blocking calls, coloring, headaches with libraries that use thread locals, reentrant lock, etc.)
There are many systems written in Cobol, Delphi, C++, that would really benefit from not being written in those languages.
There are serious headaches to be had when you have to maintain software for ten years and up.
Porting systems to another language is often terribly expensive.
jillesvangurp · 1d ago
I'm a bit opinionated here and I know some people will disagree. But being a grey beard myself (50), I don't disagree with your sentiment here. People tend to get stuck in their ways as they get older. And I've observed a lot of people my age resisting anything new (languages, frameworks, anything that's newer than what they learned 20 years ago.
Working with younger people exposes that quite mercilessly and I can recommend doing that if you catch yourself doing a lot of repetitive projects with people well over 40. Try something new if you want to stay relevant. Move on if your colleagues can't deal with that. It's only going to get worse with them.
I've been using Kotlin with Spring boot for backend development since 2018. I did Java before that; since 1995. Java has indeed improved and was probably nudged along by what Kotlin and Scala and other languages have done. But it hasn't really caught up properly IMHO. Everything Kotlin does right out of the box (intentionally, to fix what Java did wrong here), Java continues to do wrong out of the box and this is actually a big deal because it does a lot of important stuff wrong mainly for compatibility reasons. That's the big biggest difference. These are things that Java cannot fix in a backwards compatible way. That alone is a good reason to switch.
Examples of this are that it makes code less null safe, non final, introduces unnecessary mutable state, etc. Kotlin allows you to do these things when you need to but it defaults to things being closed, final, val (instead of var), etc. And these are just things that Kotlin has been doing right since it's first releases. It has progressed a lot since then.
If you like verbosity and don't want access to the countless convenient extension functions, DSLs, co-routine support, etc. that e.g. Spring ships for Kotlin, go for Java. In they end you kind of do the same things. But IMHO in a needlessly verbose and clumsy way.
But you are missing out. IMHO anything to do with Spring Flux is just an order of magnitude easier via Kotlin and co-routines and IMHO even attempting to use that from Java is misguided. But in Kotlin, you can hardly tell the difference with non reactive code. With Java, this turns into a mess of leaky abstractions, function chaining, and lots of boiler plate. Our server is effectively using only a handful of threads with lots of websockets, connections, background processing etc. happening.
Reactive/async stuff across all of the mainstream Java server frameworks is well supported from Kotlin and has been for many years. E.g. the co-routines library ships with lots of extension functions for just about anything you can name. The green thread stuff Java does is often cited as a thing that closes the gap. But from a Kotlin point of view it's just something that makes using legacy Java code a bit less tedious.
Jetbrains and Spring did some joint announcements at the latest Kotlin conf. The upcoming major release of Spring Boot is going to be even more Kotlin heavy and centered than the current one is. And honestly, you had a superior experience with v1 way back even. They won't abandon Java support. But at this point, you are really missing out if you are sticking with Java. There are non technical reasons for doing that but very few (if any) technical reasons.
They are doing a big push with the new release on making nullability checks on all the Spring Java stuff stricter for Kotlin and making sure Kotlin does the right things. And all their documentation was already dual Kotlin/Java but looks like it might be leaning towards Kotlin first going forward.
Many reasons to like Kotlin. If somebody tells you it's Android only that was never true and there's a lot of quiet Kotlin usage with anything Java because there's not a single Java framework that you can't seamlessly use from Kotlin. And almost universally it's a better experience. The older the better actually. Because the old one tend to not use any of the new Java features. Where new is introduced in the last 15 or so years.
foobarian · 1d ago
I think the Spring support is not highlighted enough. It is very good, among other things OpenAPI client code generation is very good out of the box.
LennyWhiteJr · 1d ago
Almost my entire org uses it for backend server development at Amazon. There is very strong support for Kotlin support within the Amazon dev community.
corytheboyd · 1d ago
Been in a weird position where I had to learn Java real fast, then learn Kotlin real fast to replace it. I find Java to be so incredibly unproductive compared to Kotlin, for all the reasons a sibling comment listed. I mean come on, default argument values and named input parameters are table stakes— it kills off the billion overloads, billion positional arguments, annd builder pattern nonsense all at once. Kotlin immutability by default is fantastic, I am 1000% behind default immutable data structures. The stupid, awful nullability madness disappears (mostly, need to train people to never use ! and !!). I appreciate Java, it got us to Kotlin, but Kotlin is ACTUALLY FUN to use, and expresses all ideas I have cleanly. Less, cleaner code just makes things easier to maintain, full stop.
jamesgasek · 1d ago
It is used extensively at Amazon
darthrupert · 1d ago
As a Rust enjoyer, I wouldn't get into Java at least without being forced to (better is not good enough in this case), but Kotlin seems neat. The only thing that has been blocking trying it out is that the non-IntelliJ experience has been rather poor.
One of our ex developers was a big kotlin fan and enabled it in every java/maven project he touched -that is actually quite easy and interoperability between java and kotlin is fine. He also refactored every class he touched to kotlin. After he left, no one else was really into continuing his work. Our mobile devs use kotlin though and they are happy.
I'd say it's nice and I would actually start every new (spring/java) project I do in kotlin now. But for existing projects, I actually see no value. It does not magically make code easier to understand and it doesn't reduce bugs, it's just a bit more fun and challenging to write and pads your resume...
We did have one issue where upgrading the kotlin version from 1.x to 2.x in a project broke all depending projects due to a classfile version issue though. I deferred it by just forcing the version back to 1.x. That's the kind of annoyance you can encounter.
simon_void · 6h ago
I know one of these developers as well! It's me :D
gavinray · 1d ago
Raises hand
sannysanoff · 1d ago
when you do LLM-assisted coding in Kotlin, it burns 2-3 times less tokens than Java!
PROFIT!
jascha_eng · 1d ago
The worst thing about kotlin is the intellij lock in. VSCode support is exceptionally poor and that makes using modern AI tooling (like cursor) a pain.
kle · 1d ago
I agree, but I can strongly recommend Claude Code with the Intellij plugin. Actually works pretty great for kotlin!
And, JetBrains finally started working on an open language server. It's not perfect but it makes it bearable to at least edit Kotlin in Cursor/VS Code.
I just have Cursor open in another window for the agent mode while I do my editing with intellij (or other jetbrains products).
I would never voluntary do any editing in VS Code or forks of it. It is just so slugish on large files. Plus there is always subtle things that annoy me, I can't even describe it, it just feels off. I hope Zed takes off as it is a bit more tolerable though still not there yet.
jlengrand · 1d ago
Won’t be true for long any more since they just officially announced they’ll be releasing the language server.
PaulHoule · 1d ago
Java has also improved greatly since JDK 7 so the need for JDK languages that are Java, but just a little better, is less than it was.
BrandonSmith · 1d ago
Kotlin ecosystem extends way beyond the Java runtime. I have apps developed in Kotlin running in browsers and iOS, in addition to Android.
smith7018 · 1d ago
Kotlin is much better than "Java, but just a little better."
c03 · 1d ago
Kotlin has everything. A language isn't better just because it has more.
No trailing lambdas, no infix operators, no @DslMarkers, no top level functions, and an infinite list of examples of Java verbosity making even the smallest thing look like an ancient greek epic. Java is utterly terrible for DSLs.
vips7L · 1d ago
Language {
oh {
yes {
Java {
isSoNice
}
}
}
You can contrive awfulness in any language.
PaulHoule · 22h ago
The awfulness of one style of Java DSL is the awfulness of Lisp, that is
building(of(S("expressions"),everything())
vips7L · 20h ago
Not going to lie, my brain doesn't really comprehend lisp. So the joke (or point?) is way over my head.
llm_nerd · 1d ago
When did you last use IntelliJ? It has excellent AI tooling.
cruz101 · 3h ago
curious why this is being shared? Ive been using detekt for kotlin backend projects. It gets the the job done. Is there some new release or feature?
robch · 1d ago
I have been using detekt for work and personal projects for years now. Writing advanced lint rules that take advantage type resolution makes it the best linter for Kotlin. I just hope they get k2 support soon.
LennyWhiteJr · 1d ago
I love Detekt! It's particularly good for enforcing project conventions that can't be covered with standard linters. With access to the full AST, you can basically enforce any kind of rule you want with custom analyzers. And LLMs take out 90% of the effort for creating new analyzers.
esafak · 1d ago
Do you use it in CI? Do you have a template or something to share?
LennyWhiteJr · 1d ago
Yeah, it's included as one of the gradle scripts which fails the build in CI if the rules don't pass.
No template, as it's specific to my team's project, but one example is that we enforce that classes within our core domain don't import types from outside the project. You could accomplish this with separate projects, but that comes with its own complexities. This rule basically says "any domain type shall not import a non-domain type".
Sometimes people post the same link to HN for weeks, and nothing happens. Suddenly after 10th try, trend catches up, and the same link is on the main page.
Personally, I quite like Kotlin, but I haven't been able to convince most of my greybeard colleagues to make the leap.
The language ends up being more complex, but I find it a joy to use; going "back" to Java projects always leaving me wishing I could use Kotlin instead :P
Yet it's true, Java has improved quite a lot in the last decade. It is ahead of Kotlin in a few things, like pattern matching (though not incredible, it's still better than the nigh nonexistent support in Kotlin).
But again, could be wrong about Ktor specifically.
It’s ‘advanced’ kotlin in there for sure, and takes some learning of the internal plumbing, but having everything not hidden behind annotations has been great.
Just a CMD+click on whatever Ktor DSL/plugin API your using and you can immediately start to follow along / debug what it’s actually doing.
I'm of two minds about it.
I started working with Kotlin back when Java was still a very ~~stagnant~~ stable language. I definitely find Kotlin's syntax to be much more comfortable, expressive, and in many ways much more simple than Java's.
But at this point, the only big technical features that still put Kotlin over Java for me is the handling of nulls by the type system (which is, admittedly, mitigated decently well in practice by Java tooling configurations and ugly annotations), and value types (zero heap-allocation wrapper classes).
Another thing to keep in mind is that now that Java is actually adding features again, the Kotlin developers will have to also play "catch-up" to Java in ways that it didn't have to when it first gained popularity. It puts Kotlin in an awkward spot when Java's implementation of sealed classes and interfaces was initially better and more flexible than Kotlin's, or when Java's `switch` is now more powerful than Kotlin's `when`, etc.
Kotlin is also betting heavily on their multi-platform stuff, which I'm skeptical about. It seems to me that it will further slow the ability to add useful features to the language if you have to cater to the lowest-common-denominator between Java and JavaScript (and Objective-C? -is that how it works for iOS?) runtimes. Instead of being the best language for a given platform, it'll just be a pretty good language for a few platforms. I wish them all the best in dethroning JavaScript from infecting every computing platform and domain, but I'm just skeptical.
So, honestly, I don't actually recommend people start new projects in Kotlin. I'd suggest going for Java, or something that's meaningfully different in semantics and philosophy like Clojure or Scala. I say this, but I'm not actually sure that I'd be able to follow my own advice, because I really don't want to have to stomach Java's syntax, idioms (way too many annotations), and stupid null handling.
Soon (tm): https://openjdk.org/jeps/8303099
The one feature that keeps me in Java, albeit not popular, is checked exceptions. I far prefer checked errors over checked nulls if I have to make a choice.
But, I'd still rather have safe/correct null type checking, because at the end of the day, I can always write MY code to return a Result/Try/Either type instead of throwing unchecked exceptions for expected business logic "failure" paths.
Relevant: https://news.ycombinator.com/item?id=44672787
https://news.ycombinator.com/item?id=44432640
It’s actually my #1 issue. I hate not knowing about error conditions and no one in Java uses checked exceptions because the language syntax for dealing with them sucks. Brian had a proposal for handling exceptions in switch but it seems to have died in the water.
Part of me secretly hopes Swift takes over the world because they have a typed throws that works and handling errors is a breeze.
This has consequences for config parsing, for example, where a particular subsection (sub-object? keyed struct?) may be optional, so it being missing is perfectly legal. But if you use try?, then there's no way to distinguish between it simply being missing and it being present but malformed. It unfortunately seems like the only other options in Swift is to propagate the error, or revert back to verbose try-catch blocks.
Whereas, in Zig, you can do inline catching and care about the error only as much as you want to, for example:
It's not perfect, I don't love the block-label-break thing, but I much prefer this if only because then the variable can be defensively const, which I do not believe is possible with the kind of code snippet you provided. Also, instead of breaking out, it could capture and return the error or return a new error. It's incredibly versatile.On the other hand, when I see Kotlin code that's not written by JetBrains (especially on the backend), it often does just look like Java code with cleaner syntax...
One could rightly debate over whether Kotlin's coroutines design and APIs are better than Java's virtual threads for writing asynchronous code. But, at the core, the story used to be that Kotlin had coroutines and lightweight structured concurrency "built-in" (with a blessed first-party helper library for the actual concurrency part) and Java did not have anything that accomplished the same goals. Now it does.
No comments yet
Many larger companies in The Netherlands have moved away from Scala and Java and use Kotlin now. The switching costs are neglegible and the benefits are big.
The problem with Kotlin is, you don’t want to go back to Java.
Java is getting better, so maybe in 10 years it'll be a less ergonomic Kotlin variant.
PS: Jetbrains - the company behind Kotlin - started a strategic partnership with the Spring team, to make the combo Kotlin-Spring even better: https://blog.jetbrains.com/kotlin/2025/05/strategic-partners...
PSS: Jetbrains is actually working on an official Kotlin-lsp server: https://github.com/Kotlin/kotlin-lsp So devs in the near future won't be locked into the IntelliJ ecosystem, if that is a concern of yours.
I like to avoid mixing Java/Kotlin within the same module when I can, but it still works, and parts of our codebase are mixed this way. (by module I mean e.g. the same Maven or Gradle module, i.e. try to avoid a situation where you have a `src/main/java` and `src/main/kotlin` next to each other)
There is almost no locking with Kotlin. You can stop writting Kotlin code any time and start writting Java code.
However I think it's not possible to call coroutine code from Java.
It's extremely close to Java in terms of most concepts. That makes it an easy language to switch into and out of. It's java with a nicer syntax and more sugar.
Write a Kotlin multiplatform client side business logic module in tandem with your Kotlin backend. The multiplatform module compiles for both your Android and Apple environments and for extra flexibility you are able to quickly port code from the client business logic module to the backend (or vice versa).
don't use ktor etc where some people wanna take their scala religion and put into kotlin.
kotlin is nice is you keep is super simple. use it the same way as you do Golang and you will find it pleasurable.
coroutines are the biggest downside imo. they're great for android and other environments, but now that we've got loom on the jvm they're needlessly complex (accidental blocking calls, coloring, headaches with libraries that use thread locals, reentrant lock, etc.)
Come in; the water is fine.
There are serious headaches to be had when you have to maintain software for ten years and up.
Porting systems to another language is often terribly expensive.
Working with younger people exposes that quite mercilessly and I can recommend doing that if you catch yourself doing a lot of repetitive projects with people well over 40. Try something new if you want to stay relevant. Move on if your colleagues can't deal with that. It's only going to get worse with them.
I've been using Kotlin with Spring boot for backend development since 2018. I did Java before that; since 1995. Java has indeed improved and was probably nudged along by what Kotlin and Scala and other languages have done. But it hasn't really caught up properly IMHO. Everything Kotlin does right out of the box (intentionally, to fix what Java did wrong here), Java continues to do wrong out of the box and this is actually a big deal because it does a lot of important stuff wrong mainly for compatibility reasons. That's the big biggest difference. These are things that Java cannot fix in a backwards compatible way. That alone is a good reason to switch.
Examples of this are that it makes code less null safe, non final, introduces unnecessary mutable state, etc. Kotlin allows you to do these things when you need to but it defaults to things being closed, final, val (instead of var), etc. And these are just things that Kotlin has been doing right since it's first releases. It has progressed a lot since then.
If you like verbosity and don't want access to the countless convenient extension functions, DSLs, co-routine support, etc. that e.g. Spring ships for Kotlin, go for Java. In they end you kind of do the same things. But IMHO in a needlessly verbose and clumsy way.
But you are missing out. IMHO anything to do with Spring Flux is just an order of magnitude easier via Kotlin and co-routines and IMHO even attempting to use that from Java is misguided. But in Kotlin, you can hardly tell the difference with non reactive code. With Java, this turns into a mess of leaky abstractions, function chaining, and lots of boiler plate. Our server is effectively using only a handful of threads with lots of websockets, connections, background processing etc. happening.
Reactive/async stuff across all of the mainstream Java server frameworks is well supported from Kotlin and has been for many years. E.g. the co-routines library ships with lots of extension functions for just about anything you can name. The green thread stuff Java does is often cited as a thing that closes the gap. But from a Kotlin point of view it's just something that makes using legacy Java code a bit less tedious.
Jetbrains and Spring did some joint announcements at the latest Kotlin conf. The upcoming major release of Spring Boot is going to be even more Kotlin heavy and centered than the current one is. And honestly, you had a superior experience with v1 way back even. They won't abandon Java support. But at this point, you are really missing out if you are sticking with Java. There are non technical reasons for doing that but very few (if any) technical reasons.
They are doing a big push with the new release on making nullability checks on all the Spring Java stuff stricter for Kotlin and making sure Kotlin does the right things. And all their documentation was already dual Kotlin/Java but looks like it might be leaning towards Kotlin first going forward.
Many reasons to like Kotlin. If somebody tells you it's Android only that was never true and there's a lot of quiet Kotlin usage with anything Java because there's not a single Java framework that you can't seamlessly use from Kotlin. And almost universally it's a better experience. The older the better actually. Because the old one tend to not use any of the new Java features. Where new is introduced in the last 15 or so years.
I'd say it's nice and I would actually start every new (spring/java) project I do in kotlin now. But for existing projects, I actually see no value. It does not magically make code easier to understand and it doesn't reduce bugs, it's just a bit more fun and challenging to write and pads your resume...
We did have one issue where upgrading the kotlin version from 1.x to 2.x in a project broke all depending projects due to a classfile version issue though. I deferred it by just forcing the version back to 1.x. That's the kind of annoyance you can encounter.
PROFIT!
And, JetBrains finally started working on an open language server. It's not perfect but it makes it bearable to at least edit Kotlin in Cursor/VS Code.
https://plugins.jetbrains.com/plugin/27310-claude-code-beta- https://github.com/Kotlin/kotlin-lsp
I would never voluntary do any editing in VS Code or forks of it. It is just so slugish on large files. Plus there is always subtle things that annoy me, I can't even describe it, it just feels off. I hope Zed takes off as it is a bit more tolerable though still not there yet.
Its great for DSLs though.
No trailing lambdas, no infix operators, no @DslMarkers, no top level functions, and an infinite list of examples of Java verbosity making even the smallest thing look like an ancient greek epic. Java is utterly terrible for DSLs.
No template, as it's specific to my team's project, but one example is that we enforce that classes within our core domain don't import types from outside the project. You could accomplish this with separate projects, but that comes with its own complexities. This rule basically says "any domain type shall not import a non-domain type".
and here's the diff for a 'real world' rule I implemented: https://github.com/michaelbull/kotlin-result/compare/master....
Sometimes people post the same link to HN for weeks, and nothing happens. Suddenly after 10th try, trend catches up, and the same link is on the main page.