# Hardwood - modern lightweight Java reader and writer for Parquet file format

> Source: <https://hardwood.dev/1.1.0.Beta3/>
> Published: 2026-10-24 03:47:31+00:00

# Hardwood[¶](#hardwood)

*A modern lightweight Java reader and writer for the [Apache Parquet](https://parquet.apache.org/) file format.
Available as a Java library and a command-line tool.*

What's new

- **2026-10-12** —[Hardwood 1.1.0.Beta2](https://www.morling.dev/blog/row-group-control-faster-s3-reads-footer-caching-hardwood-1-1-0-beta2/) : row group control in the writer, faster S3 reads, footer caching
- **2026-08-31** —[Hardwood 1.1.0.Beta1](https://www.morling.dev/blog/parquet-file-write-support-bloom-filters-improved-performance-hardwood-1-1-0-beta1/) : Parquet write support, Bloom filter pruning, faster reads
- **2026-06-25** —[Hardwood 1.0](https://www.morling.dev/blog/hardwood-1-0-fast-lightweight-apache-parquet-reader-for-the-jvm/) : the release announcement and the story behind the project
- **2026-06-01** —[Confluent Developer Podcast, Ep. 31](https://www.youtube.com/watch?v=9Ov0Cn_ArHE) : Gunnar Morling on building a new Parquet parser with AI

## Why Hardwood[¶](#why-hardwood)

Hardwood gives applications fast and efficient support for reading and writing Parquet, without pulling in Hadoop, Avro, or the wider [parquet-java](https://github.com/apache/parquet-java) dependency tree.
It is built to be:

- **Light-weight** : Zero transitive dependencies beyond optional compression libraries (Snappy, ZSTD, LZ4, Brotli)
- **Fast** : Hardwood aims to be the fastest Parquet reader and writer for the JVM ([1.0 read benchmarks](https://www.morling.dev/blog/hardwood-1-0-fast-lightweight-apache-parquet-reader-for-the-jvm/#_performance) )
- **Complete** : Read and write support for flat and nested schemas, every logical type, every primitive type in current use, and the encodings and codecs in current use, with new format additions tracked as they land
- **Scalable** : Hardwood is multi-threaded at the core, pages are decoded in parallel, with cross-file prefetching for multi-file reads
- **Embeddable** : The Hardwood library can be used in GraalVM native binaries; a WASM build of`dive` runs in the browser as a[preview](https://hardwood.dev/experiments/dive-web/)
- **Agent-friendly** : Hardwood's CLI comes with a skill which lets your agents inspect and analyse Parquet files
- **Compatible** : A[drop-in shim module](how-to/compat/) facilitates migration from`parquet-java` , with documented divergences where Hardwood applies stricter semantics (e.g. SQL three-valued`notEq` )

The [CLI](reference/cli/) inspects and analyses Parquet files and includes an interactive TUI for exploring a file's schema, row groups, pages, and data.

## Quick Example[¶](#quick-example)

Reading a file with the [row-based API](how-to/row-reader/):

``` python
import dev.hardwood.InputFile;
import dev.hardwood.reader.ParquetFileReader;
import dev.hardwood.reader.RowReader;

try (ParquetFileReader fileReader = ParquetFileReader.open(InputFile.of(path));
    RowReader rowReader = fileReader.rowReader()) {

    while (rowReader.hasNext()) {
        rowReader.next();

        long id = rowReader.getLong("id");
        String name = rowReader.getString("name");
        LocalDate birthDate = rowReader.getDate("birth_date");
        Instant createdAt = rowReader.getTimestamp("created_at");
    }
}
```

[Writing a file](how-to/write-row-by-row/) row by row:

``` python
import dev.hardwood.OutputFile;
import dev.hardwood.writer.ParquetFileWriter;
import dev.hardwood.writer.RowWriter;

try (ParquetFileWriter writer = ParquetFileWriter.create(OutputFile.of(path), schema)) {
    RowWriter rows = writer.rowWriter();

    for (Person person : people) {
        rows.writeRow(row -> row
                .setLong("id", person.id())
                .setString("name", person.name())
                .setDate("birth_date", person.birthDate()));
    }
}
```

[Set up Hardwood in your project](getting-started/), then read [your first file end-to-end](tutorial/first-read/).
Alternatively, [install the Hardwood CLI](getting-started/#command-line-tool) for working with Parquet files on the command line.

## Status and Limitations[¶](#status-and-limitations)

The read path is stable and suitable for production use; `ColumnReader`, with its `Validity` and `LayerKind` types, is annotated `@Experimental`, so its shape may still change.
The write path ships both APIs described under [Choosing a Writer](how-to/#choosing-a-writer); the row-oriented `RowWriter` and its builders, the `ColumnBatch` setters for nested and nullable columns, and the in-memory destination `InMemoryOutputFile` are annotated `@Experimental`, so their shape may still change.

Writing targets local files through `OutputFile.of(Path)` and the heap through `OutputFile.inMemory()`.
Reads have no file-size ceiling, but a column chunk read without an OffsetIndex is capped at 2 GB, and some backends carry their own limits; see [Limits](reference/reader/#limits).

## Roadmap[¶](#roadmap)

Forward-looking items, none committed to a specific release.

- **Finalize `ColumnReader` API** — stabilize the API for columnar access and move it out of "Experimental" state. ([#522](https://github.com/hardwood-hq/hardwood/issues/522) )
- **Writer extensions** — object-store output and parallel column encoding, on top of the write path described in[The Write Model](concepts/write-model/) . ([#9](https://github.com/hardwood-hq/hardwood/issues/9) )
- **Parquet Modular Encryption** — read files encrypted under the Parquet[Modular Encryption spec](https://github.com/apache/parquet-format/blob/master/Encryption.md) : encrypted footer, per-column keys, AES-GCM and AES-GCM-CTR. ([#128](https://github.com/hardwood-hq/hardwood/issues/128) )
- **Apache Arrow interop** —`ColumnReader` output as Arrow`FieldVector` /`VectorSchemaRoot` for zero-copy handoff to DuckDB, DataFusion, Pandas-via-JNI, and other Arrow-native consumers. ([#153](https://github.com/hardwood-hq/hardwood/issues/153) )

## Getting help[¶](#getting-help)

Ask questions on [GitHub Discussions](https://github.com/hardwood-hq/hardwood/discussions) and file bugs on the [issue tracker](https://github.com/hardwood-hq/hardwood/issues); see [Contributing](contributing/).

## Articles, talks & podcasts[¶](#articles-talks-podcasts)

- [Hardwood: A New Parser for Apache Parquet](https://www.morling.dev/blog/hardwood-new-parser-for-apache-parquet/) (original project announcement)
- [Building a New Parquet Engine with AI](https://www.youtube.com/watch?v=9Ov0Cn_ArHE) (Confluent Developer podcast)
- [Hardwood Promises High-Speed JVM Apache Parquet Processing with Zero Mandatory Dependencies](https://www.infoq.com/news/2026/07/hardwood-java-parquet/) (InfoQ article)
- [Hardwood: Building a Parquet Parser From Scratch (With a Little Help From AI)](https://speakerdeck.com/gunnarmorling/hardwood-building-a-parquet-parser-from-scratch-with-a-little-help-from-ai) (conference talk)
- [GitHub Open Source Friday with Gunnar Morling](https://www.youtube.com/watch?v=teqFSSQEtCw) (GitHub podcast)
- [Chasing Efficient Java Development: From 1BRC to Developing Hardwood AI Natively](https://www.infoq.com/podcasts/chasing-efficient-java-development/) (InfoQ podcast)
