# TeaVM: compiling Java bytecode to JavaScript, WebAssembly and C

> TeaVM is an ahead-of-time compiler from Java bytecode to JavaScript, WebAssembly and C, aimed at JVM developers who want their code running in a browser or a WASM runtime. It ships its own class library reimplementation, which is the source of both its independence and its main constraint.

**konsoletyper/teavm** — Compiles Java bytecode to JavaScript, WebAssembly and C

- Repository: https://github.com/konsoletyper/teavm
- Website: https://teavm.org
- Stars: 3,118 · Forks: 339
- Language: Java
- License: Apache-2.0
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/konsoletyper-teavm

## What TeaVM solves, and who actually needs it

The problem is narrow but real: you have Java bytecode, and the place you want it to run has no JVM. The README describes TeaVM as compiling Java bytecode to JavaScript, WebAssembly and C, which puts it in the ahead-of-time camp rather than the interpreter or JIT camp. That distinction matters. TeaVM does not ship a virtual machine that interprets your classes at runtime; it translates them ahead of time into a target language, and the resulting artifact runs on whatever engine that target language already has, typically a browser engine or a standalone WASM runtime.

The audience follows from that. If your code is a library, a game, a simulation, a tool, or a business application written against a subset of the Java class library, and you want it distributed as a web page or a WASM module, TeaVM is a candidate. If your code assumes a servlet container, a database driver, threads with real concurrency, or a JVM-specific runtime API, the translation target has no equivalent and the fit is poor. The repository's own samples directory hints at where the project puts its emphasis: hello, async, promise, web-apis, gamepad, kotlin, kotlin-coroutines, scala, pi, software3d, benchmark, emscripten, wasm-sab, module-test and stdout-helper. That is a browser-and-WASM-shaped list, not an enterprise-server list.

## How the bytecode-to-target pipeline is structured

TeaVM consumes Java bytecode, not Java source. That means the front end of your toolchain can be javac, the Kotlin compiler, or the Scala compiler; the samples directory contains kotlin, kotlin-coroutines and scala entries, which is consistent with that design. Whatever produces the .class files, TeaVM reads them.

The repository layout shows the pieces. core/ holds the compiler itself, and the README names org.teavm.vm.TeaVM from the teavm-core artifact as the lower-level entry point. platform/ and classlib/ hold the platform and class library layers. interop/ and jso/ deal with crossing the boundary between Java and the host language, which is unavoidable when the output is JavaScript. extension/, metaprogramming/ and html4j/ are additional layers, and tools/ contains build tooling. The README points at :tools:classlib-comparison-gen:build, which builds a Java class library compatibility report into tools/classlib-comparison-gen/build/jcl-support. That task exists because TeaVM does not use OpenJDK's class library, so the question of which java.* and javax.* APIs are actually available is a live one for every user.

The key architectural fact is stated plainly in the README: TeaVM has its own reimplementation of the Java class library, implemented from scratch or based on non-(L)GPL projects, specifically Apache Harmony, Joda-Time and jzlib. This is why the project can say it does not rely on OpenJDK or other (L)GPL code, and it is also why API coverage is a moving target rather than a given.

## Installing TeaVM and compiling a first sample

The README does not give a step-by-step install for end users; it points to the project website, specifically the Getting started page at teavm.org/docs/intro/getting-started.html, and notes that TeaVM is published to Maven Central, where the artifact shown in the badge is org.teavm:teavm-maven-plugin. So the practical route is a Maven or Gradle build plugin, and the README explicitly says that if you are not satisfied with Maven you can embed TeaVM or write your own plugin for a build tool such as Ant or Gradle.

If you want to build TeaVM itself from source, the README gives the commands directly. Cloning the repository and running the Gradle wrapper publishes the artifacts to your local Maven repository:

```bash
git clone https://github.com/konsoletyper/teavm.git
cd teavm
./gradlew publishToMavenLocal
```

On Windows the README gives gradlew.bat publishToMavenLocal as the equivalent. Note the README's warning that samples must be built separately, as described in samples/README.md. The samples directory has its own Gradle wrapper (samples/gradlew and samples/gradlew.bat) and its own settings.gradle.kts, which is consistent with it being a separate build rather than a subproject of the root build.

For the class library compatibility question, the README names one Gradle task worth running:

```bash
./gradlew :tools:classlib-comparison-gen:build
```

The README states the result lands at tools/classlib-comparison-gen/build/jcl-support. That report is the concrete thing to read before assuming a given java.* API is implemented. The README does not document what the report's format looks like, only where it is written.

## The class library is the real constraint, not the compiler

The compiler translating bytecode is not usually where a TeaVM project fails. The class library is. TeaVM reimplements the Java class library rather than linking OpenJDK's, and the README lists its bases: Apache Harmony, Joda-Time and jzlib. Anything in your dependency graph that reaches into JDK internals, relies on a specific OpenJDK behaviour, or uses an API the reimplementation has not covered will not translate.

This is a structural trade-off, not a bug. Avoiding (L)GPL code is the stated reason for the reimplementation, and the licence section is explicit that contributors must not base class library code on OpenJDK or other (L)GPL-licensed code. The cost is coverage and behavioural fidelity. The existence of :tools:classlib-comparison-gen:build is itself evidence that the project treats coverage as something users need to measure rather than assume.

The second constraint is the embedding API. The README says the APIs for embedding are still unstable and may change between versions, and points at org.teavm.tooling.TeaVMTool from teavm-tooling as the starting point, with org.teavm.vm.TeaVM from teavm-core underneath. If you write your own build plugin against those classes, you are signing up to track changes across releases. The release history shows three releases in the months before this writing, 0.15.0 on 2026-06-14, 0.14.1 on 2026-05-25 and 0.14.0 on 2026-05-02, so the surface does move.

## TeaVM compared with GWT, and what the difference really is

The most common comparison for TeaVM is GWT, and the difference is at the input boundary. GWT compiles Java source, which means it has to model the Java language and its own subset rules at the source level. TeaVM compiles Java bytecode. In practice that means TeaVM can accept output from any JVM language compiler, which is why the samples include Kotlin and Scala alongside plain Java. A GWT-style source-level compiler cannot take a Kotlin-generated class file as input.

The second difference is the output set. TeaVM targets JavaScript, WebAssembly and C. GWT's output is JavaScript. If your deployment target is a WASM runtime or a native binary produced through C, that is a different set of options rather than a different quality of the same option.

The trade-off is that bytecode input gives up source-level information. Diagnostics, source maps and error messages have to be reconstructed from bytecode and debug attributes rather than read directly from source. The README does not discuss debugging support or source maps, so that is a question to answer from the documentation site rather than from the repository README. If you are choosing between the two on the basis of tooling maturity rather than input flexibility, the README gives you no grounds to prefer TeaVM; it gives you grounds to prefer it when your source language is not Java or when your target is WebAssembly.

## Maintenance, licensing and what upgrades cost

The repository is not archived, and the last push was on 2026-09-15, which is recent. Releases are frequent enough that a pinned version will age: 0.14.0, 0.14.1 and 0.15.0 all landed within roughly six weeks of each other. The embedding APIs are documented as unstable, so a project that embeds TeaVMTool rather than using the Maven plugin carries the upgrade cost directly. A project that uses the Maven plugin carries it indirectly, through class library coverage changes between versions.

On licensing, TeaVM is distributed under Apache License 2.0, and the README states that TeaVM does not rely on OpenJDK or other (L)GPL code. The class library is based on Apache Harmony (Apache 2.0), Joda-Time (Apache 2.0) and jzlib (a BSD-style licence). The README also sets a contribution rule: if you contribute to the class library implementation, the code must not be based on OpenJDK or other (L)GPL-licensed code. That rule is worth reading before you plan to port an existing JDK class into the project. This is a description of what the README says, not legal advice; if the licence interaction between TeaVM, your dependencies and your distribution model matters to your organisation, that is a question for your own counsel.

The upgrade question to settle early is whether you depend on behaviour that the class library comparison report shows as implemented, partially implemented or absent. That report is regenerated by a Gradle task, so you can produce it for the version you are considering instead of guessing.

## Conclusion

TeaVM fits teams that already have JVM code and want it running in a browser or a WebAssembly runtime without rewriting it, and who accept that the class library is TeaVM's own reimplementation rather than OpenJDK. It does not fit projects that depend on the full JDK surface, on reflection-heavy frameworks, or on JNI. Before committing, check the class library compatibility report produced by the :tools:classlib-comparison-gen:build Gradle task, confirm the embedding APIs are still marked unstable, and verify that your target output (JavaScript, WebAssembly or C) is one the samples actually demonstrate for your build tool.

## FAQ

### How do I use TeaVM to compile Java to JavaScript or WebAssembly?

The README directs users to the Getting started page at teavm.org/docs/intro/getting-started.html and notes that the project publishes a Maven plugin, org.teavm:teavm-maven-plugin, to Maven Central. TeaVM consumes Java bytecode, so any compiler that produces class files can feed it.

### What is a TeaVM alternative if I need Java in the browser?

The closest comparison is GWT, which compiles Java source rather than Java bytecode. That difference means GWT cannot take class files produced by the Kotlin or Scala compilers, while TeaVM's bytecode input can, and TeaVM also targets WebAssembly and C in addition to JavaScript.

### Does TeaVM use the OpenJDK class library?

No. The README states that TeaVM has its own reimplementation of the Java class library, built from scratch or on Apache Harmony, Joda-Time and jzlib, and that the project does not rely on OpenJDK or other (L)GPL code. The repository includes a Gradle task, :tools:classlib-comparison-gen:build, that produces a compatibility report.

### How do I build TeaVM from source?

The README says to clone the repository and run the Gradle wrapper, either ./gradlew publishToMavenLocal or gradlew.bat publishToMavenLocal on Windows. It adds that samples must be built separately, as described in samples/README.md.

### Can I embed TeaVM in my own build tool instead of using Maven?

Yes. The README says that if you are not satisfied with Maven you can embed TeaVM in your program or create your own plugin for a build tool such as Ant or Gradle, starting from org.teavm.tooling.TeaVMTool in the teavm-tooling artifact. It warns that these embedding APIs are still unstable and may change between versions.

## Sources

- [konsoletyper/teavm on GitHub](https://github.com/konsoletyper/teavm)
- [License: Apache-2.0](https://github.com/konsoletyper/teavm/blob/master/LICENSE)
- [Project website](https://teavm.org)
- [README](https://github.com/konsoletyper/teavm/blob/master/README.md)
- [Releases](https://github.com/konsoletyper/teavm/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/konsoletyper-teavm
