unclutter
September 18, 2026 · View on GitHub
WXT browser extension: Jev-powered page clutter removal with reusable template rules.
Made by Kitze
kitze.io · X · YouTube
More projects by Kitze
![]() Zero To Shipped A full-stack starter kit for web and mobile apps. |
Sotto Voice-to-text for macOS. Local AI, one-time purchase. |
Tinkerer Club A private community for builders, self-hosters, and AI tinkerers. |
|
Sizzy The browser for web developers. |
Supermac A macOS command center for everyday workflows. |
DMX A focused desktop client for X. |
Support this project
Sponsors
|
Postiz Schedule social posts with AI agents. |
FounderStack A SaaS stack for your business, without subscriptions. |
Matte 3D mockups, screen recordings, and video editing. |
|
HTML/CSS to Image Turn HTML/CSS into images, PDFs, and screenshots. |
NameMyVenti Get your brand shouted out at Starbucks. |
|
Unclutter
WXT extension for Chrome / Chromium and Firefox. Jev classifies nonessential page elements through Vercel AI Gateway or TypeSafe AI directly; the extension stores and reapplies local hiding rules by page template.
Install from source
Requires Bun and Node.js 22.12 or newer.
git clone https://github.com/kitze/unclutter.git
cd unclutter
bun install --frozen-lockfile
bun run build
- Open
chrome://extensions(or your Chromium browser's extensions page). - Turn on Developer mode.
- Click Load unpacked and select
.output/chrome-mv3inside the cloned repository. - Pin Unclutter, refresh any already-open website, then open its popup.
- Under Connection, choose Vercel AI Gateway or TypeSafe AI, paste the matching API key, and save it.
- Choose Manual (default) and click Analyze page, or select On page visit. Your selected provider must have credits / Jev access.
After replacing unpacked builds, click Reload on the extension card and refresh website tabs. Existing keys/settings stay in place. V1 templates show Update available; Re-analyze once to include cookie dialogs, or automatic mode upgrades them once while preserving paused templates and keep-visible choices.
For Firefox 140+, run bun run build:firefox, open about:debugging#/runtime/this-firefox, choose Load Temporary Add-on, and select .output/firefox-mv2/manifest.json. Temporary add-ons disappear on Firefox restart; permanent Firefox distribution requires Mozilla signing. Chrome/Edge/Brave can use the Chromium build. Safari packaging is not included.
Bring your own Vercel AI Gateway key or TypeSafe AI key (the same kind used as JEV_KEY / TYPESAFE_API_KEY). Configure it in the extension popup, not in source code or build-time environment variables. No key or shared account is bundled.
One key is stored. Switching the provider persists immediately and reuses that key for the next analysis; paste a matching key if the providers use different credentials. Saving a key saves the selected provider with it. Removing the key does not reset the provider. Existing installations without a provider setting default to Gateway. Saved templates remain usable offline regardless of provider.
TypeSafe direct uses POST https://api.typesafe.ai/v1/systemone, Bearer authentication, and body model jev-latest. Gateway uses its evaluation-model v4 endpoint and typesafe-ai/jev headers. TypeSafe requests never carry Gateway protocol headers; Gateway requests never carry the TypeSafe model field.
Behavior
- Manual: paid analysis only when you click Analyze page / Re-analyze.
- On page visit: analyze new templates in visible tabs, after a short render-settling delay. This automatically sends candidate snippets to the selected provider and incurs API charges. Off by default.
- Saved templates apply without further model requests, including zero-rule results. New analysis-rubric versions may refresh an enabled old template once in automatic mode; paused profiles and disabled rules are preserved.
- Automatic attempts are deduplicated across tabs and persisted before the request. Failure/interruption does not trigger automatic retries; click Analyze page / Re-analyze to retry.
- Cookie overlays (including Sourcepoint's session-numbered iframe/container IDs and BBC's
ngasCookiePrompt) are eligible for visual hiding. No Accept/Reject buttons are clicked and no consent choice is written. - Empty ad wrappers and their reserved-height/padding/advertisement labels collapse too, stopping before useful sibling content. Normal overflow-based cookie scroll locks are released while hiding the overlay and restored when paused.
- Toolbar badge: green ON = saved and active; gray OFF = paused; amber … = analyzing; red ! = failed. Tooltip includes actual hidden element count.
- Pause / Resume controls the current page type across tabs. The header switch disables the whole extension. Both restore hidden elements immediately.
- Re-analyze replaces this template's rules while preserving disabled rules that are still identified. Failed, malformed, or stale responses leave existing rules unchanged.
- Uncheck a rule in Hidden elements to keep those elements visible.
- Forget this page type removes its saved rules, restores the page, and permits a fresh analysis.
- Removing the API key leaves saved rules usable offline.
Template reuse
Keys combine exact origin, policy version, page kind, normalized route family, and a stable main-shell marker. Homepage, article, product, search, listing, and generic routes stay separate. Article/product leaves and date/ID segments are normalized; tracking query parameters do not fragment the cache.
Examples: BBC /news/articles/cabc123 and /news/articles/cdef456 share a profile if their shells match. /, /news, and a different article shell do not. Generic short routes such as /news/world and /news/business stay separate. No global cross-domain rules.
This is a conservative heuristic, not perfect template recognition. Different route families may need separate initial analyses; different layouts sharing the same shell may share a profile. Every selector is revalidated against the current DOM before hiding. Stable data-testid, data-component, IDs, and classes are used; no positional selectors or AI-generated CSS. Randomized class-only pages may yield no safely targetable candidates. There is no periodic cache expiry or automatic paid retry. Re-analyze manually after site redesigns.
Privacy and safety
- API key stays in local extension storage, not encrypted and not synced. Chrome restricts storage access to trusted extension contexts. It is never sent to page content scripts, websites, logs, or repository source.
- Only extension background code calls the selected provider's fixed endpoint. Popup-origin checks protect settings/manual analysis. Page-visit requests are validated and require the user's saved automatic-mode opt-in.
- Each analysis sends up to 60 bounded candidate descriptions (tag, structural signals, short text, position, match count). No full URL, query string, page title, main article body, form values, cookies, or raw HTML is sent. Email-like and long numeric strings in snippets are redacted, but this is not a guarantee of anonymization. Do not analyze sensitive pages if sending snippets to your selected provider is inappropriate.
- Jev receives typed keep/ad/promotion/newsletter/social/cookie/uncertain choices. Page text is untrusted evidence, not instructions. The model cannot emit code or selectors. Responses are validated for type, completeness, valid categories, and numeric ranges. Uncertain results remain visible. Where provided, selected-choice probability and TypeSafe confidence must both be at least 0.9; either failing keeps the element visible. Invalid/non-finite values reject the response. Gateway answers without confidence still work. These are conservative operational thresholds, not calibrated accuracy claims.
- Main content, navigation, ordinary forms, login/payment/security, and paywalls are protected. Cookie-dialog headings and checkbox controls may hide with their containing overlay, but sensitive inputs still block hiding. No links are clicked, consent granted, requests blocked, or access restrictions bypassed. Hiding cookie dialogs is not rejection or tracking protection; use Pause to access consent choices. Hiding ads does not prevent their network/tracking activity.
- Hidden DOM nodes are not deleted. A temporary attribute, extension-owned stylesheet, and reversible inline display overrides remove occupied space (including inline
!important). Original style values/priorities are restored; unrelated site style changes are preserved. - Late-loaded elements are rechecked through a bounded/debounced mutation observer. SPA navigation restores the previous rules and resolves the new template. In-flight analyses are discarded after navigation or concurrent edits.
- Cross-origin iframe contents and shadow DOM are not traversed. Identified consent iframe/container selectors are reusable across numeric session IDs. Native dialogs and ordinary embedded forms remain visible. Scroll unlocking does not run behind other visible modals; non-overflow locks (e.g. fixed-body/inert/custom event interception) may still require site-specific handling.
- HTTP(S) access is required to restore saved rules automatically on later visits. Internal browser pages, extension stores, PDFs and file URLs are not supported.
Development
bun install
bun run check
bun run build
bun run build:firefox
Use bun run dev for WXT development mode. No background server is needed for unpacked production builds.
The normal checks use synthetic fixtures and need no API key. Optional live smoke test: set JEV_KEY or TYPESAFE_API_KEY for TypeSafe AI, or AI_GATEWAY_API_KEY for Gateway, then run bun scripts/smoke-jev.ts. Do not set both provider families; conflicting direct-key aliases are rejected too. Never pass a key as a command-line argument. The smoke sends synthetic inputs only and incurs a small API charge. Never commit .env files, API keys, browser profiles, or real browsing data.
Outputs: .output/chrome-mv3/ and .output/firefox-mv2/. bun run zip packages Chromium.
Architecture: lib/page-context.ts identifies templates, lib/dom.ts extracts candidates and applies reversible rules, lib/jev.ts implements Gateway evaluation-model v4 and TypeSafe System One with shared choice validation, entrypoints/background.ts owns credentials/cache/actions, entrypoints/cleaner.content.ts handles page lifecycle, and entrypoints/popup/ provides controls. Settings and profiles use independent storage keys to avoid unrelated-tab write loss.
License
MIT.
More projects by Kitze
Apps & tools
|
gifs.so Search, copy, and download reaction GIFs. |
Glink Feedback, roadmaps, changelogs, and discussions. |
Benji Tasks, habits, calendar, health, and routines in one place. |
|
Perkz Sell and manage access to private GitHub repositories. |
JustWrite Distraction-free writing sprints for macOS, with time or word-count goals. |
Releaseflow App updates and downloads. |
|
Passlock A macOS password manager with time locks and unlock challenges. |
||
Open source
|
Skillbox A self-hosted, versioned skills library for AI agents. |
Unclutter Remove page clutter with AI-powered, reusable browser rules. |
PageGrade Grade page clarity, writing, and on-page SEO. |
|
Council Let your coding agents deliberate together before making a plan. |
CodexMaxx Manage Codex accounts, usage, and active sessions on macOS. |
React Hanger A collection of useful React hooks. |
|
React Genie Animate React elements as they enter the viewport. |
MobX Router A simple router for MobX and React apps. |
|
All projects · GitHub · Follow on X · YouTube
