Update kobweb to v0.25.0 - #28
Open
renovate[bot] wants to merge 1 commit into
Open
Conversation
renovate
Bot
force-pushed
the
renovate/kobweb
branch
from
July 2, 2026 23:33
e03bf54 to
24cc326
Compare
renovate
Bot
force-pushed
the
renovate/kobweb
branch
from
July 5, 2026 22:10
24cc326 to
9016d54
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
0.23.3→0.25.00.23.3→0.25.00.23.3→0.25.00.23.3→0.25.00.23.3→0.25.00.23.3→0.25.00.23.3→0.25.0Release Notes
varabyte/kobweb (com.varabyte.kobwebx:silk-icons-mdi)
v0.25.0This release is functionally identical to v0.24.1 but with all Kotlin / Compose dependencies migrated to latest.
Full Changelog: varabyte/kobweb@v0.24.1...v0.25.0
v0.24.1This is a jam packed release featuring long-planned tweaks to the network APIs as well as new lucide and material symbol icons!
In the previous release, we revisited the backend network APIs to support multipart requests, but due to backwards compatibility, we could not yet touch the frontend APIs, as the method names we wanted to use were already taken. Instead, we deprecated them.
In this release, those frontend changes are now done! Potentially, there may be some codebases out there which might break with this change, but they would have been ignoring scary deprecation warnings for a while now. As these methods are not used by most Kobweb users, we decided to incrementally update the release version instead of put out a new major version.
If you are a developer with a fullstack website and you get warnings after updating, please review the
Notessection below about migrating. We did our best to tell the IDE how to automatically update your deprecated code to the latest versions of the API, but it doesn't always do the best job.Changes
Frontend
Icons!
Notessection below for more details.Introduced a slew of Kotlin-idiomatic network request APIs.
Notessection below for more details.CSS Modifiers
Modifier.animation { delay(...) }object-positionpropertytext-wrappropertytab-sizepropertyimage-renderingpropertyimage-orientationpropertyTransform.Nonevalue (and global keywords, e.g.Transform.Inherit)Improved CSSPosition output, now producing simpler output
CSSPosition(Edge.Left)is now just"left", and not"left 0% top 50%"Worker
Made network APIs more flexible so they could be called from a worker script.
windowthrows a runtime exception. So now....window.fetch(...)self.fetch(...)Added support for launching coroutines inside a worker context
CoroutineContext(window.asCoroutineDispatcher()).launch { ... }CoroutineContext(self.asCoroutineDispatcher()).launch { ... }Backend
You can now expose system properties from your build script to your backend server
Notessection below for more details.Added support for multiple headers on the same request
When you run
kobweb run --layout=staticin dev mode, it will now return 404 on dynamic pages.Gradle
KOBWEB_EXPORT_BROWSER_PATHor directly in your site's build script viakobweb.app.export.browser.path.Notes
Material Symbols
Kobweb has supported Material Design Icons for a long time, but Google deprecated those and replaced them with Material Symbols instead. If you are using MDI in your own project, you may want to consider migrating over if possible, as presumably MDI is mostly stale now and future work will go into MS.
// site/build.gradle.kts kotlin { sourceSets { jsMain.dependencies { implementation(libs.silk.icons.ms) } } }At that point, you can reference them in your code! Material Symbol icon methods begin with the
Msprefix.For example, if you wanted to use the mail icon, find the corresponding method with the same name:
MsMail()You can also pass in a style, with one of three values (where outline is the default):
Lucide Icons
Check out the official page to see their list of icons.
To use these in your project, simply add the following dependency to your build script:
// site/build.gradle.kts kotlin { sourceSets { jsMain.dependencies { implementation(libs.silk.icons.lucide) } } }At that point, you can reference them in your code! Lucide icon methods begin with the
Lucideprefix.For example, if you wanted to use the mail icon, find the corresponding method with the same name:
LucideMail()The full API for that method is:
so feel free to play with those values in your own site.
Backend system properties
If you are running a kobweb server and want to expose some values to it from the build script, we made this easy:
kobweb { app { server { systemProperties.put("example.key", "example.value") } } }Then, anywhere inside your
jvmMainserver code:We are using this new feature in the todo template example (e.g.
kobweb create examples/todo). This allows us to make it easy for users to toggle the implementation of the backend datastore from in-memory to a MongoDB database. Feel free to check out the project if you are curious!Revisiting Network APIs
The stdlib
fetchAPI is very powerful but full of dynamic, type-unsafe code. Kobweb's network APIs aresuspendfriendly and type-safe.However, in the earliest days of Kobweb development, I made an incorrect assumption and oversimplified what I would accept for a request's payload body. Specifically, I only accepted a byte array for it. However, there are several different data types that web request APIs traditionally accept, including multipart bodies, json, html text, and blobs.
Therefore, this version of Kobweb introduces a new
RequestBodyclass which you construct with one of the various providedbodyOffactory methods. So where before you would pass raw bytes into one of the Kobweb network methods, now you pass in the output of abodyOfcall instead.Of course there is a
bodyOffor raw bytes. But we also support wrapping the other types as well (blobs, etc.)And instead of returning raw bytes back, we now return a
Responseobject (a standard class in web APIs). You can pull raw bytes out of its body payload by using our newbodyAsBytesextension method:A little more verbose, admittedly, but now users can work with
Responseobjects directly, which is a lot more powerful.Real-world example: multipart request
To showcase a real example, the following code was introduced in the last release demonstrating how to send a multipart request:
Now, I would write it as follows, ditching the
RequestInitobject and the need toawaitthe response (since Kobweb'sfetchmethod is suspend aware):Migrating deprecated network methods
We deprecated a lot of network methods in this release, since, as we discussed in the prior section, we settled on the approach we should have used in the beginning: take in a rich request body type and return a
Responseobject.If you are a user caught up in this, we apologize for the inconvenience.
In the previous release, we pushed people away from using, say,
fetch, which originally returned raw bytes, and migrated them to usefetchBytesinstead (same function, new name). Now, here we are abandoning raw bytes! And pushing users back to the original method, except now it takes in a rich body type and outputs aResponse. Users are expected to callbodyAsByteson top of theResponseobject to get those raw bytes out again.For every method we deprecated, we included logic to help the IDE try to migrate the code for you. However, sometimes, it just really sucks at it, so manual migration / tweaking may be required.
In the following table, we'll use the
postmethod to demonstrate before and after migrations, but keep in mind this same transition would apply for any of the HTTP verbs (get, put, delete, etc.).window.fetchBytes(HttpMethod.POST, url, bytes)window.fetch(HttpMethod.POST, bodyOf(bytes)).bodyAsBytes()window.tryFetchBytes(HttpMethod.POST, url, bytes)window.tryFetch(HttpMethod.POST, bodyOf(bytes)) { bodyAsBytes() }window.http.postBytes(url, bytes)window.http.post(bodyOf(bytes)).bodyAsBytes()window.http.tryPostBytes(url, bytes)window.http.tryPost(bodyOf(bytes)) { bodyAsBytes() }window.http.postBytes(url, bytes)window.http.post(bodyOf(bytes)).bodyAsBytes()window.http.tryPostBytes(url, bytes)window.http.tryPost(bodyOf(bytes)) { bodyAsBytes() }window.api.postBytes(url, bytes)window.api.post(bodyOf(bytes)).bodyAsBytes()window.api.tryPostBytes(url, bytes)window.api.tryPost(bodyOf(bytes)) { bodyAsBytes() }window.api.postBytes(url, bytes)window.api.post(bodyOf(bytes)).bodyAsBytes()window.api.tryPostBytes(url, bytes)window.api.tryPost(bodyOf(bytes)) { bodyAsBytes() }As you can see, the new versions are a bit more verbose, but by separating out the logic for making the request and reading the response, we get a lot more power with fewer methods.
Serialization extensions
Not many people know that Kobweb also provides an artifact (
com.varabyte.kobwebx:kobwebx-serialization-kotlinx) that adds extensions for network requests that are Kotlinx serialization aware.We also revisited those methods and simplified them as well.
For the following table, imagine we had the following serializable classes:
In the following table, note that a common change is moving the
Resresponse class out from the initial request signature into a trailingbodyAs<T>call.window.http.postBytes<Req>(url, req)window.http.post<Req>(url, req).bodyAsBytes()window.http.tryPostBytes<Req>(url, req)window.http.tryPost<Req>(url, req) { bodyAsBytes() }window.http.post<Req, Res>(url, req)window.http.post<Req>(url, req).bodyAs<Res>()window.http.post<Res>(url)window.http.post(url, body = null).bodyAs<Res>()window.http.tryPost<Req, Res>(url, req)window.http.tryPost<Req>(url, req) { bodyAs<Res>() }window.http.tryPost<Res>(url)window.http.tryPost(url, body = null) { bodyAs<Res>() }window.api.postBytes<Req>(url, req)window.api.post<Req>(url, req).bodyAsBytes()window.api.tryPostBytes<Req>(url, req)window.api.tryPost<Req>(url, req) { bodyAsBytes() }window.api.post<Req, Res>(url, req)window.api.post<Req>(url, req).bodyAs<Res>()window.api.post<Res>(url)window.api.post(url, body = null).bodyAs<Res>()window.api.tryPost<Req, Res>(url, req)window.api.tryPost<Req>(url, req) { bodyAs<Res>() }window.api.tryPost<Res>(url)window.api.tryPost(url, body = null) { bodyAs<Res>() }The above tables certainly makes it look like this would be a very disruptive change indeed, but in practice, not too many people use fullstack Kobweb, and even for those that do, some of these methods are pretty niche, so we don't expect most users to even notice a single warning!
Thanks
The community really benefits from contributions like this. Thank you so much!
Full Changelog: varabyte/kobweb@v0.24.0...v0.24.1
v0.24.0In this update, we took some time to focus on the backend API, adding support for multipart requests. We also revisited the associated frontend APIs (and deprecated a bunch of them) paving the way for more improvements to follow.
This release also makes markdown handling more robust, and it raises the versions of kotlin to 2.3.10, compose (html) to 1.10.0, and compose (runtime) to 1.10.2 (now sourced from androidx).
Changes
Frontend
window.getSelectionanddocument.getSelectionholdsIncontracts toModifier.thenIf/UnlessandCssStyleVariant.thenIf/Unlessthenlambda block.Modifier.displayBetweenwhich was broken since a prior rename{param?}) are now only allowed in the final position of a routebaseblock in theirCssStyleblock.window.api.bytes(...)changed towindow.api.getBytes(...))Backend
Added support for multipart request bodies.
Request.BodyandResponse.BodyAPIs as a side effectAdded a user data property on
RequestandResponseclassesMarkdown
attrslambda blocks instead of string manipulationGradle
nullerror that could occur in the Gradle task listenerkotlin-dslplugin, added Gradle assignment plugin)Misc
Thanks!
Notes
Multipart requests
Requests using multipart forms is outside the scope of these release notes, but consider reading the official docs on the topic for more information.
Kobweb does not yet have an idiomatic way to send a multipart request (we will add this into a future release, but you can use the stdlib for this, leveraging
FormData,RequestInit, andwindow.fetchAPIs for now.)The following FE code (imagine in a
@Pagesomewhere) lets the user pick a file from their machine and send it to the server, using multipart forms to send both the file itself and an extra description as metadata:Then, to handle a multipart request on the backend, write an API endpoint that uses
req.body.multipart()to query it. The following endpoint is just a demo and returns diagnostic information about what was sent back as body text:Our API is inspired by, but (we think) slightly more Kotlin idiomatic than, the ktor version.
Migrating frontend / backend APIs
Changes in this release caused us to reevaluate our APIs used for communicating between the frontend and backend, after adding multipart support challenged simple assumptions that I had mistakenly made a long time ago.
Fortunately, migration should be pretty easy, and it is hoped that most projects won't even notice the changes, or at least, will just need to accept IDE suggestions on deprecated lines of code.
HTTP responses expecting raw bytes
The APIs that send HTTP verb requests and expect raw bytes back have been renamed to be more explicit, e.g.
In a near future release of Kobweb, the old
get,post, etc. methods will be repurposed to return a different, richer type.Reading / writing body text
Before, we put read/write extension methods directly on the Request and Response objects, but body content can be more flexible than I originally realized, so I tweaked these APIs and moved them onto the exposed body objects instead.
We also now support alternate ways of reading body content, i.e.
body.stream()andbody.bytes()Querying body text is async now
Previously, Kobweb read the bytes out of the body itself on the backend and converted it into a string, but this was not compatible with some kind of response bodies. So now, we let the user query the body contents at their convenience.
If you run into an error that an API call you wrote cannot call a suspend method, this generally means you may have to update its signature to be explicitly suspend:
Full Changelog: varabyte/kobweb@v0.23.3...v0.24.0
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about these updates again.
This PR was generated by Mend Renovate. View the repository job log.