28 KiB
Change Log
Unreleased
1.26.0 - 2026-03-04
- Fix: Prevent StackOverflow when serializing recursive class definitions. The serial name description now ends when encountering a recursive descriptor.
- Fix: Embedded code will now be used first if it is fresher than cached network code.
1.25.0 - 2026-01-12
- Fix: Work-around the Kotlin compiler returning a non-
Unitvalue for a function that declaresUnitas its return value. We'd previously observed this problem with Kotlin/JS and recently started seeing it in Kotlin/JVM also. - Fix: Prevent some memory leaks on native.
- Upgrade: Kotlin 2.3.0.
1.24.0 - 2025-10-23
- New: Add JVM support for Windows (x64 and ARM).
- In-development snapshots are now published to the Central Portal Snapshots repository at https://central.sonatype.com/repository/maven-snapshots/.
- Upgrade: Kotlin 2.2.21.
1.23.0 - 2025-09-09
- Fix: Recover from more full disk exceptions. We had a bug on Kotlin/Native where Zipline would crash if it was unable to create the cache directory.
- Upgrade: Kotlin 2.2.10.
- Upgrade: Okio 3.16.0.
1.22.0 - 2025-07-25
- Upgrade: Kotlin 2.2.0.
- Upgrade: OkHttp 5.1.0.
1.21.1 - 2025-07-17
- Fix: Recover from more SQL exceptions. We had a bug on Kotlin/Native where a full disk on the host device would cause the disk cache to crash. With this update it gracefully degrades to not caching.
- Fix: Work-around Kotlin/JS treating null as Unit. When we updated our intermediate JavaScript to
es2015, that caused
suspendfunctions that returnUnitto crash. We now explicitly handle cases where functions that should returnUnitdon’t!
1.21.0 - 2025-07-15
- New: Switch to ES2015 as our intermediate target when compiling from Kotlin to JavaScript to QuickJS bytecode. This results in artifacts that better preserve function names in stack traces. Note that this benefit isn't free; gzipped artifacts are about 3% larger with this update!
- Upgrade: Okio 3.15.0.
- Upgrade: SQLDelight 2.1.0.
- Upgrade: Kotlin 2.1.21.
1.20.1 - 2025-04-02
- Fix: Update source map parser to ECMA 426 which will not fail on the
ignoreListkey and ignore any extensions. - Upgrade: Kotlin Serialization 1.8.1.
1.20.0 - 2025-03-20
- New: Add Linux ARM to supported platforms for JVM artifact.
- JVM native libraries are now cross-compiled with Zig build system. Please report any issues!
- Upgrade: Kotlin 2.1.20
- Upgrade: Kotlin Serialization 1.8.0.
1.19.0 - 2024-12-03
- Upgrade: Kotlin 2.1.0
1.18.0 - 2024-11-14
- Fix: Prevent clients from caching the dev server's responses.
- New: "compile" subcommand in 'zipline-cli' compiles
.jsfiles to.ziplinefiles. - Upgrade: Kotlin Serialization 1.7.3.
- Upgrade: kotlinx.coroutines 1.9.0.
- Upgrade: Okio 3.9.1.
1.17.0 - 2024-08-28
- New: Expose
globalThis.gc()function into the guest code. - Upgrade: Kotlin 2.0.20
[1.16.0] - 2024-07-17
- Fix: Support 16KB page sizes in our Android native library. This is necessary to prevent an
UnsatisfiedLinkErrorcrash on Android 15 / API level 35.
[1.15.0] - 2024-07-16
- New: Use different dispatchers for cache vs code execution. Both the cache and QuickJS need to be
thread-confined, but they don't need to be confined to the same thread. With this release we've
added a new
CoroutineDispatcherparameter toZiplineLoader.withCache(). It is used when reading and writing the cache. The existingCoroutineDispatcherused to create theZiplineLoaderis used to access QuickJS. - New:
EventListener.cacheHit()is called on each cache hit.
[1.14.0] - 2024-07-09
- New:
ZiplineLoader.load()andloadOnce()now accept a suspending function. - New: Don't crash in
ZiplineLoaderwhen writing to the disk cache fails. Use the newLoaderEventListenertype to observe such failures. - Fix: Don't crash in Gradle if the Zipline runtime library is absent.
- New: Extend Kotlin's
AutoCloseableinZipline,ZiplineServiceandZiplineScope. - Upgrade: Oracle Linux 8 for x86_64 Linux (
amd64/oraclelinux:8on Docker). - Upgrade: Kotlin Serialization 1.7.1.
[1.13.0] - 2024-06-14
- Fix: Don't derive the Zipline compiler's output directory from the Kotlin/JS output directory.
Zipline's outputs are now emitted to directories named like
build/zipline/Development, andbuild/zipline/ProductionWebpack. This avoids aPropertyQueryExceptioncrash in Gradle.
[1.12.0] - 2024-06-13
- Fix: Don't allocate a stack trace when canceling a coroutine or a job. We've observed that
applications create many instances of
CancellationException, such as when canceling a flow in routine business logic. Unfortunately, we've also seen that creating the stack traces for these exceptions is slow on Kotlin/Native. With this update Zipline reuses a single instance of CancellationException everywhere. We believe that losing the diagnostic information is worth the performance benefit. - Fix: Don't break the configuration cache. Zipline's compile task violated a Gradle requirement by reading another task's property before that task had completed.
- New:
ZiplineFunction.asDynamicFunction()short-circuits Kotlin Serialization in Kotlin/JS. This new mechanism allows performance-sensitive code to reduce the amount of work required to call bridged functions. - Upgrade: Kotlin Serialization 1.7.0.
[1.11.0] - 2024-06-05
- New:
apiTrackingproperty on thezipline { }Gradle extension allows disabling API generation. - Fix: Calling
Zipline.close()will now callZiplineService.close()on all bound services. Strong references to the services will also be cleared to prevent reference cycles on native. - Upgrade: Kotlin 2.0.0
[1.10.1] - 2024-05-13
- Fix: Build the released artifact on macOS instead of Linux to work around an issue packaging native dependencies.
[1.10.0] - 2024-05-01
- Fix: Clean source paths that show up in stack traces.
- Fix: Don't leak Zipline instances. We had a bug where our memory-leak detection itself introduced a memory leak. We held a reference to a Zipline instance that was intended to be used to report services that were garbage collected but not closed.
[1.9.0] - 2024-04-11
- Breaking: Reorder the parameters in
ZiplineLoadersoFileSystemalways precedesPath. - Fix: Release unused services in
Zipline.close(). This was a memory leak. - Fix: Don't break Gradle's configuration cache in the
ziplineApiDumptask. - New:
ZiplineCryptographyadds aSecureRandomAPI for guest code. - New:
Zipline.getOrPutAttachment()lets you attach application data to a Zipline instance. - New: Support building Zipline with the new Kotlin K2 compiler.
- Upgrade: Kotlin 1.9.23
- Upgrade: kotlinx.coroutines 1.8.0
- Upgrade: Okio 3.9.0
- Upgrade: SQLDelight 2.0.2
[1.8.0] - 2024-01-11
- Fix: Don't crash validating signatures on Android 7.x. We incorrectly used an API that wasn't available until API 26+.
- New:
FreshnessCheckerdecides whether to load cached code. If it returns false,EventListener.applicationLoadSkippedNotFresh()will be called. - New:
EventListener.manifestReady()is called when the manifest is fetched and verified, but before any code is downloaded. - Upgrade: Okio 3.7.0
[1.7.0] - 2023-11-30
- New: Gradle APIs to optimize production builds for either small artifact size or developer
experience. Call the appropriate functions in the
zipline {}block of your build file:zipline { ... optimizeForSmallArtifactSize() } - Fix: Don't crash when very large
Longvalues are sent over a bridged API. Zipline uses JSON to encode values shared between host and guest, and that converts all primitive numeric types toDouble. It is necessary to add@Contextualto all serializedLongvalues to get this fix.
[1.6.0] - 2023-11-20
- Upgrade: SQLDelight 2.0.0
[1.5.1] - 2023-11-14
- Fix: remove the Zipline version from the
klibmetadata in thezipline-cinterop-quickjsartifact. This restores the behavior from 1.4.0 to work around KT-62515.
[1.5.0] - 2023-11-02
- New:
Zipline.eventListenercan be used to get theEventListenerfrom aZiplineinstance. - Upgrade: Kotlin 1.9.20
[1.4.0] - 2023-10-31
-
New:
EventListener.Factorycan be used to scope events to a particularZiplineinstance. -
New: Support arbitrary metadata in the
ZiplineManifest. This newMap<String, String>can be produced in yourbuild.gradle.ktsfile, and consumed from theZiplineManifestinstance.zipline { ... metadata.put("build_timestamp", "2023-10-25T12:00:00T") } -
Upgrade: OkHttp 4.12.0
-
Upgrade: Okio 3.6.0
[1.3.0] - 2023-09-20
- Fix: Configure a 6 MiB stack size by default. Previously Zipline didn't enforce any stack size limit, which resulted in difficult-to-diagnose crashes when the stack size was exceeded. Callers must manually ensure their calling stack sizes are larger than 6 MiB!
- Fix: Always include type parameters for nested parameterized types.
- Fix: Don't double-free when calling
NSData.dataWithBytesNoCopy. We had a bug where we were double-freeing memory in the Kotlin/NativeEcdsaP256signature verifier. - Upgrade: Kotlin Serialization 1.6.0.
[1.2.0] - 2023-08-09
- Upgrade: Kotlin 1.9.0
- Upgrade: kotlinx.coroutines 1.7.3
[1.1.0] - 2023-07-30
- New: Gradle tasks
ziplineApiCheckandziplineApiDump. These tasks work like Kotlin’s Binary compatibility validator: the Dump task writes your public API to a file (api/zipline-api.toml) and the the Check task confirms that your public API matches that file. These two tasks expose the IDs Zipline uses for functions. The:ziplineApiChecktask configures itself a dependency of Gradle's:checktask: you'll need to run:ziplineApiDumpwhen applying this update and each time your public API changes going forward. - Upgrade: Kotlin 1.8.21.
- Upgrade: kotlinx.coroutines 1.7.2.
- Upgrade: Kotlin Serialization 1.5.1.
[1.0.0] - 2023-06-12
This is Zipline's initial stable release.
With this release we commit to compatibility between host and guest programs. In particular, host applications built with any Zipline 1.x release will be able to execute guest applications built with any other 1.y release. (Application developers must write compatible interfaces to take advantage of this!)
The following are now stable:
- The manifest file format (
manifest.zipline.json) - The library file format and bytecode within (
my-library.zipline) - The host-guest call protocol
- The internal host-guest APIs for async calls, console logging, and leak notifications
As we add features and performance improvements to future releases, we will test compatibility with 1.0.
We expect to someday do ‘Zipline 2.0’ that uses WebAssembly. When that happens we’ll make sure the 2.x tools can also produce programs that run on 1.x hosts.
- Fix: Don't allow services with the different generic parameters to collide in the cache. We had
a severe bug where two services would share serializers for unrelated types. This would typically
result in a
ClassCastExceptionat runtime.
[0.9.20] - 2023-06-01
- Downgrade: Kotlin 1.8.20. (Our users aren't ready for 1.8.21 yet.)
- Downgrade: Kotlin Serialization 1.5.0. (Requires Kotlin 1.8.21.)
[0.9.19] - 2023-06-01
- Breaking: Change the calling convention between host and guest code to identify functions by IDs
instead of by their signatures. We renamed
ZiplineFunction.nametosignatureand added a newidproperty. - Breaking: Change the built-in services to share a single identifier rather than bridging them
separately based on feature (
console,event_loop,event_listener.) - Breaking: Move
ZiplineManifestfromapp.cash.zipline.loadertoapp.cash.zipline. It was also promoted to the mainziplineartifact. - New:
ZiplineService.targetTypecan be used to inspect the function declarations on the peer's version of a service. - New:
EventListener.manifestVerified()signals successful signature checks of the manifest. - New: Convert
zipline-profilerinto a multiplatform artifact. - Upgrade: Kotlin 1.8.21.
- Upgrade: kotlinx.coroutines 1.7.1.
- Upgrade: Kotlin Serialization 1.5.1.
[0.9.18] - 2023-04-17
- New: Support pass-by-reference of
StateFlowvalues. - Upgrade: Kotlin 1.8.20.
- Fix: Don't crash applying source maps to QuickJS bytecode. We had a longstanding off-by-one error interpreting an encoded function's flags.
- Fix: Retry web sockets when polling for fresh code in development mode. Previously we fell back to polling after a single web socket error.
- Fix: Don't
ClassCastExceptionwhen running Gradle in continuous mode. We were failing to post web socket updates when fresh code is available.
[0.9.17] - 2023-03-15
- Upgrade: Kotlin 1.8.10.
- Upgrade: Kotlin Serialization 1.5.0.
- Fix: Support function overloads in
ZiplineServiceinterfaces. - Fix: Workaround a crash in Kotlin/JS incremental compilation. We were using a constant string in
a
js(...)literal.
[0.9.16] - 2023-02-09
- New
withDevelopmentServerPush()subscribes to the local development server's websocket to trigger hot reloads. This is lower-latency and more efficient than polling. - Upgrade: Kotlin 1.8.0.
[0.9.15] - 2023-01-25
- Fix: Don't crash if canceled with a 0-delay job enqueued. We had a bug where calling
Zipline.close()could race with an enqueued job. - Fix: Don't crash in the JS CoroutineEventLoop. This replaces an
IllegalStateExceptionwith aCancellationExceptionwhen making a suspending call after the Zipline is closed. - Fix: Do not set
-Xir-per-module. This is no longer necessary, and may have prevented whole-program module generation. - New: Support Webpack builds. In addition to modular builds that emit many
.ziplinefiles per program, webpack builds emit a single minified.ziplinefile. (In both cases a single manifest file is used.) - New: We've added event listener events for the loader's initializer and main function.
[0.9.14] - 2023-01-16
- Fix: Don’t force
suspendfunctions to suspend. We've changed our calling convention so suspendable functions are executed inline and on the same call stack until they suspend. If such functions return without suspending, the async dispatch is skipped. - Fix: Provide more information when calling a closed service.
- Fix: Clean up file names in stack traces.
- New: Add a
ZiplineManifesttoLoadResult.Success.
[0.9.13] - 2022-12-22
- New:
ZiplineScopeis a new mechanism to close pass-by-reference services and flows. Pass aZiplineScopetoZipline.take()or implementZiplineScopedin aZiplineServiceto declare a scope, then callZiplineScope.close()to close all received services. Note that Flows that were passed-by-reference previously needed to be collected exactly once; with this change Flows may be collected any number of times. - New: Configure the development HTTP server's local port in Gradle:
zipline { ... httpServerPort.set(22364) } - New: Include the service name in
ZiplineApiMismatchException. - Fix: Prevent
.ziplinefiles from being stored in the HTTP cache. We've added 'Cache-Control: no-store' request headers to downloads to prevent caching that's redundant with ZiplineLoader's cache. - Fix: Make
ZiplineService.close()idempotent for outbound services.
[0.9.12] - 2022-12-06
- New: Add
ZiplineFunction.isSuspending. - New: Add events for
ziplineCreate(),moduleLoadStart(), andmoduleLoadEnd().
[0.9.11] - 2022-12-05
- New: Publish an event when Zipline is closed.
- Fix: Avoid a linear search through endpoint names.
[0.9.10] - 2022-11-30
- New: Add support for
varandvaldeclarations in service interfaces. - Fix: Update Gradle task to serve zipline files for compatibility with Gradle 7.6.
[0.9.9] - 2022-11-16
- Changed: Roll back Kotlin 1.7.20 to ensure downstream users can still use Compose easily. The plugin remains compatible with 1.7.21.
[0.9.8] - 2022-11-16
- New: Support Kotlin 1.7.21.
[0.9.7] - 2022-11-11
- Breaking: Change
EventListenerto pass theZiplineinstance when it is available. - Breaking: Introduce
EventListener.applicationLoadSkipped()when a downloaded manifest hasn't changed. - New: The development server (
serveDevelopmentZipline) now notifies code changes via web socket. Connect to/wsto receive"reload"messages.
[0.9.6] - 2022-10-13
- Fix: Don't fail with
unexpected callerrors because code was not being rewritten by our Kotlin compiler plugin.
[0.9.5] - 2022-10-06
- New: Support
@Contextualas a type annotation onZiplineServiceparameters and return types. This will attempt to find a contextual serializer for the annotated type. - Breaking: Rename
LoadedZiplinetoLoadResult. This allowsZiplineLoader.load()to return a flow that includes both successes and failures. - Breaking: Remove
eval()support from QuickJs. As a security measure Zipline doesn't support evaluating JavaScript at runtime.
[0.9.4] - 2022-09-07
- New: Build in a basic HTTP client for Apple platforms.
- Breaking change: Wrap exceptions thrown in bridged calls with
ZiplineException. Previously these were wrapped inExceptionwhich was difficult to catch generically.
[0.9.3] - 2022-08-23
- Breaking change: Move
SerializersModulefrom a property ofZiplineLoaderto a parameter inload()andloadOnce(). This enables using a single loader for different applications that have different serializers. - Breaking change: Make
ZiplineCachea top-level type. It has its own lifecycle and is best managed directly. - Breaking change: Pass a
startValueparameter consistently to event listener callbacks. - New: Extension
OkHttpClient.asZiplineHttpClient()makes it easier to use general-purpose Zipline APIs from multiplatform code.
0.9.2 - 2022-08-22
- Breaking change:
ZiplineLoader.load(...)is no longer suspending. - Breaking change: Don't require implementors of
ZiplineHttpClientto implement URL resolution. - Breaking change: Include a default clock implementation on iOS.
- Breaking change: Require callers to explicitly opt out of signature checks. Pass
ManifestVerifier.Companion.NO_SIGNATURE_CHECKSto useZiplineLoaderwithout code signature verification. - New: Support ECDSA P-256 for signatures.
0.9.1 - 2022-08-18
- New: Gradle extension
zipline {}block. - New: Compile files in parallel.
- New: Replace webpack with a dedicated static file server. Use
serveDevelopmentZiplineorserveProductionZiplineto serve an application locally. - Fix: Always run Kotlin/JS in strict mode.
- Upgrade: Kotlin Serialization 1.4.0.
0.9.0 - 2022-08-05
- New:
ZiplineLoaderis a new module to launch Zipline applications quickly. It supports caching including offline launching, code signing, and launching from a flow. - New: Zipline's Gradle plugin makes it fast and easy to use build Zipline applications.
- New:
EventListenermakes it easy to observe with Zipline performance and problems. - Upgrade: Kotlin 1.7.10.
[0.1.0] - 2021-09-30
We've changed this project to focus exclusively on executing Kotlin/JS libraries.
We plan to drop support for executing arbitrary JavaScript code. If you've been using either QuickJS Java (this project's name until September 2021) or Duktape Android (this project's name until June 2021), those projects remain as git branches but will not receive further updates.
The project's new Maven coordinates are app.cash.zipline:zipline.
Added
Ziplineis a new entry point for connecting to Kotlin/JS libraries.ZiplineReferencesupports sending service objects across platforms.ZiplineSerializersupports sending serializers objects across platforms.FlowReferencesupports sendingFlowobjects across platforms.InterruptHandlerinterrupts executing JavaScript.MemoryUsageinterrogates the state of the JavaScript runtime.
Changed
QuickJsentry point moved toapp.cash.zipline.
QuickJS Java change log
0.9.2 - 2021-08-04
Added
compile()method takes JS source and produces a version-specific bytecode representation.execute()method takes version-specific bytecode and runs it.
Changed
- Methods are no longer
synchronized. If you are performing concurrent access add your own synchronization.
Fixed
- Self-extract native libraries from JAR when running on the JVM.
- Correct UTF-8 handling of multi-byte graphemes to avoid mismatch between Java's modified UTF-8 and QuickJS's traditional UTF-8.
0.9.1 - 2021-07-12
JVM artifact is now available at app.cash.quickjs:quickjs-jvm for Linux and Mac OS!
Fixed
- Handle null argument array which was sometimes supplied to native code instead of a zero-element array.
- Properly track the associated proxy class from native code to avoid a segfault.
- Eliminate a segfault during engine close when cleaning up proxied objects.
0.9.0 - 2021-06-14
Backing JS engine change to QuickJS.
Package name is now app.cash.quickjs.
Entrypoint is QuickJs class.
Maven coordinates are now app.cash.quickjs:quickjs-android.
The API and behavior should otherwise be unchanged.
Duktape Android change log
Version 1.4.0 (2021-06-14)
- New: Update to Duktape 2.6.0.
- Fix: Correct a few JNI reference leaks which may have eventually caused a native crash.
- Migrated to AndroidX annotations.
Version 1.3.0 (2018-08-02)
- New: update to Duktape 2.2.1.
- Fix: update build settings to reduce AAR output size.
Version 1.2.0 (2017-09-08)
- New: support for arrays of supported types as arguments between Java/JavaScript.
- New: update to Duktape 1.8.0.
- Fix: explicitly release temporary JVM objects when returning from calls to Java from JavaScript.
- Fix: allocate a local frame when binding Java interfaces to allow many methods and arguments.
Version 1.1.0 (2016-11-08)
- New: support parsing common date formats in JavaScript's "new Date('str')" constructor.
- Fix: Duktape.evaluate returns null if the implicit return type is unsupported.
Version 1.0.0 (2016-09-28)
- Renamed Duktape.proxy and Duktape.bind to Duktape.get and Duktape.set.
- New: support for arguments of type Object between Java/JavaScript.
- New: support variadic (VarArgs) functions on Java/JavaScript calls.
- Fix: Make creation and use of a Duktape instance thread-safe.
Version 0.9.6 (2016-08-31)
- New: call JavaScript methods from Java via proxies.
- New: update to Duktape 1.5.0.
Version 0.9.5 (2016-03-07)
- New: call Java methods from JavaScript.
- New: improved stacktraces. Includes both JavaScript and Java code from the call stack.
- New: update to Duktape 1.4.0.
Version 0.9.4 (2015-11-02)
- New: expose JavaScript stacktraces when things fail.
Version 0.9.3 (2015-10-07)
- Fix: Use global refs in JNI.
Version 0.9.2 (2015-10-06)
- Fix: Get the timezone from Java rather than using UTC.
- Fix: Use recommended flags for building.
Version 0.9.1 (2015-09-22)
- Fix: Correctly propagate errors as exceptions.
Version 0.9.0 (2015-09-08)
Initial release.