cartograph / minecraft-nbt
Read, write, and manipulate Minecraft's NBT (Named Binary Tag) format; both binary and SNBT.
Requires
- php: ^8.5
- ext-zlib: *
Requires (Dev)
- brianium/paratest: ^7.22
- friendsofphp/php-cs-fixer: ^3.95
- infection/infection: ^0.32
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^13
This package is not auto-updated.
Last update: 2026-05-08 02:34:57 UTC
README
Minecraft NBT
A pure-PHP library for reading, writing, and manipulating Minecraft's NBT (Named Binary Tag) format, in both binary (file and network) form and SNBT.
Features
- Binary NBT: read and write the file format (named root) and the network format (unnamed root, Minecraft 1.20.2+)
- Compression: auto-detects GZip and Zlib on read; choose any of GZip, Zlib, or none on write
- SNBT: parse and render stringified NBT, with optional pretty-printing and configurable quote style
- 1.21.5 SNBT extensions: typed-array prefixes (
[B;...],[I;...],[L;...]), signed/unsigned suffixes (42ub,100sl, ...), hex (0xFF) and binary (0b1010) literals, underscore digit separators, trailing commas - All 13 tag types: Byte, Short, Int, Long, Float, Double, ByteArray, String, List, Compound, IntArray, LongArray, plus End for empty lists
- Type-safe construction: element-type validation on List and array tags, range-checked numeric tags
- PHPStan level max: full generic annotations on
Tag<TValue>,CompoundTag,ListTag, and theNbtfacade
Requirements
- PHP 8.5 or newer
- ext-zlib (compiled in by default on most distributions)
Installation
Install via Composer:
composer require cartograph/minecraft-nbt
Quick start
Build a tag tree and write it to a file:
use Cartograph\NBT\Nbt; $tag = Nbt::compound([ 'name' => Nbt::string('Bananrama'), 'level' => Nbt::int(42), ]); Nbt::writeFile($tag, 'player.nbt');
That's a complete, runnable example, with no fixtures and no setup. The output is a GZip-compressed binary NBT file with a TAG_Compound root containing one string and one int child.
To read it back:
$tag = Nbt::readFile('player.nbt'); echo $tag->get('name')->value(); // "Bananrama" echo $tag->get('level')->value(); // 42
Concepts
NBT is a tree of typed tags. Every tree has a CompoundTag at its root,
which is an ordered map of named children. Children can be other compounds
(nesting), ListTags (homogeneous, ordered sequences of tags), or any of
the leaf types: Byte, Short, Int, Long, Float, Double,
String, ByteArray, IntArray, or LongArray.
The same tree can be serialised two ways:
- Binary NBT, the compact wire format used by Minecraft itself, with optional GZip or Zlib compression
- SNBT, a human-readable text representation, similar to JSON with
type suffixes (
42b,1.5f,[L;1L,2L,3L])
This library reads, writes, parses, and renders both.
Usage
Read a binary file
readFile auto-detects GZip and Zlib compression from the file's leading
bytes; uncompressed files work too.
use Cartograph\NBT\Nbt; $level = Nbt::readFile('level.dat'); echo $level->get('Data')->get('LevelName')->value();
Write a binary file
GZip is the default. Pass a different Compression to override.
use Cartograph\NBT\Binary\Compression; use Cartograph\NBT\Nbt; Nbt::writeFile($tag, 'data.nbt'); // GZip Nbt::writeFile($tag, 'data.zlib.nbt', '', Compression::Zlib); Nbt::writeFile($tag, 'data.raw.nbt', '', Compression::None);
The third argument is the root tag's name (most files use an empty string).
Parse SNBT
parseSnbt accepts the full SNBT grammar including 1.21.5 extensions:
typed-array prefixes, signed/unsigned suffixes, hex/binary literals,
underscore digit separators, and trailing commas.
use Cartograph\NBT\Nbt; $tag = Nbt::parseSnbt('{name: "Bananrama", level: 42b, scores: [1, 2, 3]}'); echo $tag->get('name')->value(); // "Bananrama" echo $tag->get('level')->value(); // 42 (ByteTag) echo $tag->get('scores')->get(1)->value(); // 2 (IntTag)
Render SNBT
Two modes via SnbtOptions: compact (default) and pretty.
use Cartograph\NBT\Nbt; use Cartograph\NBT\Snbt\SnbtOptions; echo Nbt::renderSnbt($tag); // {name:Bananrama,level:42b,scores:[1,2,3,],} echo Nbt::renderSnbt($tag, new SnbtOptions(prettyPrint: true)); // { // name:Bananrama, // level:42b, // scores:[ // 1, // 2, // 3, // ], // }
SnbtOptions also lets you force-quote keys (quoteKeys: true), pick a
preferred quote style (quoteStyle: QuoteStyle::Single), and choose the
indentation unit.
Network format (Minecraft 1.20.2+)
The network protocol uses an unnamed root compound. Nbt::readNetworkBinary
and Nbt::writeNetworkBinary handle it.
use Cartograph\NBT\Nbt; $bytes = Nbt::writeNetworkBinary($tag); $tag = Nbt::readNetworkBinary($bytes);
Class overview
All tag classes live in the Cartograph\NBT\Tags namespace.
| Class | Holds | Notes |
|---|---|---|
ByteTag |
int |
-128 to 127 |
ShortTag |
int |
-32 768 to 32 767 |
IntTag |
int |
signed 32-bit |
LongTag |
int |
signed 64-bit (full PHP int range) |
FloatTag |
float |
IEEE 754 single-precision |
DoubleTag |
float |
IEEE 754 double-precision |
StringTag |
string |
UTF-8, max 65 535 bytes |
ByteArrayTag |
int[] |
each element in ByteTag range |
IntArrayTag |
int[] |
each element in IntTag range |
LongArrayTag |
int[] |
(PHP int always fits) |
CompoundTag |
array<string, Tag<*>> |
ordered map of named children |
ListTag |
list<Tag<*>> |
homogeneous; element type declared at construction |
The Nbt facade has a factory method for each (Nbt::byte(),
Nbt::compound(), ...) that returns the corresponding tag instance.
Compatibility
This library targets the Java Edition NBT format. All 13 tag types (including TAG_End for empty lists) are supported.
- File format: fully supported, all Minecraft Java versions
- Network format: Minecraft Java 1.20.2 and newer (unnamed root compound)
- Compression: GZip, Zlib, and uncompressed
- SNBT: classic syntax plus the 1.21.5 grammar extensions
Bedrock Edition's NBT variant (little-endian, varint-prefixed) is not supported.
Contributing
Bug reports, feature requests, and pull requests are welcome at
github.com/cartographgg/minecraft-nbt.
See CONTRIBUTING.md for development setup and the
required checks (tests, static analysis, code style, and mutation
testing). Each check has a Composer script: composer test,
composer static, composer style, and composer mutation.
License
Released under the MIT License. © Cartograph contributors.
Maintained as part of Cartograph, a Minecraft server directory and monitoring platform. The library is self-contained and has no Cartograph-specific behaviour; use it anywhere you need to work with NBT data in PHP.
