AdGuard FiltersRegistry: The Build Pipeline Behind AdGuard's Filter Subscriptions
Known filters subscriptions transformed for better compatibility with AdGuard
At a glance
- What is it?
- AdGuard FiltersRegistry is the canonical source repository for all filter subscriptions served to AdGuard users. It compiles filter templates into platform-specific outputs for eight AdGuard product platforms, generates incremental patches, and re-hosts accepted third-party lists via filters.adtidy.org.
- Who is it for?
- Developers contributing a new filter list should read the 12-point acceptance policy in the README before submitting a pull request; a filter that fails point 9 (too many problematic rules) or point 2 (paywall circumvention) will be rejected regardless of popularity. Teams maintaining the registry itself need Node.js 24 or later, and should run `yarn validate` before any build to catch malformed metadata.json files early.
- Can I use it commercially?
- Yes, with conditions. LGPL-3.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Adblock Filter List, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 27, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What AdGuard FiltersRegistry Does and Who Uses It
AdGuard FiltersRegistry is an internal build and hosting system, not a user-facing tool. Its purpose is to manage the complete set of filter subscriptions that AdGuard products download and apply. Two audiences interact with it directly: AdGuard's own engineering team, which maintains and evolves the build pipeline and the AdGuard-authored filters, and external filter list authors who want their list included in the registry and served to all AdGuard users.
The repository stores both AdGuard's own filters under `filters/` and accepted third-party filter lists under `filters/ThirdParty/`. Every list in the registry is served via `filters.adtidy.org` rather than from its original source URL, which means AdGuard controls the serving infrastructure and can apply compatibility transformations before delivery. A filter's `subscriptionUrl` field in its metadata.json records where the third-party list originally comes from, but users download the re-hosted version.
The eight supported product platforms are Android, CLI, Extension, iOS, Mac, Mac v2, Mac v3, and Windows. A single filter template produces different compiled outputs for each platform, with rules that are incompatible with a given platform stripped from that platform's output file.
How the Build Pipeline Compiles Filter Templates
Each filter is stored as a directory containing three files. `template.txt` is the source the compiler processes. `exclude.txt` contains regular expressions; any rule matching one of these patterns is dropped before compilation. `metadata.json` carries the filter's identity and configuration: its numeric `filterId`, name, description, homepage, group assignment, download URL, list of tags, trust level, and which platforms it targets.
The build pipeline uses `@adguard/filters-compiler` (version 3.4.0 as of the repository's current package.json) to transform each template into platform-specific filter files. It generates incremental patches using `@adguard/diff-builder` and produces localized metadata for each supported language using Crowdin configuration declared in `crowdin.yml`.
Filters can target a subset of platforms by setting the `platformsIncluded` array in their metadata.json. The README gives `["mac", "windows", "android"]` as an example. If a filter lists no platforms, the README notes it will be compiled for all platforms by default.
Wildcard domain expansion is a separate preprocessing step. The `update-wildcard-domains` and `expand-wildcard-domains` scripts fetch domain data, expand wildcard patterns, and write the results back into the filter template files. This step runs independently from the main build and requires network access.
Filter Directory Structure and metadata.json Fields
Understanding the metadata.json schema is necessary before adding or modifying any filter. The README documents all fields. Several carry operational consequences that are easy to miss.
The `disabled` field marks a filter as removed: its building is skipped and it is no longer served. The README specifies that `disabled` should be accompanied by the `obsolete` tag. The `deprecated` field is weaker: it marks a filter as no longer relevant but still builds and serves it. The distinction matters because a deprecated filter remains in product UIs while a disabled one disappears entirely.
The `trustLevel` field has three values: `low`, `high`, and `full`. Only AdGuard's own filters carry `full` trust. The `low` and `high` levels restrict which rule types the compiler allows from third-party filters, with `low` permitting only low-risk types and `high` permitting a broader but still restricted set. The README notes that a filter without an explicit trust level defaults to `low`. Third-party filters whose trust level improves over time can be re-reviewed and raised.
The `expires` field sets the default update interval that AdGuard products use when the user selects "Default" in their update settings. The `displayNumber` field controls how the AdGuard UI sorts filters in its list. These two fields are invisible to end users but affect how the product presents and refreshes the filter.
Building and Validating the Repository Locally
The repository requires Node.js 24 or later, as declared in the `engines` field of `package.json`. The package manager is Yarn. After cloning and installing dependencies, the two most important build commands are:
yarn build
yarn build:localThe difference is caching: `build:local` passes `--use-cache` to the build script, which reuses previously downloaded filter source files rather than fetching them again. On a machine with a slow connection or rate-limited API access, `build:local` is substantially faster for iterative work.
Before pushing a change, run the validation suite:
yarn validateThis runs `validate:platforms` and `validate:locales` in sequence. Platform validation checks that `platformsIncluded` and `platformsExcluded` values in metadata.json match the known platform identifiers. Locale validation checks that localized strings are well-formed. Both validators emit specific error messages that identify the file and field at fault.
For testing the compiler logic itself:
yarn testThis runs the Vitest suite. The linting targets are `yarn lint:code` (ESLint), `yarn lint:types` (TypeScript), and `yarn lint:md` (markdownlint). Running all three via `yarn lint` is recommended before a pull request.
The Third-Party Filter Acceptance Policy
The README specifies twelve criteria for accepting a third-party filter into the registry. Several are worth understanding before investing time in a submission.
Orientation matters first: the filter must target browser content blockers. A system-level or network-level filter is out of scope. Legality is a hard gate: the README explicitly names paywall circumvention as a disqualifying category. Both criteria are non-negotiable.
Popularity requirements are concrete. A GitHub-hosted filter needs at least 50 stars. A filter without a GitHub repository needs roughly 10 user issues or discussions per month on its own site. Either way, the filter must have been actively maintained for at least six months before submission.
Update frequency has a specific threshold: at least 10 updates per month. A filter that receives occasional large batches of changes rather than regular small ones may fail this criterion even if it is technically maintained.
Problematic rules are assessed at the AdGuard team's discretion. The README defines a problematic rule as one that causes false positives or unintended behavior. There is an explicit catch: a filter that blocks services purely to reflect the author's opinion, with no other justification, will not be added. This is a content-moderation stance applied to the filter list itself, not just to its rules.
Filters already in the registry that go without support for a year are subject to removal. The trust level can be raised over time if the author addresses earlier concerns.
Limitations of the Registry Model
AdGuard FiltersRegistry is not designed as a general-purpose filter list hosting system. Several constraints follow from its architecture.
All third-party filters are re-hosted via `filters.adtidy.org`. This means a filter author loses direct control of the URL users subscribe to. If AdGuard removes a filter from the registry, users who subscribed through the registry URL will stop receiving updates, and they will need to switch to the original source URL manually.
The 12-point acceptance policy gives AdGuard broad discretion to reject or remove filters based on content judgments (point 9 and the opinion-blocking clause). A filter list author whose content philosophy diverges from AdGuard's criteria has no recourse except to distribute independently.
The build pipeline adds meaningful operational complexity. It requires Node.js 24, Yarn, a configured TypeScript environment, and for wildcard domain expansion, network access to external domain sources. A team that only needs to serve one filter list in one format will find this infrastructure excessive compared to simply hosting a static text file.
Localization depends on Crowdin integration. Teams without access to Crowdin or without translated string resources cannot fully use the localization pipeline, meaning their filter's metadata will appear only in the language they authored it.
Comparison with Independent Filter List Hosting
The practical alternative to inclusion in AdGuard FiltersRegistry is maintaining a filter list independently and pointing users to the raw source URL for subscription. EasyList, for example, is a collaboratively maintained set of filter lists that authors contribute to directly. A filter submitted to EasyList works across uBlock Origin, AdGuard, and other ad-blockers without requiring platform-specific compilation, because those products handle rule interpretation themselves.
The difference in approach is compilation control versus broad compatibility. FiltersRegistry's compilation step strips incompatible rules per platform and generates incremental patches, meaning users on older versions download only the changes rather than the full list on every update. An independently hosted raw filter list offers none of those optimizations; the ad-blocker itself fetches the full file and handles rule filtering. For a large filter with frequent updates and many users spread across multiple AdGuard product platforms, the registry's compilation model reduces bandwidth and improves update reliability. For a small or specialized filter targeting a single browser extension, independent hosting with a direct subscription URL is simpler to maintain and imposes no trust-level constraints.
License and Maintenance Status
The repository is licensed under LGPL-3.0. For third-party filter contributions, the LGPL applies to the build infrastructure and tooling, not to the filter rules themselves, which each carry their own licensing terms in their respective metadata. Contributors should verify the license compatibility of their filter content before submission.
The last recorded push to the master branch was on 2026-09-27, one day before this writing. The package.json shows version 1.1.0. The build dependencies are pinned to specific versions: `@adguard/filters-compiler` at 3.4.0, `@adguard/diff-builder` at 1.1.4, and `@adguard/agtree` at 4.2.1. Upgrading any of these components requires retesting the full build and validation suite, since the compiler interface can change between minor versions. The `engines` field pins Node.js at 24 or later, so any CI or developer machine running an older version will produce a hard failure rather than a silent incompatibility.
Editorial conclusion
Developers contributing a new filter list should read the 12-point acceptance policy in the README before submitting a pull request; a filter that fails point 9 (too many problematic rules) or point 2 (paywall circumvention) will be rejected regardless of popularity. Teams maintaining the registry itself need Node.js 24 or later, and should run `yarn validate` before any build to catch malformed metadata.json files early. The build pipeline is well-suited for managing a large, multi-platform filter estate; it is the wrong tool if you need only a single-format filter list hosted at a static URL.
Frequently asked questions
How do I add a third-party filter list to AdGuard FiltersRegistry?
A filter must meet all twelve criteria in the README acceptance policy, including a minimum 50-star GitHub presence or equivalent traffic, at least 10 updates per month, six months of active maintenance, and compatibility with AdGuard syntax. Filters containing paywall circumvention rules or opinion-based blocking will not be accepted.
What are the platform-specific filter URLs that AdGuard FiltersRegistry produces?
The compiled filter files are served via `filters.adtidy.org`. Each filter's metadata.json includes a `downloadUrl` field with the exact serving URL, and third-party filters include a `subscriptionUrl` field pointing to the original source.
What Node.js version does AdGuard FiltersRegistry require?
The repository's package.json specifies Node.js 24 or later in the `engines` field. Running an older version will cause the build to fail.