This guide covers setting up your development environment, building the library, running tests, and contributing code to the AdGuard Filters Compiler.
| Tool | Version | Notes |
|---|---|---|
| Node.js | 22 | Use nvm to manage versions |
| pnpm | 10.7 | Package manager |
| Git | Latest | Version control |
Note: Development is tested on macOS and Linux. Windows users should use WSL or a virtual machine.
# GitHub
git clone https://github.com/AdguardTeam/FiltersCompiler.git
# or internal Bitbucket mirror — use the canonical URL for your environment
cd FiltersCompilerpnpm installpnpm buildBuild output goes to dist/ (ESM: dist/index.js, CJS: dist/index.cjs).
Rollup also copies JSON schemas and trust-level files into dist/.
pnpm testpnpm lint| Command | Description |
|---|---|
pnpm install |
Install dependencies |
pnpm build |
Build the library (Rollup → dist/) |
pnpm test |
Run all tests (Vitest) |
pnpm lint |
Run ESLint and TypeScript type checker |
pnpm lint:code |
Run ESLint |
pnpm lint:types |
Run TypeScript type checker (tsc --noEmit) |
pnpm build-schemas |
Regenerate JSON schemas from tasks/build-schemas/ |
pnpm build-txt |
Generate dist/build.txt with version info |
pnpm increment |
Bump patch version in package.json |
pnpm tgz |
Pack release tarball (filters-compiler.tgz) |
New source files should be written in TypeScript. The project uses TypeScript
in strict mode for new .ts files while leaving existing .js files
unchanged.
| Command | Description |
|---|---|
pnpm lint:code |
ESLint — automatically uses the TypeScript parser for .ts files |
pnpm lint:types |
Run the TypeScript type checker (tsc --noEmit) |
pnpm build |
Rollup — transpiles .ts files via @rollup/plugin-typescript |
- Create your
.tsfile undersrc/(e.g.,src/main/utils/my-feature.ts) - Import it from existing code — both
.js → .tsand.ts → .jsimports work - When importing a
.jsmodule from.ts, the import resolves toanyvia the ambient declaration insrc/types/global.d.ts. For better type coverage, write a.d.tsshim alongside the.jsfile. - Run
pnpm lint && pnpm test && pnpm build
Create test files as test/*.test.ts. Vitest discovers both .test.js and
.test.ts files automatically.
- New files: Write in TypeScript
- Existing files: Leave as JavaScript until explicitly migrated
allowJs/checkJs: Disabled — existing JS is not type-checkedstrictmode: Enabled for all.tsfiles- Naming collisions: Do not create
foo.tsalongsidefoo.jsin the same directory — rename or migrate instead
Run these checks before every commit:
# 1. Lint (includes type-checking)
pnpm lint
# 2. Run tests
pnpm testBoth must pass with no errors. Husky pre-commit hook runs pnpm lint && pnpm test
automatically.
- Create a feature branch from
master - Make your changes
- Ensure
pnpm lintandpnpm testpass - Submit a pull request to
master
Changes that affect src/ should be guided by a lightweight spec authored
before implementation begins.
- Draft — create a new spec in
specs/.current/(this directory is local-only; its contents are gitignored). - Review — share the spec for review (e.g., attach to the PR description or a JIRA ticket).
A spec directory contains at minimum:
| File | Purpose |
|---|---|
spec.md |
Problem statement, proposed solution, and acceptance criteria |
Additional files (diagrams, example filter snippets, etc.) may be added as needed.
- Each acceptance criterion in the spec should correspond to at least one test
case in
test/. - Reference the spec path in the test description or a comment so reviewers can trace coverage back to the spec.
- If full test coverage is deferred, note it as "future work" in the spec.
specs/
├── .current/ # WIP — local only, gitignored contents
│ └── .gitkeep
├── add-platform-x/ # Finalized and committed
│ └── spec.md
└── ...
Schemas in schemas/ are generated — never edit them directly. Edit the
generation scripts in tasks/build-schemas/ instead:
pnpm build-schemasImportant: Legacy schemas in
schemas/mac/andschemas/mac_v2/must not be changed.
To add support for new scriptlets and redirects, update @adguard/tsurlfilter
(which bundles updated @adguard/scriptlets):
pnpm add @adguard/tsurlfilter@latestFor fixing scriptlets converting or validation specifically, update
@adguard/scriptlets directly:
pnpm add @adguard/scriptlets@latest# 1. Bump the patch version
pnpm increment
# 2. Build the library
pnpm build
# 3. Generate build info
pnpm build-txt
# 4. Pack the tarball
pnpm tgzThis produces filters-compiler.tgz ready for publishing.
# Run all tests once
pnpm test- Framework: Vitest with node environment
- Config:
vitest.config.js - Test files:
test/*.test.{js,ts}
Test fixtures are in test/resources/:
- Filter files and platform configs used as test inputs
- Expected output files for comparison
- Some resources are gitignored (generated during test runs)
Problem: Build or tests fail with unexpected errors.
Solution: Ensure you are using Node.js 22:
node --version # Should be v22.x.xIf using nvm:
nvm install 22
nvm use 22Problem: Tests fail after directly editing files in schemas/.
Solution: Never edit schemas manually. Revert your changes and use the generation scripts:
git checkout schemas/
# Edit tasks/build-schemas/ instead, then:
pnpm build-schemasProblem: pnpm: command not found
Solution: Install pnpm globally:
npm install -g pnpm
# or
corepack enable
corepack prepare pnpm@latest --activate- AGENTS.md — AI agent instructions and code guidelines
- README.md — Project overview and usage documentation
- CHANGELOG.md — Version history
- FiltersRegistry — Consumer of this library
- AdGuard JavaScript Code Guidelines — Code style reference