CLI tool
jbarrow/commonforms avatar
jbarrow/commonforms

CommonForms turns a flat PDF into a fillable form, and the model choice is the accuracy knob

CommonForms — open models to auto-detect PDF form fields

1,300 stars161 forksPythonLicense varies

At a glance

What is it?
A Python package and CLI that detect form fields in a PDF using the FFDNet models from a published dataset paper, then write an AcroForm output. The detector runs on the CPU by default, and the flags for model, confidence and image size are where the real tuning happens.
Who is it for?
Adopt CommonForms if you have a pile of flat PDFs and need fillable versions of them, and you are willing to tune a confidence threshold and check the output. Do not adopt it expecting every field to be detected correctly on the first run, because a detector at a 0.3 confidence threshold will both miss faint fields and invent others, and the tool has no validation step.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 130 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

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

Editorial analysis

Three artefacts in one repository

The repository holds three separate things, and the README lists them explicitly.

First, the pip-installable `commonforms` package, which has a CLI and an API for converting PDFs into fillable forms. Second, the FFDNet-S and FFDNet-L models from the paper CommonForms: A Large, Diverse Dataset for Form Field Detection, published on arXiv as 2509.16506. Third, the preprocessing code for the CommonForms dataset, which is hosted on Hugging Face.

That last point matters more than it looks. The dataset is the contribution, and the tool is a way of using it. The paper is the citation target, with a BibTeX entry given in the README, and the models are hosted on Hugging Face under separate names, FFDNet-S and FFDNet-L.

The dataset code is in a `dataset` folder, and the README marks it with a construction sign emoji, which reads as a work in progress rather than a supported path. The package itself lives in a `commonforms/` directory, with `tests/`, `assets/`, a `pyproject.toml` and a pre-commit configuration at the root.

There is also a hosted model service at detect.semanticdocs.org, linked in the README header next to the paper and the dataset. That is a useful thing to know for evaluation, because you can try detection on a document before deciding whether to run the models yourself.

The project version in the metadata is 0.2.1, requires Python 3.10 or newer, and the licence field is reported as unknown by the repository metadata, which is one of the details to settle before you adopt it.

Installing into an isolated environment is the recommended path

The installation section leads with a warning rather than a command, and the warning is about the dependency footprint.

The README calls CommonForms a CLI tool with a sizable dependency footprint, listing `transformers`, `torch`, `rfdetr`, `ultralytics` and friends, and says the cleanest install is an isolated one that creates a dedicated environment and exposes just the `commonforms` command.

sh
uv tool install commonforms
# or
pipx install commonforms

If you want to use it as a library inside an existing project, you can install with `uv` or `pip`.

sh
uv pip install commonforms
# or
pip install commonforms

The warning that follows the library install path is specific and worth heeding. A plain `pip install` or `uv pip install` installs into your active environment, and because the dependency set is large and pins recent versions, this can upgrade packages like `numpy`, `pillow` and `transformers` in place. The instruction is to install into a dedicated virtualenv or conda environment, not a shared base.

The dependency list in the metadata confirms the shape of that footprint. It includes `rfdetr` at 1.3.0 or newer, `transformers` at 4.57 or newer, `ultralytics` at 8.3.204 or newer, `onnx`, `onnxruntime` and `onnxslim`, `huggingface-hub`, `pypdf`, `pillow`, `pydantic` and `formalpdf` pinned exactly at 0.1.6.

Two things stand out. The `onnxruntime` and `onnxslim` combination means the models can be converted to ONNX for inference, which is a portability feature rather than a necessity, and `formalpdf` pinned to an exact version is a hard dependency on a specific PDF library, so a conflict there will not resolve itself.

The release history also mentions the model provenance. Version 0.2.0 is described as Apache-licensed FFDetr, which suggests the 0.2 line moved to a different detection backbone and that the FFDNet weights and the FFDetr licensing are not the same thing. That distinction is worth checking against the model you actually download.

The CLI is ten arguments, and five of them change what you get

The command line surface is short and the defaults are conservative.

code
commonforms <input.pdf> <output.pdf>

That runs inference on the CPU using the default suggested settings, and the README says it should work on most PDFs.

The arguments table lists input and output as required paths, and then the options. `--model` takes a model name, FFDNet-L or FFDNet-S, or a path to a custom `.pt` file, and defaults to `FFDNet-L`. `--keep-existing-fields` is a flag defaulting to False, and it keeps existing form fields in the PDF, which matters when you are processing a document that already has some fields and you do not want to lose them. `--use-signature-fields` defaults to False and uses signature fields instead of text fields for detected signatures. `--device` defaults to `cpu` and takes things like `cpu`, `cuda` or `0`. `--image-size` defaults to 1600 and sets the image size for inference. `--confidence` defaults to 0.3 as the detection threshold.

Then two flags that are about the shape of the result rather than the detection. `--fast` is for CPU runs and trades accuracy for speed, running in about half the time. `--multiline` makes the detected textboxes allow multiline inputs.

That last flag is a good example of why this tool is worth a look. A detector that finds a box has no way to know whether the field it found is a name or an address, so whether the resulting form field accepts one line or many is a decision the user makes globally, and a global decision is wrong for some fields and right for others.

The `--keep-existing-fields` flag is the other one to note. Re-running a tool over a PDF that already has fields is a common operation, and losing the fields you already had is a nasty surprise.

The API is the same arguments as keyword parameters

The library path is a single function, and the README makes a point about the interface that is worth repeating.

py
from commonforms import prepare_form

prepare_form(
    "path/to/input.pdf",
    "path/to/output.pdf"
)

All of the CLI arguments are keyword arguments to the `prepare_form` function. That is a genuinely nice property of the design, because it means the two interfaces cannot drift, and a script written in Python has exactly the same knobs as the command line.

The function signature and the console script are declared in the metadata, with `commonforms` mapped to `commonforms:main` as the entry point and the package built by setuptools with a single package, `commonforms`.

The `formalpdf` dependency is pinned to an exact version, and `pypdf` is required at 6.1.1 or newer. `cryptography` at 3.1 or newer is present, which is consistent with PDF digital signature handling being in scope for a form tool.

One thing the README does not describe, and which is the gap to know about, is what the output looks like when detection is wrong. There is no validation pass, no confidence report per field and no way to review the detected fields before they are written into the output PDF. The output is the artifact, and the only review mechanism is opening it.

The API is also the right level to build a review workflow on. Calling `prepare_form` per document, and looking at the resulting form before you distribute it, is the obvious way to use this at scale, and the fact that the function takes the same options as the CLI means you can tune per document type.

A paper, a dataset and a hosted service define the project's shape

The surrounding ecosystem tells you what kind of project this is.

The CommonForms paper is on arXiv as 2509.16506, and the citation block in the README gives the BibTeX with the title, the author, the year, the archive prefix, the primary class cs.CV and the DOI. The instruction is to cite the paper if you use the tool, the models or the code in an academic paper, and if you use it in a non-academic setting, to reach out to the author directly, which the README says with a request to hear where the work is being used.

The dataset is on Hugging Face as jbarrow/CommonForms, and the two model checkpoints are separate entries, FFDNet-L and FFDNet-S. The hosted model service is at detect.semanticdocs.org.

The name of the dataset is the important part. A large, diverse dataset for form field detection is the reusable asset here, and the tool is a thin, well-tuned consumer of it. For a researcher, the dataset is what to look at. For an engineer with PDFs to process, the tool is what to run.

The two model sizes map onto a real trade-off in the CLI. FFDNet-L is the default, and FFDNet-S is the smaller one, and the `--model` argument also accepts a path to a custom `.pt` file, so you are not locked to either.

The maintenance picture: the last push to the repository was on 2026-06-17 and it is not archived. The release tags are 0.2.0 on 2025-11-26, described as Apache-licensed FFDetr, 0.1.6 on 2025-10-19, described as multiline and support for Python 3.10, and 0.1.5 on 2025-10-15, described as faster build times and faster CPU inference. The metadata version is 0.2.1, which is ahead of the last tag, so the repository is the more current source.

The 0.1.5 note is the one to weigh. Faster CPU inference and faster build times are what a tool needs before it can be run over a large corpus, and the fact that it was a priority suggests the tool was being used at volume.

Editorial conclusion

Adopt CommonForms if you have a pile of flat PDFs and need fillable versions of them, and you are willing to tune a confidence threshold and check the output. Do not adopt it expecting every field to be detected correctly on the first run, because a detector at a 0.3 confidence threshold will both miss faint fields and invent others, and the tool has no validation step. Verify first that the fields it found are the fields you wanted, that your PDFs are not already filled or signed in a way that complicates editing, and that the licence of the models you use, which the release notes distinguish between an Apache-licensed FFDetr and the FFDNet models, fits your use.

Frequently asked questions

How do I install CommonForms without breaking my environment?

Use uv tool install commonforms or pipx install commonforms for an isolated install that exposes only the commonforms command. The README warns that installing into an active environment can upgrade numpy, pillow and transformers in place, so a dedicated virtualenv or conda environment is recommended.

What does the CommonForms CLI command look like?

The simplest form is commonforms <input.pdf> <output.pdf>, which runs inference on the CPU with the default settings. The default model is FFDNet-L, the default device is cpu, the default image size is 1600 and the default confidence threshold is 0.3.

How do I use CommonForms as a Python library?

Import prepare_form from commonforms and call it with the input and output paths. All of the CLI arguments are keyword arguments to prepare_form, so the two interfaces offer the same options.

What are the FFDNet-S and FFDNet-L models?

They are the two model checkpoints from the CommonForms paper, released separately on Hugging Face and selectable with the --model argument, which also accepts a path to a custom .pt file. The 0.2.0 release notes mention an Apache-licensed FFDetr, so the licences of the different model artefacts are not identical.

How do I keep existing form fields when converting a PDF?

Pass the --keep-existing-fields flag, which defaults to False, to keep the form fields already present in the input PDF. The --use-signature-fields flag separately switches detected signatures to signature fields rather than text fields.

Official sources

  1. Issues
  2. jbarrow/commonforms on GitHub
  3. README
  4. 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/jbarrow-commonforms.svg)](https://hysenlabs.com/projects/jbarrow-commonforms)

Was this useful?