What Is JVM Bytecode? Java Class Files Explained

JVM bytecode is the compact instruction set the Java Virtual Machine runs. Learn how .class files work, why mods rewrite bytecode, and where ASM fits in.

Conceptsby trqUpdated June 4, 2026
Key takeaways
  • JVM bytecode is the compact instruction set the Java Virtual Machine executes.
  • The Java compiler produces bytecode in .class files, not native machine code.
  • The same .class file runs on any platform with a Java runtime, which is the point of the format.
  • Mods rewrite bytecode to change the compiled game without ever having its source.

JVM bytecode is the instruction set the Java Virtual Machine executes. When you compile Java source, the compiler does not produce machine code for your CPU. It produces bytecode, a compact, portable format stored in .class files. The JVM reads those instructions at runtime and turns them into native code as it goes.

Where Opal fits

Opal is a Fabric mod, and the modding tools it builds on do the bytecode work for you, so you do not have to touch opcodes by hand. If you want to add behavior in plain JavaScript instead, see the scripting introduction.

How source becomes bytecode

A .java file is text a person writes. A .class file is the compiled output the JVM runs. The compiler reads your source, checks it, and writes one .class file per class, each holding bytecode instructions plus a constant pool, method tables, and other metadata.

Bytecode is not tied to any one processor. The same .class file runs on Windows, macOS, Linux, or anything with a Java runtime, because the JVM is the layer that knows how to execute the instructions on the local machine. That portability is the whole point of the format.

What the instructions look like

Bytecode is a stack-based instruction set. Most operations push values onto an operand stack, pop them off, and push a result. There is no register allocation to reason about; the model is deliberately simple so the JVM can verify and execute it quickly.

A few example opcodes give the flavor:

OpcodeWhat it does
iloadPush an int local variable onto the stack
iaddPop two ints, push their sum
invokevirtualCall an instance method
getfieldRead an instance field
returnReturn from a method

You rarely read or write these by hand. Tools generate and consume them, which is where a library like ASM comes in.

Why bytecode matters for mods

Bytecode matters because it lets you change behavior without the original source. A Minecraft mod almost never has the game's source code. What it has is the compiled game on disk. To add or alter a feature, a mod reads the existing bytecode, rewrites it, and feeds the result back to the JVM as the classes load.

This is how patching frameworks insert hooks into methods they do not own. They find the right spot in a compiled method and splice in a call to the mod's code. Working at the bytecode level means a mod can attach to the game even though it never sees a line of the original Java.

Where ASM fits

ASM is a Java library for reading, writing, and transforming bytecode. It parses a .class file into events or a tree, lets code modify the instructions, and emits a valid .class file back out. It is small, fast, and works close to the raw format, which is why higher-level modding tools build on top of it rather than parsing class files themselves.

Most modders never call ASM directly. They use a higher-level layer that hides the opcodes and exposes a friendlier way to say "run my code at the start of this method." Underneath, that layer is editing bytecode, often through ASM.

FAQ