Self-hosted service
facebook/ThreatExchange avatar
facebook/ThreatExchange

facebook/ThreatExchange: PDQ, TMK and HMA for content moderation

Trust & Safety tools for working together to fight digital harms.

1,401 stars362 forksC++NOASSERTION

At a glance

What is it?
facebook/ThreatExchange is a collection of C++ hashing projects, Python tooling, API examples and moderation services for comparing and exchanging content signals. It suits trust and safety engineers, but the components have different deployment models and maturity.
Who is it for?
Adopt the hashing libraries when you need documented image or video similarity primitives, and evaluate HMA only if its AWS model matches your environment. Do not treat Open Media Match as a finished cloud-neutral deployment.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly C++, 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

PDQ and TMK address different media matching tasks

facebook/ThreatExchange originated as code for Meta's ThreatExchange API, but the repository now contains several projects aimed at content moderation and signal exchange. Its clearest building blocks are perceptual and video hashing algorithms. These tools address a specific problem: deciding whether two images or videos are sufficiently similar to find known content after transformations such as resizing or format changes. They are relevant to trust and safety engineers who maintain known-content lists, investigate reused media or build automated moderation workflows.

PDQ is the repository's image hashing component. According to the README, PDQ converts a photo into a 256-bit signature. Two resulting signatures can then be compared for similarity. The signature is not the original image, which makes the representation more suitable for scalable matching than retaining every image in a local scanning corpus. However, the README does not define the matching threshold, normalization procedure or tolerance for edited images, so those details must come from the PDQ-specific documentation or implementation rather than assumptions.

TMK+PDQF, abbreviated as TMK, targets video. The README states that it turns a video into a 256KB signature. That larger representation reflects the need to encode temporal information, although the repository description does not expose its internal stages. vPDQ offers a different strategy: it considers two videos matching according to the number of shared similar frames. It can also be applied to image hashing algorithms other than PDQ. Engineers choosing between TMK and vPDQ therefore face a concrete design choice between a video-specific 256KB signature and frame-overlap matching.

HMA adds list management to the hashing components

Hasher-Matcher-Actioner, or HMA, turns standalone similarity tools into a deployable content moderation platform for AWS. The README describes it as a list-driven system. Operators curate lists of known content, or connect the platform to hash exchange programs to share and receive lists. The implied moderation flow begins with a hasher that represents incoming media, continues through a matcher that compares representations against known content, and ends with an action component that applies a moderation result. The repository name makes those stages explicit, while the root README leaves their interfaces and operational details to the HMA wiki.

This architecture is more useful than a hashing function when the requirement includes ongoing list ingestion, content matching and action handling. It also introduces more operational surface. AWS deployment, connected exchange services, list quality and moderation policy all become part of the system boundary. HMA is therefore aimed at organizations willing to operate a moderation pipeline, not merely developers who need a callable image comparison function.

The repository also contains `open-media-match`, described as a second HMA version under construction with a cloud-agnostic Docker-based deployment. That distinction matters. Open Media Match should not be presented as a finished alternative to HMA because the README explicitly labels it as under construction. It signals an intended move away from an AWS-specific deployment model, but it does not establish feature parity, production readiness or migration compatibility.

python-threatexchange provides the documented Python entry point

The `python-threatexchange` directory provides a Python library and CLI published on PyPI under the package name `threatexchange`. Its documented reference implementations include downloading hashes from Meta's ThreatExchange API and scanning images with PDQ. The project is designed to be extensible to other hash exchanges and techniques, although the README warns that not every extension is written by the repository maintainers. That qualification separates the core reference implementation from third-party additions.

For engineers who want to combine Meta-hosted threat data with local PDQ processing, this package is the most direct documented starting point in the repository. It can serve as a library inside a larger service or through its CLI. The repository listing also contains `api-reference-examples`, with implementations in several languages. Those examples are explicitly incomplete: they may not cover every ThreatExchange API endpoint. For tag-driven workloads that require bulk download or incremental updates, the README points to a Java reference design rather than presenting the examples as a complete data pipeline.

The hosted ThreatExchange API addresses shared threat intelligence for malware, phishing pages and other threats. Access is application-based through Meta's developer site. That makes the hosted API a controlled external dependency, while the local hashing tools do not inherently require access to it. Teams evaluating the repository should distinguish between using the algorithms locally and using Meta's exchange service.

Installing python-threatexchange and obtaining API access

The README states that `python-threatexchange` is available on PyPI under `threatexchange`, but it does not provide an installation command, supported Python version or CLI invocation. Consequently, this article does not invent a `pip` command or a first executable example. Start by locating the package documentation on PyPI and confirm the supported runtime before installing it. The root README alone is insufficient to confirm an exact first-use command.

Meta's hosted ThreatExchange is a separate access path. The README directs applicants to submit an application through Meta's ThreatExchange developer product page:

text
https://developers.facebook.com/products/threat-exchange/

This command block contains the documented application URL rather than a command. An applicant should not expect API data to work merely because the local Python package is installed. The repository's local PDQ, vPDQ and TMK projects address media comparison, while hosted API access governs querying, publishing and sharing threat information.

For tag-based bulk extraction and incremental updates, the README identifies the Java reference design under `api-reference-examples/java/te-tag-query` as its recommended approach. That is the documented path to investigate when the workload is organized around tags rather than a single media scan.

The repository is broad, but component boundaries remain important

The repository is not a single application with one setup procedure. Its top-level layout separates `pdq/`, `tmk/`, `vpdq/`, `hasher-matcher-actioner/`, `open-media-match/`, `python-threatexchange/` and `api-reference-examples/`. That separation allows an engineer to adopt a narrow hashing component without deploying the entire moderation platform. It also means that a feature visible in the root README does not imply that every component supports the same language, packaging system or deployment target.

There are two meaningful alternatives within the repository. PDQ produces a compact 256-bit image signature, while vPDQ compares shared similar video frames and can use image algorithms beyond PDQ. TMK provides a separate 256KB video signature. These are not interchangeable labels for one operation. Their storage, comparison behavior and expected media inputs need separate evaluation.

HMA and Open Media Match form another comparison. HMA is documented as ready to deploy on AWS, while Open Media Match is under construction and targets cloud-agnostic Docker deployment. For an organization already committed to AWS and in need of list-based moderation, HMA is the documented full platform. For a team seeking a portable deployment, the repository currently identifies a direction rather than a confirmed production substitute.

Licensing and maintenance require a file-level review

The README says that projects in the repository are under the BSD license, subject to exceptions whose alternative licenses appear at the top of the affected files. It identifies one exception as of 12/9/2021: `pdq/cpp/CImg.h`. An engineer considering the C++ image hashing code should therefore inspect that file's license notice rather than assuming that every repository file has identical terms. This is a licensing boundary to verify, not legal advice about permitted use.

The repository is not archived. Its last push was on 2026-10-14, and recent HMA releases include `hma-v1.2.0` on 2026-10-02, `hma-v1.1.7` on 2026-06-04 and `hma-v1.1.6` on 2026-05-22. These facts show recent HMA release activity and a current repository push, but they do not establish that every subproject has the same release cadence. The root README provides no upgrade procedure, compatibility matrix or rollback documentation.

The custom classification shown in repository metadata also deserves attention because the README makes a specific BSD statement with exceptions. Review `LICENSE` and any file-level notice before redistribution. For upgrades, inspect the releases for the selected component rather than treating the latest HMA version as the version of PDQ, TMK, vPDQ or `python-threatexchange`.

Editorial conclusion

Adopt the hashing libraries when you need documented image or video similarity primitives, and evaluate HMA only if its AWS model matches your environment. Do not treat Open Media Match as a finished cloud-neutral deployment. Before selection, verify component-specific licensing, especially `pdq/cpp/CImg.h`, and the documentation for the exact subproject you intend to operate.

Frequently asked questions

What is facebook/ThreatExchange used for?

It contains tools for content moderation, media similarity matching and security signal exchange. Examples include PDQ image hashing, TMK video hashing, HMA list management and Python implementations for working with Meta's ThreatExchange API.

How do I install facebook/ThreatExchange?

The README says the Python library and CLI are available on PyPI as `threatexchange`, but it does not give an installation command or supported Python version. The repository also contains multiple independent projects, so installation details must be checked for the selected component.

What is the difference between HMA and Open Media Match?

HMA is described as a ready-to-deploy moderation platform for AWS. Open Media Match is a second version under construction that uses a cloud-agnostic Docker-based deployment, so the README does not present it as a finished replacement for HMA.

Does facebook/ThreatExchange support video similarity matching?

Yes. TMK produces 256KB video signatures, while vPDQ determines whether videos match by considering shared similar frames. vPDQ can also be applied to image algorithms other than PDQ.

Official sources

  1. facebook/ThreatExchange on GitHub
  2. Issues
  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/facebook-threatexchange.svg)](https://hysenlabs.com/projects/facebook-threatexchange)