Skip to content
This repository has been archived by the owner. It is now read-only.
Tiny, liberally-licensed NBT library. NBT is the datafile format used in Minecraft and Voxel.
Branch: master
Clone or download
This branch is 1 commit ahead, 8 commits behind TkTech:master.

Latest commit

Fetching latest commit…
Cannot retrieve the latest commit at this time.


Type Name Latest commit message Commit time
Failed to load latest commit information.


PyNBT is a tiny, liberally licenced (MIT) NBT library. It supports reading and writing big endian or little endian NBT files.

Using the Library

Using the library in your own programs is simple and is capable of reading, modifying, and saving NBT files.


NOTE: Beginning with version 1.1.0, names are optional for TAG_*'s that are added to a TAG_Compound, as they will be given the same name as their key. If you do specify a name, it will be used instead. This breaks compatibility with old code, as the position of the name and value parameter have now swapped.

from pynbt import NBTFile, TAG_Long, TAG_List, TAG_String

value = {
    'long_test': TAG_Long(104005),
    'list_test': TAG_List(TAG_String, [

nbt = NBTFile(value=value)
with open('out.nbt', 'wb') as io:


Reading is simple, and will accept any file-like object providing read(). Simply pretty-printing the file created from the example under writing:

from pynbt import NBTFile

with open('out.nbt', 'rb') as io:
  nbt = NBTFile(io)

This produces the output:

TAG_Compound(''): 2 entries
  TAG_Long('long_test'): 104005
  TAG_List('list_test'): 3 entries
    TAG_String(None): 'Timmy'
    TAG_String(None): 'Billy'
    TAG_String(None): 'Sally'

Every tag exposes a minimum of two fields, .name and .value. Every tag's value maps to a plain Python type, such as a dict() for TAG_Compound and a list() for TAG_List. Every tag also provides complete __repr__ methods for printing. This makes traversal very simple and familiar to existing Python developers.

with open('out.nbt', 'rb') as io:
  nbt = NBTFile(io)
  # Iterate over every TAG in the root compound as you would any other dict
  for name, tag in nbt.items():
      print(name, tag)

  # Print every tag in a list
  for tag in nbt['list_test']:


These changelogs are summaries only and not comprehensive. See the commit history between tags for full changes.


  • Added support for TAG_Long_Array


  • Removed pocket detection helpers and RegionFile, leaving PyNBT to only handle NBT.
  • Added a simple unicode test.


  • Internal cleanups in to ease some C work.
  • NBTFile.__init__() and's arguments have changed. For most cases changing compressed=True to NBTFIle.Compression.GZIP will suffice.
  • NBTFile.__init__() and no longer accept paths, instead accepting only file-like objects implementing read() and write(), respectively.
  • name must now be provided at construction or before saving of an NBTFile() (defaults to None instead of '').


  • TAG_List's values no longer need to be TAG_* objects. They will be converted when the tag is saved. This allows much easier lists of native types.


  • Internal code cleanup. Breaks compatibility with pocket loading and saving (to be reimplemented as helpers).
  • Slight speed improvements.
  • TAG_List can now be treated as a plain python list (.value points to self)


  • Breaks compatibility with older code, but allows much more convenient creation of TAG_Compound. name and value have in most cases swapped spots.
  • name is now the last argument of every TAG_*, and optional for children of a TAG_Compound. Instead, they'll be given the key they're assigned to as a name.
  • TAG_Compounds can now be treated like dictionaries for convienience. .value simply maps to itself.


  • Small bugfixes.
  • Adds support for TAG_Int_Array.


  • First release.
You can’t perform that action at this time.