TreeMap
무료 오픈소스 디스크 사용량 시각화 도구로, 사각형 트리맵·중복 파일 탐색·디스크 가득 예측·정리 시 파일을 휴지통으로만 이동한다
See your inbox as a bubble map of senders, then unsubscribe in a click. Google Takeout .mbox or Gmail metadata — runs entirely in your browser.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
See your email as a living map: you in the centre, every newsletter, service and person that writes to you as a floating bubble. Spot the lists you never open, unsubscribe, and pop them off the map.
Live: https://inbox-bubble-map.vercel.app · Status: v0.8 — sign in once and stay signed in; your map opens instantly from this device and only new mail syncs. Read and clean mail from the map, in Arabic, French or English.
Author: Oussama EL HADJI. Part of the Bosaj ideas portfolio (sibling repo: dual_portfolio_hub).README 전문 보기 ↗See your email as a living map: you in the centre, every newsletter, service and person that writes to you as a floating bubble. Spot the lists you never open, unsubscribe, and pop them off the map.
Live: https://inbox-bubble-map.vercel.app · Status: v0.9 — Gmail and Outlook stay signed in, your whole mailbox loads in the background (newest first), the map opens instantly from this device and only new mail syncs. Read and clean mail from the map, in Arabic, French or English.
Author: Oussama Elhadji (@Bosaj) [email protected].
People lose track of which newsletters and services email them. Bulk-unsubscribe tools show long lists. A living bubble map makes the mess visible at a glance, and popping a bubble when you unsubscribe makes cleaning up feel good.
| Encoding | Meaning |
|---|---|
| Bubble size | number of messages from that sender (area ∝ count) |
| Distance from "You" | how long ago they last wrote (log scale; rings at 7 days, 30 days, 1 year) |
| Colour | 🟠 newsletters & promos (has List-Unsubscribe / List-Id / bulk) · 🔵 automated (no-reply, alerts, receipts) · 🟢 people |
Only three colours are used on purpose. In an all-pairs chart like this, three hues are the most that stay distinguishable for every reader, colour-blind included (validated with OKLab ΔE checks). The legend chips double as filters, every bubble has a label or tooltip, and a full table view is one click away.
| Provider | How | What is read |
|---|---|---|
| Gmail | Google sign-in (gmail.modify) or an app password | map, read, archive, trash, spam, mark read, unsubscribe by email |
| Outlook / Hotmail / Microsoft 365 | Microsoft sign-in (Mail.ReadWrite) | map, read, archive, trash, junk, mark read |
| Yahoo, iCloud, AOL, GMX, Zoho, Fastmail, any IMAP | app password through the relay | map, read, archive, trash, spam, mark read |
| Any export | drop a .mbox (Google Takeout, Thunderbird, Apple Mail) or .eml | map only (read-only) |
| Demo | fictional inbox | — |
Outlook.com switched off IMAP app passwords in September 2024, which is why Outlook uses Microsoft sign-in.
/api/logo proxy (cached 30 days at the CDN, fixed icon sources only), so no icon service ever sees your sender list tied to your IP. Logos can be switched off in Display.prefers-reduced-motion./api/google/*: the code exchange runs on the server with PKCE, and the refresh token is sealed with AES-256-GCM into an httpOnly, Secure, SameSite=Lax cookie scoped to /api/google. The browser only receives short-lived access tokens and calls the Gmail API directly. Nothing is stored server-side. Without GOOGLE_CLIENT_SECRET the app falls back to the popup sign-in for the current tab./api/imap, a Vercel Function. Per request it connects over TLS, does one thing (read headers, list a sender, open one message, or apply one confirmed action), returns and disconnects. Your password stays in the tab and is sent with each request; the relay never stores or logs credentials or mail.Cache-Control: no-store. Trash and archive use the account's special-use folders (RFC 6154); nothing is expunged./api/unsubscribe): POSTs only the standard List-Unsubscribe=One-Click body to an https URL from your own headers, on port 443, to a public address it checked and pinned. No cookies, no referrer, no redirects followed, 8-second timeout, rate-limited, nothing logged.default-src 'none'; img-src data: cid:), so remote images, fonts and forms are blocked.https: and mailto: links are accepted./api/logo?d=domain), which fetches them from fixed icon services and caches them. Your browser never contacts an icon service, and the proxy never connects to the sender's own server, so it can't be used for SSRF. People and personal addresses never get logo requests.api/imap.ts IMAP relay (Vercel Function): headers / list / ids / body (postal-mime) / act; SSRF guard, rate limits, imapflow
api/unsubscribe.ts RFC 8058 one-click unsubscribe relay (https only, pinned address, no redirects)
api/google/*.ts stay-signed-in Google OAuth: login (PKCE), callback, session (token / log out)
api/_lib/session.ts AES-256-GCM sealed cookies, origin checks
api/logo.ts company icon proxy (fixed sources, type/size checks, 30-day CDN cache)
api/_lib/net.ts shared hostname / private-address guards (not a route)
src/lib/display.ts colour modes, filters, selection presets, logo domains, initials
src/lib/headers.ts RFC 2047 decoding, From / List-Unsubscribe / Date parsing
src/lib/mbox.ts streaming mbox reader (header blocks only, folding, CRLF)
src/lib/parse.worker.ts Web Worker: File.stream() → parser, progress events
src/lib/store.ts IndexedDB cache of a signed-in mailbox (memory fallback)
src/lib/account.ts client for the server session (status, tokens, log out)
src/lib/mailbox.ts Mailbox interface, reader document (sandbox + CSP), demo mailbox, map updates after actions
src/lib/gmail.ts Gmail API client (GIS token, paging, retry), read bodies, batchModify / trash / send
src/lib/outlook.ts Microsoft Graph client (MSAL v5, silent refresh), read bodies, JSON $batch moves
src/lib/providers.ts provider presets + IMAP relay client and mailbox
src/i18n.tsx English, French and Arabic strings, plural rules, locale formats
src/lib/aggregate.ts grouping, categories, months, insights, CSV / Gmail filters / Sieve
src/lib/layout.ts scales + shared d3-force setup (static layout for tests and first frame)
src/components/ BubbleMap (physics, pins, lasso, group drag), MapControls, MailUI (messages, reader, bulk actions, unsubscribe), LangSwitch, ConnectDialog, Insights…
63 Vitest tests cover colour modes, filters, selection presets, the logo proxy, header decoding, chunk-independent mbox parsing, aggregation and insights, exports, the layout, the Gmail and Graph clients (paging, retries, body decoding, batchModify / trash / $batch moves, expired tokens), the IMAP relay (validation, SSRF, rate limits, origin check, special-use folders), the unsubscribe relay (URL checks, pinning, private targets, origin, rate limit), the reader CSP, the demo mailbox, translations (every key in all three languages) and the app flows (read a message, archive a sender, switch to Arabic). GREENMAIL=1 npm test also runs the relay's real imapflow code (list, open, mark read, move to Trash/Archive) against a local GreenMail IMAP server.
npm install
npm run dev # http://localhost:5173 (the dev server also serves /api/imap)
npm test
npm run build
Optional sign-ins: copy .env.example to .env and set VITE_GOOGLE_CLIENT_ID and/or VITE_MS_CLIENT_ID. Every step is in that file. Without them, Gmail still works through an app password, and Outlook users are guided to an .mbox export.
gmail.modify and Mail.ReadWrite because the app archives, trashes and marks mail. Fetch a body only when the user opens that message, change mail only after a confirmation, and never delete permanently.src/i18n.tsx in all three languages; the translation test fails if a key is missing.src/lib/lib.test.ts, src/lib/v04.test.ts).Ground rules: keep this README in sync with reality; write tests for anything correctness-critical; never commit secrets; follow Conventional Commits (see CONTRIBUTING.md).
Proprietary & Commercial Software License — All Rights Reserved © 2026 Oussama Elhadji (@Bosaj) <[email protected]>.
Unauthorized copying, distribution, resale, or reverse engineering is strictly prohibited. See LICENSE for full legal terms.
/api/unsubscribe when the sender supports it; otherwise Gmail sends the mailto: unsubscribe email for you, or the sender's page opens. Top cleanup picks ranks by volume × unread × unsubscribable..xml: skip inbox and mark read), Sieve rules (Fastmail, Proton, Posteo, cPanel…), and the map as a PNG.