Articles / Kotlin Multiplatform: A practical use-case of Kotlin/JS IR compiler
Kotlin Multiplatform: A practical use-case of Kotlin/JS IR compiler
by dzikoysk on 2024-06-15Kotlin Multiplatform (KMP) tries to move Kotlin out of the JVM world and make it a universal language for all platforms.
Well... if something is universal, then it's usually not the best at anything. But let's not be so pessimistic.
A while ago, I was working on a project that required a library that is able to process Hangul (Korean alphabet) input on frontend.
Why would you need that? Well, Hangul is a bit more complex than the Latin alphabet, and it's not that easy to process it on the client side.
Symbols are combined into syllables, and each syllable is a separate character. Take a look at the following example:
Input | Input code | Output | Output code |
---|---|---|---|
ㅇ | 0x3147 | ㅇ | 0x3147 |
ㅏ | 0x314F | 아 | 0xC544 |
ㄴ | 0x3134 | 안 | 0xC548 |
Interesting, isn't it? There are different types of result characters depending on the context (!), for instance:
So now we've got new 2 symbols as a result. You can find more such cases, but in the end it's not a post about Hangul, but about Kotlin Multiplatform.
As a requirements for the library, I had the following points:
- I need this library on frontend and backend, so I'd like to have a single codebase
- The output characters can be calculated using some specific formulas, so I should be able to do some basic operations on code points
- I want to have a possibility to easily test the library
Backend was already in Kotlin, so KMP seemed to be a decent choice.
§ Setting up the project
KMP is quite loudly advertised by JetBrains, so I'd expect that setting up the project should be a piece of cake.
Well, as usual it is unnecessarily complicated, but could be worse. The Gradle structure looks quite standard:
The setup for the 2 targets I was interested in (JVM and JS) looked like this in Kotlin 1.8:
§ KMP related issues
§ Kotlin/JS runs on Node with... Yarn
I initially thought they took the simplest way, and the project will just simply run on standard Node.js + NPM setup, so I was quite surprised when I started getting errors from Yarn.
Well, it turns out that Gradle cache does not like Yarn lock files, so it's time for our first workaround to actually make it work:
§ Publishing to NPM is not officially supported
As long as you can mark the output as a library with
binaries.library()
, you don't really have a way to publish it to NPM.
In order to do that, you need to use the mpetuska/npm-publish plugin:The plugin adds some additional tasks, but to get it all in just one command, you still need to register a new one:
* meh *
§ SDK is not the same as on JVM, obviously
Java has a decent support for code points that would be good enough for me. Unfortunately, it turns out that part of the
String
class is not ported to Kotlin mappings...
This time I was saved by another member of the community, who created a library that provides this missing functionality: cketti/kotlin-codepoints.§ The library
If you're lucky enough to finish the project, you can publish it to NPM and use it in your frontend project.
I actually didn't have any problems with that part, so I can't really complain about it.
The bundle size is of course a bit bigger than the one you'd get with a pure JS library, but it's not that bad.
And this is the result! Try to type
ㅇ
→ ㅏ
→ ㄴ
and see if it really works: