Library / SDK
osiegmar/FastCSV avatar
osiegmar/FastCSV

FastCSV: a small RFC 4180 CSV library for Java with a builder API

Fast, lightweight, and RFC 4180 compliant CSV library for Java. Zero dependencies, ~90 KiB. Trusted by Apache NiFi, JUnit, and Neo4j.

693 stars103 forksJavaMIT

At a glance

What is it?
FastCSV is a Java CSV parser and writer with zero runtime dependencies, roughly 90 KiB, and a builder-based API where readers and writers are typed rather than generic, used in production by Apache NiFi, JUnit and Neo4j. It suits a Java service that has to move CSV in and out of a pipeline without pulling in a dependency tree, and the project leans on mutation testing, fuzzing and a stack of static analysers to make the RFC 4180 edge cases behave.
Who is it for?
Adopt FastCSV if you need CSV handling in a Java service and want something small, typed and free of a dependency tree, since the library is RFC 4180 compliant, fuzz-tested and used in production by projects like Apache NiFi, JUnit and Neo4j.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 26 days ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Small on purpose, and the API shape that follows from it

FastCSV describes itself as fast, lightweight and easy to use, the production-proven CSV library for Java, with the summary line that it is the most-starred CSV library for Java and trusted by leading open source projects such as Apache NiFi, JUnit and Neo4j.

The project description gives the numbers that define it: zero dependencies and about 90 KiB. That is the whole selling point for a lot of Java teams. A CSV parser is one of those things that ends up on the classpath of everything, and a library with no runtime dependencies and a jar the size of a screenshot is a library you can add to a shared module without an argument.

The API explains how it stays small. Both the writer and the reader are built with a builder, and the reader is typed on the record type you want:

java
try (CsvWriter csv = CsvWriter.builder().build(Path.of("output.csv"))) {
    csv
        .writeRecord("header 1", "header 2")
        .writeRecord("value 1", "value 2");
}
java
try (CsvReader<CsvRecord> csv = CsvReader.builder().ofCsvRecord(Path.of("input.csv"))) {
    csv.forEach(IO::println);
}

The reader is `CsvReader<CsvRecord>`, so the record type is part of the type rather than something you cast to later, and the writer returns itself from `writeRecord` so records chain. The example reading is `csv.forEach(IO::println)`, which shows the reader is an iterable-like thing rather than a pull parser with a cursor, so a whole file is a stream of records.

Both examples use try-with-resources, which is not incidental. A writer holds a file handle, and the library is designed so that the scope of the handle is the scope of the block.

The project is MIT licensed, the last push was on 2026-09-27, and the recent releases are v4.4.0 from 2026-07-28, v4.3.1 from 2026-06-29 and v4.3.0 from 2026-05-19.

RFC 4180 compliance as the specification, not a guideline

The feature list puts RFC 4180 compliance on its own line and describes it as handling edge cases correctly, and that framing matters more than it might look.

RFC 4180 is the specification for comma separated values, and it is stricter than most people assume. It defines the record and field structure, the use of CRLF as the line break, the quoting rules for fields containing the delimiter, quotes or line breaks, and the way a doubled quote inside a quoted field is escaped. A parser that does not follow those rules will not round-trip, and a CSV file written by such a parser will be misread by something else.

For a library whose whole job is interoperable text, that compliance is the requirement rather than a feature, and the README's list is careful to say it handles the edge cases correctly rather than merely that it is compliant. The list of edge cases in practice is the boring list that bites in production: embedded delimiters, embedded newlines inside a quoted field, doubled quotes, an empty final line, a file with no trailing newline, and a quoted field that is entirely whitespace.

The specification is also what makes the library's behaviour predictable across the ecosystem. A file written by FastCSV is a file that Excel, Python's csv module, pandas and every other RFC 4180 implementation will read the same way, which is the property you want when a CSV is going to be handed to a partner.

The performance claim sits alongside the compliance one, and the README is careful about where the numbers come from. The performance section points at a benchmark image and says the numbers are based on the Java CSV library benchmark suite in a separate repository, osiegmar/JavaCsvBenchmarkSuite, which is the author maintaining a comparison of the available Java CSV libraries. So the comparison is against a suite the library's own author controls, which is worth knowing when you read the chart.

Mutation testing, fuzzing and a stack of static analysers

The quality section of the feature list is unusually specific, and it is the part of the project that best explains why a small library can be trusted with edge cases.

First, high test coverage including mutation testing for reliability. Mutation testing is the technique where the tests are run against deliberately broken versions of the code, so a test that still passes when the code is mutated is a test that was not asserting anything. For a parser whose failure mode is a subtly wrong result rather than an exception, that is a better fit than a coverage number, which only tells you a line was executed.

Second, security by fuzzing. The project is fuzz-tested via OSS-Fuzz, which is the continuous fuzzing service run for open source projects, and the README carries an OSS-Fuzz badge with a link to the open Chromium bug tracker issues for the project. There is also an OpenSSF best practices badge.

Third, the static analysis. The README names SpotBugs, PMD, Error Prone, NullAway and Checkstyle as the tools used to ensure code quality, and makes a specific behavioural claim: it never returns null unexpectedly. That is a real API guarantee for a library that people call from optional paths, and NullAway is the tool that enforces it, since it is a nullness checker for NullAway-aware code.

The repository layout backs all of this up. There is a `config/` directory that almost certainly holds the Checkstyle, PMD and Error Prone configuration, a `buildSrc/` directory for custom Gradle build logic, a `docs/` directory that is the source of the fastcsv.org site, and an `example/` module with its own build file and sources. The build is a Kotlin DSL Gradle project, with `build.gradle.kts`, `settings.gradle.kts`, `gradle.properties` and the wrapper scripts.

Two more files are worth noting. There is a `THIRD-PARTY-LICENSES.md`, which matters for a library that claims zero runtime dependencies, since the build tooling and the test dependencies still have licences. And there is a `KEYS` file, which is the convention for the keys used to sign release artefacts, alongside a `SECURITY.md` for responsible disclosure and a `CHANGELOG.md`.

The release process is automated too, with `release-please-config.json` and a `.release-please-manifest.json`, which is the standard tool for cutting versions and changelog entries from conventional commits.

Java 17, Android 34, GraalVM Native Image and OSGi

The last line of the feature list is the compatibility one, and it is more informative than it looks: Java 17+, Android 34+ compatible, including GraalVM Native Image and OSGi.

Java 17 as a floor is a deliberate choice rather than a legacy constraint. It puts the library on the LTS releases that are still supported and lets the code use the language features that came with it, at the cost of excluding anyone on Java 8 or 11. For a library with no dependencies, that is a reasonable trade, since adding a second artifact for older runtimes would multiply the testing matrix.

Android 34 means the same code runs on a recent Android device, which matters because CSV handling shows up in mobile apps reading exported data, and the project is a single artifact rather than a desktop library with a server variant.

GraalVM Native Image is the more interesting entry, because a native image build is a hard constraint on a library. It means every class on the code path has to be reachable at build time and every reflective use has to be registered, and a library that reaches into the JDK's internals or uses dynamic proxies in its parser will fail there. Supporting it means the implementation stays with what the native image generator can see, which is a discipline that keeps a library honest about how it uses reflection.

OSGi is the other unusual one. OSGi is the module system for Java, where bundles declare their imports and exports and the container wires them at runtime, and its strictness about package visibility means a library that works under OSGi is unlikely to be relying on accidental access to internals of its own dependencies. For a zero-dependency library, OSGi support is mostly about the bundle metadata being right, but it is a signal that the project is used in enterprise environments where module hygiene is not optional.

The javadoc badge points at javadoc.io for the `de.siegmar.fastcsv` artifact, which also tells you the Maven coordinates, and the Maven Central badge confirms the group is `de.siegmar` and the artifact is `fastcsv`.

Against a hand-rolled parser and against a full CSV-to-object library

The comparison worth making is with the two alternatives most Java projects actually choose.

The first is a hand-rolled parser, usually a split on a comma with a strip of quotes. That is the thing FastCSV exists to replace, and the failure modes are worth naming because they are the reason a careful library is worth its jar. Splitting on a comma breaks on a quoted field containing a comma, which is legal CSV and common in real exports. Handling quotes with a regular expression breaks on a field containing an escaped quote. Neither handles a newline inside a quoted field. And a hand-rolled parser has to be written again in every project, so the bug is written again too.

The second alternative is a CSV-to-object-mapping library, the kind that turns a row into a Java bean using annotations or a naming convention. Those are convenient when your CSV has a stable header row and a fixed record shape, and they are the wrong tool when the record shape varies, when the header is not the first line, when the number of columns varies per row, or when you want to stream and transform. They also pull in a reflection-based mapping layer, which is at odds with the GraalVM Native Image support the project advertises.

FastCSV sits deliberately between the two. It is a parser and writer with no object mapping, and it is small enough and typed enough to compose with whatever mapping you prefer. The `CsvReader<CsvRecord>` type parameter is the seam: you ask for `CsvRecord` when you want the raw fields and something else when you have your own representation.

The comparison with the other popular Java CSV libraries is where the benchmark suite comes in, and the honest reading of that chart is that speed differences between a well-written parser and a poorly written one are usually small compared with the cost of the surrounding I/O, unless you are parsing very large files in a tight loop. The RFC 4180 compliance, the absence of dependencies and the fuzzing are the more durable reasons to pick this one.

For a team whose main concern is a small jar and no surprises, that is a defensible choice over a larger library that also pulls in a mapping framework whether you use it or not.

Editorial conclusion

Adopt FastCSV if you need CSV handling in a Java service and want something small, typed and free of a dependency tree, since the library is RFC 4180 compliant, fuzz-tested and used in production by projects like Apache NiFi, JUnit and Neo4j. Do not adopt it if your CSV is not really CSV, because the library is built around the RFC 4180 model of records, fields and quoting rather than around a looser format, and check first that you are on Java 17 or newer, since that is the stated baseline and it also covers Android 34 and GraalVM Native Image.

Frequently asked questions

What is FastCSV?

It is a Java CSV parser and writer, MIT licensed, with zero runtime dependencies and a footprint of about 90 KiB. It is RFC 4180 compliant, and the project says it is trusted by Apache NiFi, JUnit and Neo4j.

How do I write and read CSV with FastCSV?

Build a writer with `CsvWriter.builder().build(Path.of("output.csv"))` and chain `writeRecord` calls, or build a reader with `CsvReader.builder().ofCsvRecord(Path.of("input.csv"))` and iterate it, for example with `csv.forEach(IO::println)`. Both are used inside try-with-resources.

What Java version does FastCSV require?

Java 17 or newer, and Android 34 or newer. The library also supports GraalVM Native Image and OSGi, which is why the implementation avoids reflective tricks that would break a native image build.

How is FastCSV tested for correctness?

The project reports high test coverage including mutation testing, and it is fuzz-tested via OSS-Fuzz following OpenSSF best practices. Static analysis uses SpotBugs, PMD, Error Prone, NullAway and Checkstyle, with the guarantee that it never returns null unexpectedly.

Where are the FastCSV performance numbers from?

The README states the benchmark is based on the Java CSV library benchmark suite maintained in a separate repository, osiegmar/JavaCsvBenchmarkSuite, which the FastCSV author also maintains. The chart is in the docs directory of the project.

Is FastCSV still being maintained?

The repository is not archived and the last push was on 2026-09-27. Recent releases are v4.4.0 from 2026-07-28, v4.3.1 from 2026-06-29 and v4.3.0 from 2026-05-19, with versions and changelog cut automatically by release-please.

Official sources

  1. License: MIT
  2. osiegmar/FastCSV on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/osiegmar-fastcsv.svg)](https://hysenlabs.com/projects/osiegmar-fastcsv)

Was this useful?