Skip to content

lightningkite/kiteui

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

KiteUI

Maven Central Version Nightly License CI Status KDoc

Kotlin Android JVM JS iOS

Donate

A Kotlin Multiplatform UI Framework inspired by Solid.js that uses the native view components of each platform.

Why make this library instead of using Compose Multiplatform?

  1. Web targets: Compose is built on its own rendering stack, and thus it must render its entire UI on web in a canvas. This makes accessibility and good performance extremely difficult and server-side rendering impossible.
  2. Smaller Binary Sizes: Compose generates fairly large binaries, since it must recreate the entire UI set of the target platform - i.e. text fields, checkboxes, and more.
  3. URL-based navigation: Deep linking is difficult in Compose, so creating links to pages requires extra effort.

For these reasons, we think Compose isn't sufficient nor can be made sufficient for any multiplatform development that includes a web target. That's why we created this library.

Here is a comparison of the same UI built with KiteUI and Compose Web:

Compose Web KiteUI Web
Live site https://zal.im/wasm/jetsnack https://kiteui-jetsnack-demo.cs.lightningkite.com/
Source Code https://github.com/JetBrains/compose-multiplatform/tree/master/examples/jetsnack https://github.com/lightningkite/kiteui-jetsnack-demo
Web Binary Size (including fonts and css) 12.17389 MB (July 30, 2025) 0.77092 MB (July 30, 2025)
Performance in KiteUI is faster or equivalent to the performance of Compose multiplatform Web from internal testing.

Features

  • Smaller Binary Size: KiteUI makes fairly small bundle sizes.
  • Fine-Grained Reactivity: Inspired by Solid.js, KiteUI uses a fine-grained reactivity system that only updates what needs to be updated while avoiding compiler magic.
  • Semantic Theming System: KiteUI's theming system is built around semantic concepts rather than direct styling, making it easier to maintain consistent UI across your application.
  • Web-First Approach: With URL-based navigation and (upcoming) server-side rendering capabilities, KiteUI is designed to work seamlessly in web environments while still supporting native platforms.
  • True Native Component Integration: Because KiteUI uses the underlying platform's view system, integrating a native view not accounted for in the library is extremely easy.
  • Automatic Load State: The reactivity mechanism tracks loading in progress, so your elements will automatically go into a visual loading state if they're waiting for data.
  • Annotation URL-based routing: A simple annotation binds pages and their URLs together.

Goals

  • Small JS size
  • Web Client and server-side rendering, Android, iOS, eventually desktop
  • Pretty by default - ugliness should take effort
  • Simple Routing
  • Easy to extend into native components on the platform
  • Make loading and issue handling pretty without manual work

Interesting design decisions

  • Base navigation around URLs to be very compatible with web
  • Use fine-grained reactivity based on SolidJS
  • Use themes for styling; avoid direct styling.
  • Derive theme variants from existing themes programmatically. Make theme variants semantically based.
  • Don't use a KMP network client, they're all too big - include a custom, simpler, and more limited implementation

Project Status

We are using this in production, but I will not declare the API as totally finalized. However, with the sheer number of projects we have written in it, we at least have to keep some level of compatibility. We'll document how to adjust to new changes as they come.

Road Map

  • Server-side rendering - We have a lot of stuff prepared for this, but there's work that must be completed to finish it.
  • WASM target - should be fairly easy to implement, since at one time we had it implemented but it was slower and bigger. From what I hear performance has improved enough to make restoring this target sensible.
  • Desktop Target - We're still not sure what underlying UI framework we wish to target. Compose Desktop, Swing, and JavaFX are all possibilities, though we'll likely go with Compose.
  • Form validation - I feel like there could be some tools that would make form validation easier. Still haven't found the right API though.
  • Performance Improvements - while it's already running fairly fast, I always would like more time to improve it.

Importing

Maven repository: maven("https://lightningkite-maven.s3.us-west-2.amazonaws.com") Dependency: api("com.lightningkite.kiteui:library:<current tag>")

Take a look!

You can look at the example project we're hosting to get an idea of what you can do.

Click the magnifying glass in the app to see the source!

One example directly on this page:

See for yourself

If you want to try another theme, start here, change the theme, then go to the "Sample Log In" sreen.

Screenshot 1 Screenshot 2

@Routable("sample/login")
object SampleLogInPage : Page {
    override fun ViewWriter.render(): ViewModifiable = run {
        val email = Property("")
        val password = Property("")
        frame {
            gap = 0.rem
            image {
                source = Resources.imagesSolera
                scaleType = ImageScaleType.Crop
                opacity = 0.5
            }
            padded - scrolling - col {
                expanding - space()
                centered - sizeConstraints(maxWidth = 50.rem) - card - col {
                    h1 { content = "My App" }
                    sizeConstraints(width = 20.rem) - field("Email") {
                        fieldTheme - textInput {
                            hint = "Email"
                            keyboardHints = KeyboardHints.email
                            content bind email
                        }
                    }
                    sizeConstraints(width = 20.rem) - field("Password") {
                        fieldTheme - textInput {
                            hint = "Password"
                            keyboardHints = KeyboardHints.password
                            content bind password
                            action = Action(
                                title = "Log In",
                                icon = Icon.login,
                            ) {
                                fakeLogin(email)
                            }
                        }
                    }
                    centered - sizeConstraints(width = 15.rem) - important - button {
                        h6 { content = "Log In" }
                        onClick {
                            delay(1000)
                            fakeLogin(email)
                        }
                    }
                }
                expanding - space()
            }
        }
    }

    private suspend fun ViewWriter.fakeLogin(email: Property<String>) {
        fetch("fake-login/${email()}")
        pageNavigator.navigate(ControlsPage)
    }
}

About

A Kotlin Multiplatform UI Framework based on Solid JS

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Contributors 10