Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/LWJGL/lwjgl3/llms.txt

Use this file to discover all available pages before exploring further.

LWJGL 3 uses an Ant-based build system and a Kotlin-powered code generator. Before you write any code, you need a working JDK, Ant, and a clone of the repository. This page walks through every step from cloning to running your first demo.

Prerequisites

  • JDK 8 or newer — LWJGL 3 requires Java 8 to build and run.
  • Ant 1.9.3 or newer — All build targets are defined as Ant tasks.

Cloning and initializing

git clone https://github.com/LWJGL/lwjgl3.git
cd lwjgl3
ant init
ant init downloads Kotlin, TestNG, JCommander, and other compile-time dependencies into bin/libs/. You only need to run it once. If you also intend to work on the wiki, run ant init-wiki as well (optional).

Build process

The build pipeline runs in this order. Each step depends on the previous one completing successfully.
1

Compile the Generator and Templates

ant compile-templates
Compiles the Kotlin-based Generator module and all binding template modules.
2

Run the Generator

ant generate
Executes the Generator against every template under modules/lwjgl/*/src/templates/kotlin/. The Generator compares input and output timestamps and only writes files that have changed, keeping native recompilation to a minimum.
3

Compile Java sources

ant compile
Compiles all generated and hand-written Java sources.
4

Compile native code

ant compile-native
Compiles the C/C++ sources for the current platform. Cross-compilation to another architecture is possible via the LWJGL_BUILD_ARCH environment variable (see below).
5

Run the test suite

ant tests
Runs the TestNG test suite defined in config/tests.xml.
6

Run a demo

ant demo -Dclass=<classpath to demo>
Launches the demo class identified by the class property. Demo source files live under modules/samples/src/test/java/org/lwjgl/demo.
If incremental generation causes unexpected results, use the ant clean-* targets to force a clean rebuild of the affected module.

IDE setup

LWJGL ships a pre-configured IntelliJ IDEA project. The free Community Edition works with the Kotlin and Ant plugins. The TestNG and Copyright plugins are optional.
  1. Open File > Open and select the root folder of the cloned repository.
  2. Open File > Project Structure > Project and choose or create the Project SDK.
  3. If you skipped ant init-wiki, either ignore the VCS root errors or remove the missing directories under Settings > Version Control.

Build configuration

The Ant build reads the following optional environment variables.
VariableDescription
LWJGL_BUILD_TYPESource of pre-built binary dependencies. Valid values: nightly (default — latest CI build), stable (latest verified nightly), release/latest (latest official release), release/{version} (a specific release).
LWJGL_BUILD_ARCHTarget native architecture. One of x64, x86, arm64, or arm32. Defaults to the architecture of the JVM running Ant. Set this to cross-compile.
LWJGL_BUILD_OFFLINESet to true, on, or yes to prevent Ant from downloading binary dependencies. Useful when working offline or when using custom native builds.
LWJGL_BUILD_OUTPUTOverride the default output root. By default, /bin, /generated, and /release are created in the repository root. When this variable is set, those directories become symlinks pointing into the specified path — useful for faster storage.

Runtime configuration

LWJGL properties are read at runtime from system properties or set programmatically via the Configuration class. There are two property types:
  • STATIC — Read once during class initialization and stored in static final variables. These must be set before any LWJGL class is loaded.
  • DYNAMIC — May be read repeatedly; they can change LWJGL behavior at any point during execution.
The full list of supported options is in the Configuration class. Useful options for development include:
PropertyTypeEffect
org.lwjgl.util.DebugStaticEnables debug mode; prints info messages and activates extra runtime checks.
org.lwjgl.util.DebugAllocatorStaticTracks every memAlloc/memFree call and reports leaks on JVM exit.
org.lwjgl.util.DebugStackStaticReports asymmetric MemoryStack push/pop pairs immediately.
org.lwjgl.util.DebugLoaderStaticPrints SharedLibraryLoader exceptions (requires Debug).
org.lwjgl.librarypathDynamicOne or more directories (separated by File.pathSeparator) that take priority over java.library.path when loading natives.
Set a property programmatically before touching any other LWJGL class:
Configuration.DEBUG.set(true);
Configuration.DEBUG_MEMORY_ALLOCATOR.set(true);

The Generator

The Generator translates Kotlin template files into Java binding classes and C JNI glue code. Both the Generator itself and all binding templates are written in Kotlin.
  • Generator source: modules/generator/src/main/kotlin/org/lwjgl/generator
  • Template configuration: modules/lwjgl/<module>/src/templates/kotlin/<module>
  • Template source: modules/lwjgl/<module>/src/templates/kotlin/<module>/templates
The Generator defines a DSL that templates use to describe native functions, structs, and constants. It skips unchanged files by comparing input and output timestamps (and falls back to an in-memory content comparison), so only truly modified bindings trigger native recompilation.

Build docs developers (and LLMs) love