A fast, dependency-light Minecraft NBT (Named Binary Tag) reader/writer for Java 21. Handles every tag type across the binary, gzip-compressed, SNBT, JSON, and base64 wire formats.
Important
The NBT binary format is a specification designed by Mojang AB (a Microsoft subsidiary). This library is a clean-room implementation of that specification - no Mojang code or assets are bundled. You are responsible for ensuring your use of NBT data complies with the Minecraft EULA and Minecraft Usage Guidelines.
- Every tag type -
ByteTag,ShortTag,IntTag,LongTag,FloatTag,DoubleTag,StringTag,ByteArrayTag,IntArrayTag,LongArrayTag,ListTag,CompoundTag, plus the sentinelEndTag - Every wire format - raw binary, gzip-compressed binary, SNBT (stringified NBT), JSON, and base64
- Every I/O surface -
byte[],File,InputStream/OutputStream,URL, and in-memory buffers - Round-trip tested - exhaustive
NbtRoundTripTestcovers primitives at edge values, arrays (empty + large), deep nesting, and heterogeneous lists - JMH-benchmarked - synthetic corpus and real Hypixel SkyBlock auction data exercised by
NbtBenchmarks - Three dependencies - Gson, Lombok, and
simplified-dev/utils- nothing else
| Requirement | Version | Notes |
|---|---|---|
| JDK | 21+ | Required |
| Gradle | 9.4+ | Wrapper included |
| Git | 2.x+ | For cloning the repository |
Add JitPack and the dependency to your build:
Gradle (Kotlin DSL)
repositories {
maven(url = "https://jitpack.io")
}
dependencies {
implementation("com.github.minecraft-library:nbt-factory:master-SNAPSHOT")
}Gradle (Groovy DSL)
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.minecraft-library:nbt-factory:master-SNAPSHOT'
}Maven
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupId>com.github.minecraft-library</groupId>
<artifactId>nbt-factory</artifactId>
<version>master-SNAPSHOT</version>
</dependency>To build from source:
git clone https://github.com/minecraft-library/nbt-factory.git
cd nbt-factory
./gradlew buildEvery format goes through NbtFactory. All methods are static - call them directly.
// Decode a base64-encoded gzipped NBT payload (e.g. a Hypixel item)
CompoundTag root = NbtFactory.fromBase64(base64String);
// Read typed values
String name = root.getString("id");
int count = root.getInt("Count");
// Mutate
root.put("Lore", new StringTag("Enchanted"));
// Re-encode to any format
byte[] bytes = NbtFactory.toByteArray(root); // gzipped
byte[] raw = NbtFactory.toByteArray(root, Compression.NONE);
String snbt = NbtFactory.toSnbt(root);
String json = NbtFactory.toJson(root);
String b64 = NbtFactory.toBase64(root);Stream-based I/O:
try (var in = new FileInputStream("level.dat")) {
CompoundTag level = NbtFactory.fromStream(in);
}Open the project root and let Gradle import. The jmh source set is registered as test sources via the idea block in build.gradle.kts, so NbtBenchmarks appears alongside the unit tests. Run configurations for JUnit tests are auto-generated.
To run a single test: right-click NbtRoundTripTest > Run.
┌─────────────────────────────────────────────────────────────┐
│ NbtFactory (public entry point) │
└───────┬─────────────────────────────────────────────────────┘
│
├── fromBase64 / fromByteArray / fromFile / fromStream / fromUrl
├── fromSnbt / fromJson
│
▼
┌────────────────────────┐ ┌─────────────────────────────┐
│ io/buffer/ │ │ io/stream/ │
│ NbtInputBuffer │ │ NbtInputStream │
│ NbtOutputBuffer │ │ NbtOutputStream │
│ (heap-backed codec) │ │ (DataInputStream wrapper) │
└──────────┬─────────────┘ └────────────┬────────────────┘
│ │
▼ ▼
┌──────────────────────────────────────────────┐
│ TagType (dispatch) │
│ each variant knows its NbtByteCodec │
└──────────┬───────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ tag/ │
│ Tag, TagType, ByteTag..DoubleTag, │
│ StringTag, EndTag, NumericalTag, │
│ ByteArrayTag/IntArrayTag/LongArrayTag, │
│ CompoundTag, ListTag │
│ └─ borrow/ (BorrowedXxxTag, Tape) │
└──────────────────────────────────────────────┘
Format wrappers:
io/snbt/ SnbtSerializer / SnbtDeserializer - Mojang's text format
io/json/ NbtJsonSerializer / Deserializer - JSON mirror of NBT
Compression is provided by dev.simplified.stream.Compression (gzip by default, passthrough available). Modified UTF-8 is handled in NbtModifiedUtf8.
Benchmarks live in src/jmh/java/lib/minecraft/nbt/benchmark/NbtBenchmarks.java. They run against two corpora:
- Synthetic - a hand-built compound with one of every tag type at realistic sizes. Always available.
- Auction - ~100k real SkyBlock auction-house item NBTs fetched from the public Hypixel API. Auction benchmarks are no-ops if the fixture is missing.
Generate the fixture (idempotent, no API key required):
./gradlew generateAuctionFixtureThis writes src/test/resources/nbt-bench-fixture/auctions.bin (roughly 40 MB). The file is gitignored so it never bloats the repository.
Run the benchmarks:
./gradlew jmhFilter to specific benchmarks:
./gradlew jmh -Pjmh.includes=".*readAuctionGzipped.*"nbt-factory/
├── build.gradle.kts
├── settings.gradle.kts
├── gradle/
│ └── libs.versions.toml
├── LICENSE.md
├── COPYRIGHT.md
├── CONTRIBUTING.md
├── CLAUDE.md
├── README.md
└── src/
├── main/java/lib/minecraft/nbt/
│ ├── NbtFactory.java # public entry point
│ ├── exception/ # NbtException, NbtMaxDepthException
│ ├── io/
│ │ ├── NbtInput.java # read dispatch
│ │ ├── NbtOutput.java # write dispatch
│ │ ├── util/ # NbtByteCodec, NbtModifiedUtf8, NbtKnownKeys, ByteList/IntList/LongList
│ │ ├── buffer/ # heap-backed codec
│ │ ├── stream/ # DataInputStream/DataOutputStream wrappers
│ │ ├── snbt/ # SnbtSerializer / SnbtDeserializer
│ │ ├── json/ # NbtJsonSerializer / NbtJsonDeserializer
│ │ └── tape/ # NbtInputTape (borrow-API parser)
│ └── tag/ # Tag, TagType, every concrete tag class
│ └── borrow/ # BorrowedXxxTag navigators + Tape
├── test/java/lib/minecraft/nbt/
│ ├── NbtRoundTripTest.java
│ └── AuctionFixtureGenerator.java
└── jmh/java/lib/minecraft/nbt/benchmark/
└── NbtBenchmarks.java
See CONTRIBUTING.md for development setup and the pull-request process.
This project is licensed under the Apache License 2.0 - see LICENSE.md for the full text.
See COPYRIGHT.md for third-party attribution notices, including information about the NBT specification's origin.