Browser Support Test — Kotlin source
Audit your real browser against 30 modern web capabilities - WebGPU, WASM, WebAuthn, Service Workers and more. Get a weighted readiness score, copy-paste detection snippets, and a shareable link.
This is the Kotlin implementation — the same logic the interactive tool runs, in a shareable, citable form.
// browser-support-test — Kotlin polyglot showcase port.
//
// Runtime capability probe, weighted score, and support tier.
//
// This is the Kotlin sibling of src/tools/BrowserSupportTest.tsx (+ the
// browser-support/* modules) that powers the live tool.
//
// ILLUSTRATIVE PORT: the live tool detects *browser* features at runtime
// (navigator/window probes) — a browser-only concern that cannot run in a
// JVM process. This port shows the ANALOGOUS pattern for Kotlin: probes
// query the JVM surface through Kotlin's lens — KotlinVersion, system
// properties, and class-presence lookups — the direct equivalent of
// `'feature' in window`. The scoring algorithm and tier thresholds below
// are byte-for-byte the same as the TypeScript lib's; only the probe
// targets differ.
//
// Language: Kotlin (1.9, JVM, standard library only).
// Ported from src/tools/BrowserSupportTest.tsx (+ browser-support/* modules).
// Source: CosmoDev polyglot showcase port.
// License: display source — part of CosmoDev's polyglot tool pages.
package org.cosmolabs.cosmodev.browsersupport
import kotlin.math.roundToInt
private const val SUPPORTED = "supported"
private const val LIMITED = "limited"
private const val UNSUPPORTED = "unsupported"
private const val UNKNOWN = "unknown"
/** One capability the audit can check: [probe] returns true when the
* capability is present in THIS runtime. */
private data class Check(
val id: String,
val title: String,
val category: String,
val weight: Double,
val probe: () -> Boolean,
)
/** Outcome of one probe. */
private data class FeatureResult(val id: String, val status: String)
/** contribution × weight. Same values as src/tools/browser-support/score.ts. */
private fun contribution(status: String): Double = when (status) {
"supported" -> 1.0
"limited" -> 0.5
"needs-https" -> 0.3
else -> 0.0 // unsupported, unknown
}
/** Class-presence probe: true when [name] is loadable in THIS JVM
* (looked up without running static initializers). */
private fun hasClass(name: String): Boolean = try {
Class.forName(name, false, ClassLoader.getSystemClassLoader())
true
} catch (e: ClassNotFoundException) {
false
}
/** Weighted readiness 0–100; matches computeScore() exactly. Results whose
* id isn't in the catalog are ignored. */
private fun computeScore(results: List<FeatureResult>, catalog: List<Check>): Int {
val weights = catalog.associate { it.id to it.weight }
var earned = 0.0
var possible = 0.0
for (r in results) {
val w = weights[r.id] ?: continue
earned += contribution(r.status) * w
possible += w
}
if (possible == 0.0) return 0
return (earned / possible * 100).roundToInt()
}
/** tier_for mirrors tierFor() in the island — same thresholds. */
private fun tierFor(score: Int): Pair<String, String> = when {
score >= 90 -> "Fully modern" to "text-success"
score >= 75 -> "Very capable" to "text-success"
score >= 55 -> "Capable, minor gaps" to "text-accent"
score >= 35 -> "Showing its age" to "text-fg-muted"
else -> "Legacy browser" to "text-danger"
}
/** Representative catalog of JVM capability probes. */
private fun checks(): List<Check> = listOf(
Check("jvm-64", "64-bit JVM", "Platform", 1.0) {
"64" == System.getProperty("sun.arch.data.model")
},
Check("unix", "Unix platform", "Platform", 2.0) {
!System.getProperty("os.name", "").lowercase().startsWith("windows")
},
Check("coroutines", "CoroutineContext", "Language", 2.0) {
hasClass("kotlin.coroutines.CoroutineContext")
},
Check("unsigned", "Unsigned integers", "Language", 1.0) {
hasClass("kotlin.UInt")
},
Check("sequences", "Lazy sequences", "Data", 2.0) {
hasClass("kotlin.sequences.Sequence")
},
Check("virtual-threads", "Virtual threads", "Runtime", 3.0) {
hasClass("java.lang.VirtualThread")
},
)
/** Run probes; a throw degrades to 'unknown' so one failure can't abort
* the audit. */
private fun runChecks(catalog: List<Check>): List<FeatureResult> = catalog.map { c ->
val status = runCatching { c.probe() }
.fold({ if (it) SUPPORTED else UNSUPPORTED }, { UNKNOWN })
FeatureResult(c.id, status)
}
fun main() {
val catalog = checks()
val results = runChecks(catalog)
val score = computeScore(results, catalog)
val (label, _) = tierFor(score)
val supported = results.count { it.status == SUPPORTED }
println("Kotlin ${KotlinVersion.CURRENT} · ${System.getProperty("os.name")}")
println("$supported/${results.size} capabilities · readiness $score · $label")
// LIMITED is intentionally absent from probes — kept for vocabulary parity.
check(LIMITED.isNotEmpty())
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →