# JLD2.jl: an HDF5-compatible file format written in pure Julia

> JLD2 is the Julia package for saving and loading data into files that follow the HDF5 format specification, with a two-call API, compiler generated serialization code, custom serialization procedures and upgrade hooks for types that change between versions.

**JuliaIO/JLD2.jl** — HDF5-compatible file format in pure Julia

- Repository: https://github.com/JuliaIO/JLD2.jl
- Website: http://juliaio.github.io/JLD2.jl/
- Stars: 641 · Forks: 93
- Language: Julia
- License: NOASSERTION
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/juliaio-jld2-jl

## A Julia save format that stays inside the HDF5 container

JLD2 is the package the Julia ecosystem uses to save and load data, and its central claim is interoperability rather than novelty. The files it writes adhere to the HDF5 format specification, which makes them compatible with HDF5 tooling and with H5 libraries in other languages, and JLD2 can also read HDF5 files it did not write. That property changes what a saved dataset is. Instead of a blob only your own code can decode, it is a container that an existing scientific stack already understands, which matters as soon as someone outside your team wants the data. The package is pure Julia, so there is no compiled library to ship alongside it, and the documentation site at JuliaIO.github.io/JLD2.jl/dev is where the API reference lives. The last push to the repository was on 2026-10-09.

## Two calls cover most of what you need

The API is small on purpose. The README gives the basic usage as a save call and a load call:
```julia
jldsave(filename; data)
load(filename, "data")
```
The save writes a named entry, here the keyword argument data, and the load retrieves that entry by name from the file. There is no separate handle object to manage and no session to keep alive, which means the everyday case in a Julia script reads as two lines. Around that core, JLD2 serializes complex nested structures out of the box, so a struct holding arrays, strings and other structs is stored without you writing a serializer per type. The practical consequence is that the interesting decisions in your code are about the shape of the data you store and how you name it, not about the mechanics of writing it.

## The compiler generates the serialization code

The speed claim in the documentation is explained by mechanism rather than by benchmark. JLD2 uses the Julia compiler to generate efficient code for serializing complex structures, so the work of walking and writing a nested object is specialised at compile time rather than interpreted dynamically. That is a different performance model from a runtime library that reflects over values, and it is why the package can hold its own on workloads with large arrays of composite types. The trade-off sits in the same design. Because the code is generated for your concrete types, the generated path is tied to the type definitions in play when it was compiled, and a type that changes shape between sessions is precisely the situation the package has to handle explicitly rather than implicitly.

## Custom serialization procedures and the upgrade mechanism

Two extension points carry the design weight. The first is custom serialization procedures: users may provide their own to control how data gets stored, which is the answer to types that contain handles, caches or objects you would rather not write to disk. The second is the upgrade mechanism. JLD2 provides upgrade mechanisms for data structures that need post-processing on load, for example when the Julia types have changed. That means a file written months ago, before you renamed a field or changed a struct, is not a dead end: the package has a documented path for running a transformation as the data is loaded. If you maintain long-lived datasets, this is the feature to read about first, because it is the difference between a format you can migrate and one that quietly breaks when a type changes.

## What the repository tree reveals about what gets tested

The tree tells you more about the project than a feature list would. There is a Project.toml, which is how Julia packages declare their identity and dependencies, an ext/ directory for package extensions, docs/ for the documentation sources, test/ for the test suite and benchmark/ for measurement work. Two names stand out. The root holds a script called filter-downgrade-tests.jl, and there is a filterpkgs/ directory beside it, which together suggest that reading data written by other or older package versions is exercised deliberately rather than incidentally. A codecov badge and an Aqua QA badge sit in the README, and the Aqua badge in particular points at a package-quality checking suite being run in CI. None of this is a performance claim; it is evidence about where the project's own attention goes.

## Licence, releases and the version line you will pin

The repository is listed under a custom licence that GitHub cannot classify, and the file to read is LICENSE.md. That classification is common for Julia packages with a licence text the service does not recognise, and it means you have to read the file rather than rely on a badge. The release history shows a steady 0.6 line: v0.6.7 on 2026-09-16, v0.6.6 on 2026-08-23 and v0.6.5 on 2026-07-07, with a last push on 2026-10-09 that came after the newest tag. For a package that sits inside most Julia environments indirectly, that cadence is the thing to watch, since a version bump in JLD2 can arrive through a dependency update rather than through a deliberate change on your side.

## Where JLD2 is the wrong choice

Two cases point away from this package. The first is a workload that will never leave Julia and never needs another language to read the file. In that case the HDF5 compatibility buys nothing, and the container adds a layer of structure you do not need, while the alternative of writing files through the HDF5 libraries directly, or through a Julia-only serialization, keeps the file format exactly as simple as the data. The second is a long-lived archive where types will keep changing. JLD2 does have the upgrade mechanism for that, but it is a mechanism you must design for: you decide which changes get a post-processing step and how old files are migrated, and a file written by a version of your code that predates the change still needs that path. If nobody owns the migration, the file format will outlive the plan for it, and the container that made the data portable will not save the metadata that made it loadable.

## Conclusion

JLD2 fits Julia teams that need to persist arrays and nested structures to disk and still want the resulting files readable from Python, R or C through ordinary HDF5 tooling, and that need a migration path when their own types change. It does not fit projects that want a plain Julia-only file format with no HDF5 compatibility, or that expect the same file to be readable by an older Julia version without running an upgrade step. Before adopting it, read the upgrade section of the documentation and plan how you will handle type changes, because that mechanism is the part of the design you will depend on later, and note that the licence file is a custom licence GitHub cannot classify.

## FAQ

### Is JLD2.jl compatible with HDF5?

Yes. JLD2 files adhere to the HDF5 format specification, so they work with HDF5 tooling and H5 libraries in other languages, and JLD2 can also read HDF5 files it did not create.

### How do I save and load data with JLD2.jl?

The basic usage is jldsave(filename; data) to write a named entry and load(filename, "data") to read it back. Complex nested structures are serialized out of the box.

### Can I control how my types are stored in JLD2.jl?

Yes. Users may provide custom serialization procedures to control how data gets stored, and JLD2 also offers upgrade mechanisms for structures that need post-processing on load, for example when the Julia types have changed.

### What is the licence and release cadence of JLD2.jl?

The repository is listed under a custom licence that GitHub cannot classify, with the text in LICENSE.md. Releases in the current line are v0.6.7 from 2026-09-16, v0.6.6 from 2026-08-23 and v0.6.5 from 2026-07-07, and the last push was on 2026-10-09.

## Sources

- [Issues](https://github.com/JuliaIO/JLD2.jl/issues)
- [JuliaIO/JLD2.jl on GitHub](https://github.com/JuliaIO/JLD2.jl)
- [Project website](http://juliaio.github.io/JLD2.jl/)
- [README](https://github.com/JuliaIO/JLD2.jl/blob/master/README.md)
- [Releases](https://github.com/JuliaIO/JLD2.jl/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/juliaio-jld2-jl
