# codeclysm/extract: A Minimal Go Archive Extractor with a Custom FS Hook

> This review covers codeclysm/extract, a small Go library for unzipping zip, tar.gz, and tar.bz2 archives, with a focus on its renamer and FS interfaces.

**codeclysm/extract** — A Go library to extract archives in zip, tar.gz or tar.bz2 formats

- Repository: https://github.com/codeclysm/extract
- Stars: 50 · Forks: 21
- Language: Go
- License: MIT
- Published: 2026-08-17 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/codeclysm-extract

## What extract Solves and Who It Serves

codeclysm/extract is a Go library that unpacks archives in three formats: zip, tar.gz, and tar.bz2. It targets developers who need to embed archive extraction into a larger application without pulling in a heavyweight tool. The README shows a simple call: open a file, pass it to extract.Bz2 with a destination path, and the archive is unpacked. That is the core value: a few lines of code to go from compressed bytes to files on disk. The intended user is a Go developer building a tool that accepts uploads, downloads, or bundles, and needs a straightforward extraction step. The library does not aim to be a general-purpose archiver; it only extracts, it does not create archives. For that narrow job, it offers a compact API surface with three format-specific functions and one auto-detecting function.

## The Mechanism: Format-Specific Functions and a Magic-Byte Detector

The library works by exposing three direct functions: Zip, Gz, and Bz2, each taking a context.Context, an io.Reader, a destination path, and a renamer function. The renamer is a func(string) string that can alter the destination path for every file before extraction. The README gives an example of shifting paths by splitting on filepath.Separator and dropping the first element, which effectively extracts a subfolder. If you do not know the archive type, the Archive function infers it from the first bytes of the reader. That inference is a practical convenience: it saves you from writing a switch on file extensions or magic numbers yourself. The context parameter is passed through, which suggests cancellation and deadlines are supported, though the README does not detail how deeply the context propagates into the extraction loop. The design keeps the API small: you either pick a format or let the library guess.

## Getting It Running: Commands and Configuration from the README

To use the library, you import it with the v4 module path: import "github.com/codeclysm/extract/v4". The README shows a minimal extraction: os.Open a file, then call extract.Bz2(context.TODO, file, "/path/where/to/extract", nil). The nil is the renamer, meaning no path rewriting. You can also read the archive into a byte slice and wrap it in a bytes.Buffer, which is useful when the archive arrives over a network or from an in-memory source. For path control, you define a renamer function and pass it as the fourth argument. There is no separate configuration struct or options object; the function signatures carry all parameters. The zero-value nil renamer is acceptable, so the library works without any setup beyond importing it. No build tags or environment variables are mentioned in the material.

## The FS Interface: A Genuine Extension Point with a Catch

For advanced control, extract defines an Extractor struct that holds an FS field. The FS interface has seven methods: Link, MkdirAll, OpenFile, Symlink, Remove, Stat, and Chmod. This interface abstracts the filesystem operations needed for extraction, allowing you to wrap os functions to chroot a path, scramble file contents, emit events per operation, or back the store in memory. That is a real extension point, and it is the most interesting part of the library. The catch is the OpenFile method signature: it returns *os.File. That return type ties any implementation to the os package, so an in-memory store cannot return an *os.File without a fake wrapper. The README acknowledges this by saying you could reimplement them for an in-memory store, but the signature makes that awkward. If you want a fully virtual filesystem, you would need to construct a temporary os.File, which defeats the purpose. This is a limitation worth noting if your use case is sandboxing or testing.

## Limitations and Wrong Tool Scenarios

The library only supports zip, tar.gz, and tar.bz2. No rar, no 7z, no plain tar without compression, and no xz. If your users upload rar files, this is not the tool. The README also does not mention any protection against path traversal attacks, such as archive entries containing "../". The renamer could be used to sanitize paths, but the default nil renamer passes paths through unchanged. That means a malicious archive could write outside the destination directory if the underlying os functions do not validate. The FS interface could be used to enforce a chroot, but that is on you. The library also hides the details of how it handles symlinks or hard links; the FS interface includes Link and Symlink, so it supports them, but the README does not describe the policy. If you need a hardened extractor with built-in traversal guards, you will have to add that logic yourself.

## A Real Alternative: Archive Files Differently

The main alternative in the Go ecosystem is the standard library's archive/zip and archive/tar packages, combined with compress/gzip and compress/bzip2. The difference is that the standard library gives you low-level control over each entry, but you must write the extraction loop yourself, including directory creation, file permissions, and symlink handling. extract wraps that loop into a single function call, saving boilerplate. The trade-off is that with the standard library you can handle any format that tar supports, such as xz if you bring in another package, and you can implement custom validation per entry. With extract, you get a fixed set of formats and a fixed extraction flow, but you gain the renamer and the FS hook. If you need full control over the extraction process, the standard library is a viable path. If you want a quick, opinionated helper, extract is the simpler choice.

## Maintenance and License Considerations

The project is licensed under MIT, which permits commercial use, modification, and redistribution with attribution. The latest release is v4.0.0, pushed on 2024-08-08, with prior releases in 2023 and 2022. The repository is not archived, but the push history shows a gap of over a year between v3.1.0 and v3.1.1, and then another gap before v4.0.0. That suggests maintenance is sporadic rather than continuous. The README and release notes do not mention any deprecations or upgrade guides for v4, so moving from v3 to v4 may require checking the changelog yourself. The module path includes /v4, which is a Go modules convention for major version bumps. For upgrade cost, the API appears stable across the README examples, but you should verify that the FS interface has not changed between versions. The license is permissive, but you should keep the copyright notice if you redistribute the library.

## Conclusion

Adopt codeclysm/extract if you need a tiny, dependency-light Go library for extracting the three most common archive formats and you value the ability to intercept every file operation through the FS interface. Skip it if you need support for rar, 7z, or xz, or if you expect active maintenance beyond the current v4.0.0 release. Before adopting, verify that the FS interface's use of *os.File fits your storage layer, since that return type ties you to the os package. Also check the current source for any unmerged fixes, as the last push was in August 2024.

## FAQ

### What does extract mean in files in codeclysm/extract?

It means unpacking an archive to a destination directory. The package handles zip, tar.gz and tar.bz2, and offers one function that infers the format from the first bytes of the file when you do not know which you have.

### What is the meaning of extract for the codeclysm Go library?

It is a Go library for extracting archives, imported as github.com/codeclysm/extract/v4 because the major version goes in the import path. The usual call takes a context, a reader, a destination path and an optional path renamer.

### How do I extract only a subfolder with codeclysm/extract?

Pass a renamer function as the fourth argument. The example splits the path on the platform separator, drops the first element and joins the rest, which strips the archive's top level directory before each file is written.

### Can codeclysm/extract write somewhere other than the real filesystem?

Yes. Build an Extractor with an FS field, where FS is your own type implementing Link, MkdirAll, OpenFile, Symlink, Remove, Stat and Chmod. The README suggests wrapping the operating system functions to chroot paths, scramble files, emit an event per operation, or back an in-memory store.

## Sources

- [Official README](https://github.com/codeclysm/extract#readme)
- [Project repository](https://github.com/codeclysm/extract)
- [Release notes](https://github.com/codeclysm/extract/releases)

---

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