Type-safe Scala.js bindings for writing k6 load tests in Scala instead of JavaScript.
- Typed facades for core k6 modules (
k6/http,k6/metrics,k6/html, gRPC, WebSockets, browser, and more) - Cross-built for Scala 2.12, 2.13, and 3.x
- Examples for sbt, Scala CLI, Mill, and Gradle
k6-jslib— optional artifact with ES-module facades over the k6 jslib CDN (e.g.k6-utils1.2.0, httpx session, k6chaijs-style assertions)
sbt (Scala.js):
libraryDependencies += "org.virtuslab" %%% "k6-scala" % "<version>"Optional jslib helpers (ES module output; pair with k6-scala):
libraryDependencies += "org.virtuslab" %%% "k6-jslib" % "<version>"Use the same <version> for both modules. For local development, sbt publishLocalDev publishes version dev for use in Scala CLI examples.
- JDK 17+ (CI uses Temurin 21)
- k6 on your
PATH - A Scala.js toolchain (sbt, Scala CLI, Mill, …)
From the repository root after sbt publishLocalDev:
scala-cli --power package examples/scala-cli-helloworld/example.scala \
--js --js-emit-source-maps \
--js-module-kind commonjs -f --js-no-opt \
-o example.js
k6 run example.jsUse --js-module-kind commonjs for scripts that rely on k6 modules that only expose a default export (for example k6/secrets). Most other facades work with ES modules as well.
k6 expects your script to expose a default-exported main (and optionally options). In Scala.js:
import scala.scalajs.js.annotation._
@JSExportTopLevel(JSImport.Default)
def main(): Unit = {
/* scenario */
}See examples/ and examples/api-examples/ for full samples.
The tables link to the official k6 JavaScript API docs. Status Supported means this repository provides Scala.js facades or pure Scala helpers intended for use with the matching k6 release line.
| Scala / topic | k6 JS API (reference) | Notes |
|---|---|---|
Core (check, fail, group, sleep, …) |
k6 module | org.virtuslab.scalajs.k6 |
| HTTP | k6/http | Methods, Params, Response, cookies, batch, FormData, … |
| Options & scenarios | Options | Options, Scenario, executors, thresholds |
| Execution | k6/execution | |
| Data | k6/data | SharedArray |
| Encoding | k6/encoding | Base64 |
| Timers | k6/timers | |
| Metrics | k6/metrics | Counter, Gauge, Rate, Trend |
| Crypto | k6/crypto | Hash, HMAC, Hasher |
| Web Crypto | Web Crypto API | subtle, getRandomValues, … |
| WebSocket (legacy) | k6/ws | connect, Socket |
| WebSocket (experimental) | k6/experimental/websockets | Browser-like API |
| gRPC | k6/net/grpc | Client, streaming |
| HTML | k6/html | parseHTML, Selection, Element |
| Browser | k6/browser | browser, Page, Locator, … |
| Secrets | k6/secrets | Requires CommonJS module kind (see below) |
Facades are compiled as ES modules and use URL imports from jslib.k6.io (pinned to k6-utils 1.2.0 unless noted in source).
| Area | k6 / jslib reference | Notes |
|---|---|---|
| Random & string utils | k6-utils | RandomUtils, StringUtils |
| HTTP session (httpx) | jslib httpx | Session |
| BDD-style assertions | k6chaijs | ChaiJS, expect, describe |
The k6/secrets facade is only reliable when Scala.js emits CommonJS. k6’s ESM path does not always expose default on namespace imports the way Scala.js expects. See examples/api-examples/k6-secrets.scala and CLAUDE.md.
k6-grpc-streaming.scala expects a running gRPC server (e.g. k6’s RouteGuide demo). It is not run in CI by default.
- User guide: this README and CONTRIBUTING.md
- ScalaDoc: run
sbt k6scala/docandsbt k6-jslib/doc, then opentarget/scala-3.x.x/api/index.htmlunder each project
sbt +test # test all Scala versions
sbt scalafmtCheckAll # formatting
sbt "k6scala/doc" "k6-jslib/doc"See CONTRIBUTING.md.
Apache License 2.0 — see LICENSE.