Skip to main content

Seamless k6.io Performance Testing in Scala Projects Using Scala.js

Picture of Michał Wiącek, Software Engineer

Michał Wiącek

Software Engineer
Jan 20, 2026|22 min read
colourfull_wave
1//> using scala "3.5.0"
2//> using platform scala-js
3
4package example
5
6import scala.scalajs.js
7import scala.scalajs.js.annotation.*
8
9@js.native
10object k6 extends js.Object {
11 def check(response: Response, checks: js.Dictionary[Boolean]): Boolean = js.native
12 def sleep(response: Int): Unit = sjs.native
13}
14
15@js.native
16object http extends js.Object {
17 def get(url: String): Response = js.native
18}
19
20@js.native
21trait Response extends js.Object {
22 def body: String = js.native
23 def status: Int = js.native
24}
25
26@JSExportTopLevel(JSImport.Default)
27object K6ScalaExample {
28 @JSExport
29 def main(): Unit = {
30 val response = Http.get("https://quickpizza.grafana.com/")
31 }
32}
1//> using scala "3.5.0"
2//> using platform scala-js
3//> using dep "org.scala.js::k6-scala::0.0.1-SNAPSHOT"
4
5package example
6
7import scala.scalajs.js
8import scala.scalajs.js.annotation.*
9import org.scala.js.k6.http.Http
10
11@JSExportTopLevel(JSImport.Default)
12object K6ScalaExample {
13 @JSExport
14 def main(): Unit = {
15 val response = Http.get("https://quickpizza.grafana.com/")
16 }
17}
1lazy val root = Project("root", file("."))
2 .enablePlugins(ScalaJSPlugin)
3 .settings(
4 scalaVersion := "3.5.0",
5 publish / skip := true,
6 scalaJSLinkerConfig ~= {
7 _.withModuleSplitStyle(ModuleSplitStyle.FewestModules).withModuleKind(ModuleKind.ESModule)
8 },
9 runK6example := {
10 val jsTargetDir = (Compile / fullOptJS / crossTarget).value
11 val name = (Compile / fullOptJS / moduleName).value
12 val jsOutput = jsTargetDir / s"${name}-fastopt.js"
13 val log = streams.value.log
14 log.info(s"Using JS output: ${jsOutput.getAbsolutePath()}")
15 log.info(s"Running k6 test...")
16 val exitCode = Process(Seq("k6", "run", jsOutput.getAbsolutePath)).!
17 if (exitCode != 0) {
18 log.error("k6 failed!")
19 }
20 }
21)
1import mill._
2import mill.api.Loose
3import mill.scalalib._
4import mill.scalajslib._
5import mill.scalajslib.api._
6
7val projectScalaVersion = "3.5.0"
8
9object helloworld extends ScalaJSModule {
10
11 override def scalaVersion = projectScalaVersion
12 override def scalaJSVersion = "1.18.1"
13 override def ivyDeps: Target[Loose.Agg[Dep]] = super.ivyDeps() ++ Agg(
14 ivy"org.scalajs::k6-scala::0.0.1-SNAPSHOT".withDottyCompat(projectScalaVersion)
15 )
16 override def moduleKind = ModuleKind.ESModule
17 override def moduleSplitStyle = ModuleSplitStyle.FewestModules
18 override def sources = T.sources {
19 Seq(millSourcePath / "src").map(PathRef(_))
20 }
21
22 def runK6test() = T.command {
23 val jsFilePath: os.Path = fastLinkJS().dest.path / "main.js"
24 println(s"Using JS output: $jsFilePath")
25 val exitCode = os.proc("k6", "run", jsFilePath).call(stdout = os.Inherit, stderr = os.Inherit).exitCode
26 if (exitCode != 0) {
27 throw new Exception("k6 failed!")
28 }
29 }
30}
1hyperfine -r 100 -p 'rm -rf .scala-build/ example.js example.js.map' 'scala-cli --power package example.scala --js --js-emit-source-maps --js-module-kind esmodule -f --js-no-opt'
2hyperfine -r 100 'k6 run example.js'
3hyperfine -r 100 'k6 run pure.js'
4hyperfine -r 100 -p 'mill clean' 'mill helloworld.fastOpt'
5hyperfine -r 100 -p 'sbt clean' 'sbt fastOptJS'
6hyperfine -r 100 -p './gradlew clean' './gradlew link'
7hyperfine -r 100 'sbt runK6test'
8hyperfine -r 100 'mill runK6test'
9hyperfine -r 100 './gradlew runK6test'

Subscribe to our newsletter and never miss an article