999 Cleaner is a small local-first browser extension that removes already-rejected
999.md ads from your browsing flow. It was built as a practical personal tool:
when you check the same search every day, the same listings keep coming back.
This keeps the page focused on listings you still care about.
This project is unofficial and is not affiliated with 999.md.
- Firefox package for Mozilla Add-ons and temporary local testing.
- Chrome package for Chrome Web Store and Chromium-derived browsers such as Brave, Opera, Vivaldi, and Chromium.
- Edge package for Microsoft Edge Add-ons.
Safari is not packaged by this repository yet. Safari distribution needs an Apple Developer/Xcode pipeline and should be added as a separate release track.
- Adds a local hide action to detected
999.mdlist cards. - Hides previously rejected ads automatically by exact ad ID.
- Adds a detail-page panel for hiding or restoring the current ad.
- Provides a popup with hidden-ad count, restore buttons, saved links, and full clear.
- Keeps all hidden-ad state in browser local extension storage.
- Declares no data collection in the Firefox manifest.
- Ships with TypeScript, WXT, Vitest, jsdom, Biome, pnpm, and GitHub Actions CI.
999 Cleaner is local-first by design.
- No account.
- No backend.
- No analytics.
- No tracking.
- No remote sync.
- No data sale or sharing.
The extension only requests access to https://999.md/*,
https://www.999.md/*, and local extension storage. Hidden ads stay in the
current browser profile.
The intended installation paths are the browser extension stores:
- Mozilla Add-ons for Firefox.
- Chrome Web Store for Chrome and most Chromium-derived browsers.
- Microsoft Edge Add-ons for Edge.
Until those listings are accepted, GitHub Releases provide packaged builds for inspection and temporary testing. Unsigned Firefox packages are not a replacement for a signed Mozilla Add-ons listing for everyday use.
Requirements:
- Node.js 22.
- Corepack enabled with
corepack enable.
pnpm install --frozen-lockfile
pnpm release:checkTemporary Firefox test:
pnpm build:firefoxThen open Firefox:
- Go to
about:debugging#/runtime/this-firefox. - Click
Load Temporary Add-on. - Select
.output/firefox-mv2/manifest.json.
Temporary Chrome or Chromium test:
pnpm build:chromeThen open chrome://extensions, enable Developer mode, click Load unpacked,
and select .output/chrome-mv3.
Temporary Edge test:
pnpm build:edgeThen open edge://extensions, enable Developer mode, click Load unpacked, and
select .output/edge-mv3.
pnpm install --frozen-lockfile
pnpm dev:firefox
pnpm dev:chrome
pnpm dev:edgeUseful checks:
pnpm lint
pnpm format:check
pnpm test
pnpm typecheck
pnpm build:all
pnpm zip:all
pnpm release:checkRegenerate extension icons after changing scripts/generate-icons.mjs:
pnpm generate:iconspnpm dev:firefox uses Firefox Developer Edition automatically when it is
installed at C:\Program Files\Firefox Developer Edition\firefox.exe. To
override the browser binary, set FIREFOX_BINARY before running the command.
entrypoints/999.content/- content script and CSS injected into999.md.entrypoints/popup/- extension popup UI.public/icon/- generated extension icons used by browser manifests.scripts/- deterministic local tooling such as icon generation.src/999/-999.mdURL, filter, and DOM helpers.src/content/- runtime behavior for cards and detail pages.src/manifest/- browser-specific manifest construction.src/storage/- hidden-ad state and extension storage adapter.tests/- unit tests for parsing, DOM detection, storage, manifests, assets, and content behavior.
The content script scans links that look like 999.md ad detail URLs, extracts
the ad ID, finds the closest single-ad card wrapper, and adds a small hide
button. When a listing is hidden, the ad ID and optional metadata are persisted
locally. Future page scans remove matching cards from the DOM.
The extension also hides some promoted list ads that visibly violate active
filters supported by the current MVP, such as known location aliases, room count,
and max price filters. This logic is intentionally conservative because 999.md
markup can change.
- Detection uses public URL patterns plus DOM heuristics, not private
999.mdinternals. - Hidden state is local to the current browser profile.
- The extension hides exact ad IDs only; it does not detect reposts with new IDs.
- Map/canvas marker support is not fully solved. Only visible DOM cards or popups can be handled reliably.
- The UI copy is currently optimized for the languages used on
999.md.
Maintainer release steps live in docs/RELEASING.md. Store submission copy and reviewer notes live in docs/STORE_SUBMISSION.md.
MIT. See LICENSE.