# HummusJS: fast native PDF handling for Node, unmaintained since 2019

> HummusJS is a Node module for creating, modifying and parsing PDF files and streams, with a native core and prebuilt binaries for each platform. The first thing in its README is an end of support notice from 2019 and a pointer to MuhammaraJS, a maintained drop-in replacement, so the interesting question is when to keep using it and when to move.

**galkahana/HummusJS** — Node.js module for high performance creation, modification and parsing of PDF files and streams

- Repository: https://github.com/galkahana/HummusJS
- Website: http://www.pdfhummus.com
- Stars: 1,178 · Forks: 168
- Language: C
- License: NOASSERTION
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/galkahana-hummusjs

## A C engine with a JavaScript face

HummusJS is a Node.js module for high performance creation, modification and parsing of PDF files and streams, and the README calls it a fast NodeJS module for creating, parsing and manipulating PDF files and streams. The project site is pdfhummus.com, and the documentation is in the project wiki.

The architecture is the interesting part. The primary language in the repository is C, and the JavaScript files at the top level are wrappers, not the implementation. hummus.js is the main entry point, binding.gyp is the native build description, and hummus.d.ts carries the TypeScript definitions for the whole API. The src/ directory holds the native code, and the tests/ directory holds the JavaScript test suite.

The point of a native module here is speed on operations that are inherently expensive in a managed runtime. PDF work involves compression, font handling, stream encoding and object graph manipulation, and doing that in C is what makes the module worth its build complexity rather than another pure JavaScript library.

The author is Gal Kahana, and there is a related project for people who want the engine in C++ rather than in Node, PDF-Writer.

One detail in the metadata is worth knowing before you read further. The package on npm is named hummus, not hummusjs, at version 1.0.118, and it is published from the standard npm registry.

## The end of support notice comes before the welcome

The README leads with an announcement rather than with documentation, and that is the single most important thing about this project.

The update is dated 9/11/2019 and titled Ending Support. The author says that after six years he decided to finish supporting HummusJS, and that you may still use the code as is with the provided licence, but that he will not be providing answers, solutions or responses.

For existing users that is a precise and reasonable arrangement. The code stays, the licence stays, and nobody is on the hook for support. For new users, the README points elsewhere. If you want to continue using HummusJS and are looking for a maintained version, you can move to MuhammaraJS, which the author describes as a drop-in replacement for HummusJS, and thanks Julian Hille for maintaining it.

That pointer is the answer to most questions about this repository, and it is worth being precise about what a drop-in replacement means in practice. It means the API surface is intended to match, so the migration is a change of dependency name and import paths rather than a rewrite. It does not mean the two are identical in every corner, and for a library that manipulates binary PDF structures the corners are where the differences hide.

The repository is not archived and the last push was on 2026-10-04, so the tree is still being touched. The public record of releases is empty, since the repository has no GitHub releases, and the npm version 1.0.118 is the artefact people actually consume.

## Streams are the API, and the wrappers are the documentation

The files at the top of the repository are a map of the API, and they show that the module is organised around streams rather than around files.

There are five of them. PDFRStreamForFile and PDFRStreamForBuffer read a PDF from a file on disk or from a buffer in memory. PDFWStreamForFile and PDFWStreamForBuffer write one to a file or to a buffer. And PDFStreamForResponse is the one that matters for a server, because it writes a PDF out over an HTTP response rather than into a file.

That last wrapper is the reason the samples directory contains PDFServer.js, and why the aws-sdk appears among the dev dependencies. A service that generates a PDF for a client does not want to buffer the whole document in memory and then write it, and a stream that writes into the response removes that step.

The read side exists for a reason beyond reading a document back. A PDF produced by another system often has to be inspected, and inspecting means parsing the object graph and the streams rather than treating the file as an opaque blob. The module is described as a creation, modification and parsing tool, and the parsing half is what the read streams are for.

The combination of a native core with a small number of stream wrappers is the design that made this module popular, and it is also the design that a drop-in replacement can reproduce, which is presumably why the successor exists.

## Prebuilt binaries first, build from source as the fallback

Installing a native module usually means a compiler on every developer machine and a toolchain on every build server. HummusJS avoids most of that with the standard node-pre-gyp pattern.

The install script in package.json runs node-pre-gyp install with a fallback to build, and the EXTRA_NODE_PRE_GYP_FLAGS variable is passed through so a user can add flags. The binary configuration names the module hummus, puts the artefact under a module_path of ./binding, and points the remote path at a template with the version and toolset substituted, hosted on hummus.s3-us-west-2.amazonaws.com. The package name template is {node_abi}-{platform}-{arch}-{libc}.tar.gz, and that template is the whole compatibility story in one line: the prebuilt archive is chosen by Node ABI, operating system, architecture and C library.

```bash
node-pre-gyp install --fallback-to-build $EXTRA_NODE_PRE_GYP_FLAGS
```

The practical consequence is that a supported platform gets a binary and no compilation, and anything else falls back to building the sources in src/ with binding.gyp, which needs a C++ toolchain and takes noticeably longer. On a platform where the fallback triggers and the build has not been exercised in years, that is where friction appears.

The files array in package.json lists what actually ships: the src directory, hummus.js, binding.gyp and the five stream wrappers, which is a useful indication of the intended public surface.

## TypeScript definitions, TAP output and a sample server

The developer experience details are in the metadata rather than in the README, which is typical for a project whose documentation lives in a wiki.

There is a hummus.d.ts file in the repository, so the module is typed for TypeScript users. The test script runs mocha with the TAP reporter over the tests directory with a 15 second timeout.

```bash
mocha -R tap ./tests/*.js --timeout 15000
```

The TAP reporter choice is a small signal about intent, because TAP is the format continuous integration systems parse, which suggests the tests were set up to run in a pipeline rather than only on a laptop.

The dev dependencies tell the rest of the story. Mocha 12 and Chai 3 are the test stack, and the aws-sdk is there for the sample. The sample in samples/ is PDFServer.js, which fits the module's strongest use case: generating a PDF and streaming it to a caller.

The wiki is the reference for the API. The README itself is short by design, and the project site carries the marketing and the blog-like material. For a library that has been around long enough to have a successor, the wiki is the thing to read when you need a specific call, and the migration notes of the successor are the thing to read when you are deciding whether to stay.

## Licence, versioning and the practical decision

The licence needs a note, because the two sources disagree. The package metadata in package.json declares the licence as Apache-2.0, while the repository metadata classifies the project under a custom licence that GitHub cannot categorise and points at the LICENSE file. When a package manifest and a licence file disagree, the licence file is the document that governs the distribution, so the safe reading is to open LICENSE before shipping anything.

The author's own wording in the README is that you may still use the code as is, with the provided licence, which points at the same file.

The version number tells you where the project stopped. The npm package is at 1.0.118, and the support announcement is from 2019.

So the decision is fairly simple. If a project you are working on already uses HummusJS, the code is still there, the licence still applies and the module still does its job, and the honest risk is not that it breaks tomorrow but that a new Node release ships an ABI the prebuilt binaries do not cover and the fallback build fails on a toolchain you have not maintained.

If you are starting something new, the successor is the answer. MuhammaraJS is a drop-in replacement, it is maintained, and the migration is a matter of changing what you import. The only reason to pick the original is if you are pinned to it by something you cannot change, and in that case the important thing is to know that you are on your own.

## Conclusion

HummusJS fits a project that already depends on it, that runs on a platform with a prebuilt binary for its Node ABI, and that needs the PDF stream abstraction it offers rather than a document model. It does not fit a new project, because the author ended support in 2019 and the recommended path is MuhammaraJS, a drop-in replacement that is still maintained. Verify three things before you build anything new on it: that the node-pre-gyp binary host still serves a build for your Node ABI and platform, since the prebuilt archives are named by ABI, platform, architecture and libc, that the module builds from source on your machine if it has to fall back, which needs a C++ toolchain and the sources under src/, and what the LICENSE file actually grants, because the package metadata declares Apache-2.0 while the repository is classified under a custom licence.

## FAQ

### Is HummusJS still maintained?

No. The README leads with an update dated 9/11/2019 ending support, in which the author says that after six years he decided to stop supporting HummusJS, that you may still use the code as is with the provided licence, and that he will not be providing answers or solutions. The repository is not archived and the last push was on 2026-10-04.

### What is the maintained alternative to HummusJS?

MuhammaraJS, at github.com/julianhille/MuhammaraJS, which the author describes as a drop-in replacement for HummusJS and credits Julian Hille for maintaining. The recommendation to move to it is the author's own instruction in the README.

### How does the HummusJS native module get installed?

The install script runs node-pre-gyp install --fallback-to-build $EXTRA_NODE_PRE_GYP_FLAGS, which downloads a prebuilt binary from the configured host, hummus.s3-us-west-2.amazonaws.com, with the archive named {node_abi}-{platform}-{arch}-{libc}.tar.gz, and falls back to compiling the sources in src/ through binding.gyp when no binary matches.

### What licence does HummusJS use?

The package metadata in package.json declares Apache-2.0, but the repository is classified under a custom licence that GitHub cannot categorise and points at a LICENSE file, and the README refers to the provided licence. Read the LICENSE file before redistributing, since the manifest and the repository classification disagree.

### How do I run the HummusJS tests?

The test script is mocha -R tap ./tests/*.js --timeout 15000, run against the tests directory. The TAP reporter means the output is the format continuous integration systems parse, and the sample in samples/ is PDFServer.js, which shows the module writing a PDF out over an HTTP response.

## Sources

- [galkahana/HummusJS on GitHub](https://github.com/galkahana/HummusJS)
- [Issues](https://github.com/galkahana/HummusJS/issues)
- [Project website](http://www.pdfhummus.com)
- [README](https://github.com/galkahana/HummusJS/blob/main/README.md)

---

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