# gdx-liftoff and the case for a generator that knows which JDK you need

> gdx-liftoff is a setup tool for libGDX Gradle projects that fills in the versions, the target platforms and the language levels for you, and its documentation spends most of its length on the Java version matrix because that is where new users get stuck. Its real product is the project template, and its real cost is the number of combinations it has to keep consistent.

**libgdx/gdx-liftoff** — A modern setup tool for libGDX Gradle projects

- Repository: https://github.com/libgdx/gdx-liftoff
- Stars: 688 · Forks: 71
- Language: Kotlin
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/libgdx-gdx-liftoff

## One jar, and a project that already matches the framework version

gdx-liftoff is a setup tool for libGDX Gradle projects, and the workflow is deliberately short.

You download the latest application jar from the releases page and run it, and running it is usually a matter of double-clicking the file. If you would rather use a terminal, the command is:

```shell
java -jar gdx-liftoff-VERSION.jar
```

The release also targets libGDX 1.14.2 by default, which is the detail that tells you how the tool thinks. It is not a generic Gradle project generator with a libGDX flavour, it is a generator for a specific framework version, and the framework version is chosen for you.

The packaging is worth a note too. Recent releases also provide downloads named for specific operating systems, but the jar without an operating system in its name works on all platforms, and that one is the recommended choice. A single cross-platform jar avoids the question of which of the per-platform builds you actually grabbed.

The project is written in Kotlin, licensed Apache-2.0, and its build is a Gradle project of its own, with a build.gradle, settings.gradle, a gradle.properties and a version.txt at the root alongside src/ and a Guide.md and Troubleshooting.md.

## The Java version matrix is the whole difficulty, spelled out

Most of the documentation is about Java versions, and reading it explains why a setup tool is needed at all.

The build requirement is Java 17 or newer, up to 27. The reason given is that Gradle's current version, as well as current Android tools, now require an installed JDK of version 17 or higher, and that regardless of which platforms you target, Gradle 8.10 and up need a JDK of at least 17. You can still target older releases, as low as 8 typically, while building with any JDK from 17 upward.

The subtlety is that the JDK you build with and the language level you target are different numbers, and the tool handles both. For a browser target via GWT you need language level 8 or 11, with 11 recommended. For iOS via RoboVM you are limited to at most Java 8 language features and will not have access to any APIs added in Java 8, so at most APIs from 7 are available, and Liftoff forces language level 8 for RoboVM even if other modules use a higher level. For a browser target via TeaVM the module always uses at least language level 17, even if a lower level is used in core or other modules.

The warning that matters most for a first project is about how to enter the number. When you enter the JDK version for a project it is always one integer, such as 8 or 21, and entering a bugfix or point release will confuse Gradle and lead to bizarre bugs. JDK versions and language levels never include bugfix versions, and the entry should always be a single int with no dot or separator character.

## Why JDK 21 exactly, and which JDK to install

The tool recommends a specific JDK version for a specific reason, and the reason is about packaging rather than about the code.

If you use a JDK version that is not 21 for Gradle, the automatic desktop release packaging with Construo needs some configuration changes so that it downloads the same version of JDK that Gradle uses. The project describes this as not hard but tedious, and recommends using 21 exactly for that reason, with a troubleshooting document explaining how to change the Construo JDK download links so a different JDK can be bundled.

For people who do not know what JDK they have, or do not have one, the guide recommends the JDK 21 installers from OpenJDK vendors, naming BellSoft Liberica and Azul Zulu, and says they are recommended for Windows and macOS users because they have good default settings in their MSI Windows installers. It explicitly does not recommend Oracle's OpenJDK, and gives two reasons. The first is that Oracle's installers have confusing default options. The second is licensing clarity, because the OpenJDK vendors that must use GPL v2 with the Classpath Exception as their licence have clearer terms, and Oracle can and has changed its licensing without much warning.

On Linux the answer is the package manager and OpenJDK 21. On macOS there is a wrinkle: you might need both an AARCH64 and an x86_64 OpenJDK, because any tools still using LWJGL2 need the x86_64 build and will run through Rosetta. The Windows links given are also said to have working macOS installers.

The final instruction is the one people skip. Do not install a JRE. If a JRE is installed, it should be replaced with a JDK and the JDK made the default.

## Java 25 and 27 bring a new LWJGL constraint, and it is fiddly

The newest paragraph of the documentation is about the current JDKs, and it is the part most likely to affect a project you are starting today.

Java 25 through 27 are now somewhat supported to build projects, in recent Liftoff versions. Java 25 includes useful features for reducing memory usage, if you enable them, using the Compact Object Headers flag to launch. Java 27 came out on September 15, 2026 and is, in the project's phrase, surprisingly already supported by Gradle, and a major improvement in Java 27 is enabling Compact Object Headers by default.

Running with Java 25 or newer requires LWJGL3 to be version 3.4.0 or later, and the current Liftoff version handles that automatically using Gradle constraints. If you need an older LWJGL3 you can change lwjgl3Version in gradle.properties, which makes the constraints require a version of your choosing, and one reason to want that is better support for Wayland on Linux, which changed how it worked starting in LWJGL 3.3.4.

The current state is that libGDX 1.14.2 uses LWJGL 3.3.3 unless some Gradle config changes that version, and the constraints now default to LWJGL 3.4.3 instead, which is what allows Java 25 and up to work. The practical guidance is to leave lwjgl3Version at 3.4.3, or set it to 3.3.3 for the Wayland reason.

There is one more behavioural change worth knowing. Running on Java 25 or newer with the sun.misc.unsafe-memory-access option set to deny, which will be the default in future JDKs, makes LWJGL3 use the new foreign function memory APIs instead of the older and scheduled-to-be-removed sun.misc.Unsafe class.

## The alternatives the tool mentions, and what a native build costs

The documentation also covers the two paths a project might take that are not the default.

Advanced users may want to try GraalVM, either to run the project or to build a native-image distributable. Native-image, also called Substrate VM, avoids distributing a JDK at all by compiling a fairly small executable to native code. The trade-offs are stated: it starts up quickly, but cannot reach as high a peak speed as a JDK normally can, and may stutter when the garbage collector runs, so it is not always a great option for games. The narrower case where it makes sense is a game that already performs very well and does not produce much garbage, and there is a second reason, that a native binary is harder to decompile than a jar, which is trivial to take apart.

Liftoff includes some very out-of-date native-image configuration that is disabled by default, and you can enable it in gradle.properties by setting enableGraalNative to true. The documentation then points at Construo for building native launchers.

For iOS via RoboVM, the constraint repeats because it is a common source of confusion. You are limited to at most Java 8 language features and will not have access to any APIs added in Java 8, so at most APIs from 7 are available, and you need to make sure the code you write is compatible with RoboVM if you target it. The project files a DINish licence in a file of its own alongside the main licence, and there are separate documents for the architecture, for GWT and a general guide, which reflects how many platforms this one generator has to cover.

## Where gdx-liftoff is the wrong choice

The first case is a team that already has a working libGDX build. If your Gradle configuration is settled, the JDK is pinned and the language levels are decided, a generator that rewrites them is a liability rather than a convenience.

The second is anyone who wants to be on the bleeding edge of a platform support. The generated versions move at the pace of the releases, so a new JDK or a new target platform is only available once a Liftoff version catches up, and the changelog between releases is where you would look to see that. The project is candid about this, describing Java 25 through 27 as only somewhat supported to build projects.

The third is a project outside libGDX. This is a generator for libGDX Gradle projects, and none of the Java version reasoning, the LWJGL constraint, the RoboVM language level or the TeaVM rule applies to a different framework. Reading the tool for general Gradle advice is possible but the specifics do not transfer.

The fourth is the multiplicity of targets itself. A project targeting desktop, Android, iOS through RoboVM, and the browser through both GWT and TeaVM has to accept language level 8 in some modules and 17 in another, and the tool does the bookkeeping but cannot remove the constraint. A project that targets one platform would be better served by a simpler template.

## Conclusion

gdx-liftoff suits a developer starting a libGDX project who would otherwise spend an afternoon matching JDK versions, Gradle versions and per-target language levels by hand, since that mapping is the entire job and the tool encodes it. It does not suit a team with a fixed build pipeline that already pins everything, and it does not suit someone who needs the newest platform support on the day it lands, because the generated versions move at the pace of the releases. Before you generate a project, read the Java version section rather than the tooltips, since the JDK and language level combination is the part that produces obscure failures, and note that the last push was on 2026-10-19 with the newest release v1.14.2.3 dated 2026-09-26.

## FAQ

### What is gdx-liftoff?

It is a setup tool for libGDX Gradle projects, written in Kotlin and licensed Apache-2.0. You download a jar from the releases page and run it, and it generates a project with the framework version, the JDK, the Gradle setup, the dependency versions and the per-target language levels already filled in.

### Which Java version do I need to build a gdx-liftoff project?

Java 17 or newer, up to 27, because Gradle 8.10 and up and current Android tools require it. You can still target older releases, as low as 8 typically, while building with any JDK from 17 upward. The project recommends 21 exactly, because a non-21 JDK needs extra configuration for the automatic desktop packaging with Construo.

### How do I enter a JDK version in gdx-liftoff?

As one integer, such as 8 or 21, with no dot and no other separator. Entering a bugfix or point release confuses Gradle and leads to bizarre bugs, because JDK versions and language levels never include bugfix versions.

### What language level does gdx-liftoff use for iOS, GWT and TeaVM targets?

For iOS via RoboVM it forces language level 8, and you get at most APIs from Java 7. For the browser via GWT you need level 8 or 11, with 11 recommended. For the browser via TeaVM the module always uses at least language level 17 even if other modules use a lower one, and building with JDK 21 makes level 17 work out of the box.

### Does gdx-liftoff support Java 25 and Java 27?

Yes, in recent versions, though the project calls it somewhat supported to build projects. Java 25 and up requires LWJGL3 version 3.4.0 or later, which the current version handles automatically through Gradle constraints, and Java 27 is already supported by Gradle. You can override lwjgl3Version in gradle.properties if you need an older LWJGL3.

## Sources

- [Issues](https://github.com/libgdx/gdx-liftoff/issues)
- [libgdx/gdx-liftoff on GitHub](https://github.com/libgdx/gdx-liftoff)
- [License: Apache-2.0](https://github.com/libgdx/gdx-liftoff/blob/master/LICENSE)
- [README](https://github.com/libgdx/gdx-liftoff/blob/master/README.md)
- [Releases](https://github.com/libgdx/gdx-liftoff/releases)

---

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