Making Shade Multiplatform

Renee Vandervelde
4 min readApr 18, 2021

--

Shade is a Kotlin SDK for Phillips Hue lights that I’ve worked on for the past several years. It was written from scratch in Kotlin, with support primarily focused on well typed Kotlin structures. So why does it only support the JVM? The answer is that Kotlin’s Multiplatform isn’t quite ready. Let me explain.

When I released Shade, one commitment I made with the library is to keep it stable. This includes being stable against API changes. The library has not encountered a breaking change, even amongst discovering new requirements in the Hue API since its release and entire endpoints being retired. The library remains at a stable 1.x release currently.

I am currently working on the Multiplatform updates to Shade. However, making Shade a Multiplatform project will require major changes in the API. In this 2.0 release of the SDK, I want to maintain this same level of stability going forward after its release. And here’s where we start to run into problems.

Kotlin’s Missing Multiplatform Tools

I’m a big proponent of Kotlin’s Multiplatform. I use it on many projects, and continue to create tools to support common operations on Multiplatform projects. But the platform is still lacking maturity in standard libraries, structures, and basic tools. Here are some examples that have held back Shade.

Incomplete and Unstable Time Structures

Time structures are complex, and their use is critical to so many applications. Kotlin has some time structures available, but it would be generous to call them experimental.

The Duration classes are built into the stdlib and support all platforms. However these are still marked experimental, and while that remains true libraries should not be built around these API’s.

The KotlinX DateTime library looks like a promising Multiplatform implementation of date and time constructs. However it’s not currently stable and most recent release at the time of writing was v0.1.1 five months ago. The library is still missing entire constructs like Time

Shade relies on both duration and time structures like these, and is designed to be built around canonical types like the platform stdlibs and extensions. Are there are other Multiplatform implementations of datetime libraries that can be used? Yes. Klock is an example. However, when these libraries do stabilize, this could leave the Shade SDK in a tough spot. For now, it makes more sense to see how these first-party libraries develop for such a critical component of any application.

Value Classes

One thing Shade does to ensure a clear API is wrap simple values in defined types. An example is the Percentage type. Hue’s arguments for this could be easily confused, but the API in Shade makes it easier to use.

Inline classes are designed for exactly this type of decorative type definition. But not only are they experimental, they just got refactored to a new construct: value classes.

I am excited to migrate Shade’s value classes to these new constructs, but need them to stabilize first.

KotlinX Serialization Bugs

In the course of refactoring Shade to use Ktor and KotlinX serialization, I’ve found quite a few bugs. While I have been able to use workarounds for many of these, it has lowered confidence in the stability of the tool. Inline classes aren’t supported, custom serializers often don’t work as documented and errors are unclear.

Builds

One problem I haven’t seen entirely solved for Kotlin Multiplatform is an elegant way to create and distribute builds. Currently builds are done through JitPack, however this may not work for Multiple platforms outside of the JVM and Javascript platforms. The distribution will likely move to something like Maven Central for distribution. However, I am personally hoping that GitHub solves their authentication issues with their Packages platform before this needs to be changed.

So What’s Next?

The good news is a lot of progress has been made and most of the hard work in migrating Shade to Multiplatform is done now.

You can find an unstable working branch on GitHub, but be aware that these API’s will change as the above problems are fixed.

Should the first-party kotlin libraries not show signs of stabilizing by summer, other options will be evaluated. One potential option being considered is creating very simple container types (like the value classes) and then creating extension modules to adapt them to various platform dates.

I am also working on another Multiplatform project to support value types for measurements like percentages and other units of measure that I frequently use in projects. It’s called Spondee and I expect this to stabilize fairly quickly.

--

--

Renee Vandervelde

Software Engineer at Stripe. Currently focused on Kotlin and Android.