Privacy-first, local-first Gmail subscription cleaner
QuiteInbox helps you find, manage, and unsubscribe from email subscriptions in your Gmail inboxβwithout sending your data to any third-party server.
- Local-First Architecture: All processing happens in your browser. No server-side storage of your email content or metadata.
- Smart Subscription Detection: Automatically identifies subscriptions using RFC 8058 headers and heuristics
- Multiple Unsubscribe Methods:
- One-click unsubscribe (RFC 8058 compliant)
- HTTP link unsubscribe
- Mailto unsubscribe
- Bulk Actions: Unsubscribe from multiple senders at once
- Email Cleanup: Archive or delete old subscription emails
- Safety First: Protected keywords prevent accidental deletion of important emails (banking, receipts, OTPs, etc.)
- Activity Log: Local audit trail of all actions performed
- Dark Mode: Built-in light/dark theme support
- Export/Import: Export your settings and action logs as JSON
- β Store your email content on any server
- β Send your email metadata to third parties
- β Include analytics or telemetry
- β Track your usage
- β Sell or share your data
- β Store minimal metadata locally in IndexedDB (sender groups, action logs, settings)
- β Use Google OAuth with PKCE for secure authentication
- β Request only the Gmail permissions you explicitly authorize
- β Provide full transparency as open-source software
All data is stored locally in your browser using IndexedDB:
- Sender Groups: Sender name, domain, message count, unsubscribe method, safety flags
- Action Log: Timestamped record of actions (unsubscribe, archive, delete) with results
- Settings: Theme preference, protected keywords/domains, scope permissions
- Scan Checkpoint: Last scan time and processed message IDs (for resumable scans)
No email content or message bodies are ever stored.
QuiteInbox uses Google OAuth 2.0 with PKCE (Proof Key for Code Exchange) for secure authentication.
gmail.readonly: Read email headers and metadata to find subscriptions and their unsubscribe methods
gmail.modify: Archive, trash, or delete old subscription emails; create Gmail filtersgmail.send: Send unsubscribe emails directly via Gmail API (alternative to opening mail client)
You can enable/disable optional scopes in the onboarding flow and in Settings.
- Node.js 20.19+ or 22.12+
- npm or yarn
- A Google Cloud project with OAuth 2.0 credentials
git clone https://github.com/your-username/quiteinbox-app.git
cd quiteinbox-appnpm installβ IMPORTANT: Create a "Desktop app" OAuth client (NOT "Web application")
Quick Setup:
- Go to Google Cloud Console
- Create a new project (or use existing) and enable the Gmail API
- Navigate to APIs & Services > Credentials
- Click "Create Credentials" > "OAuth client ID"
- Select "Desktop app" from the Application type dropdown
- Name it: "QuiteInbox Desktop Client"
- Click "Create"
- Copy the Client ID (Client Secret is optional but can be included if shown)
Why "Desktop app" and not "Web application"?
- Desktop app clients work seamlessly with PKCE and localhost redirects
- No need to configure authorized redirect URIs or JavaScript origins
- Simpler setup, fewer configuration errors
- Equally secure (PKCE provides the cryptographic protection)
Alternative: Using "Web application" type If you prefer or already have a "Web application" OAuth client:
- You MUST add to "Authorized redirect URIs":
http://localhost:5173/oauth/callback - You MUST add to "Authorized JavaScript origins":
http://localhost:5173
π Detailed Instructions: See docs/OAUTH_SETUP.md for step-by-step guide with screenshots and troubleshooting.
Security Note: We use PKCE (Proof Key for Code Exchange), which provides cryptographic protection without requiring client secrets. The code_verifier/code_challenge pair is what protects the OAuth flow.
Create a .env file in the project root:
cp .env.example .envEdit .env and add your Google OAuth client ID:
VITE_GOOGLE_CLIENT_ID=your_client_id_here.apps.googleusercontent.com
That's all you need! No secret required.
npm run devOpen http://localhost:5173 in your browser.
Click "Sign in with Google" and authorize the requested Gmail scopes.
- Select a time range (3/6/12 months, or all time)
- Click "Start Scan"
- QuiteInbox will scan your inbox for subscriptions
- View all detected subscription senders
- Each sender shows:
- Display name and domain
- Message count
- Unsubscribe method (one-click, http, mailto, unknown)
- Safety status (protected/not protected)
- Click on a sender to view details
- Click "Unsubscribe" to execute the unsubscribe action
- Or select multiple senders and use bulk actions
- From a sender's detail page, choose cleanup options:
- Archive all messages
- Delete messages older than X days
- Keep only the last N messages
- See a timestamped log of all actions performed
- Export the log as JSON for your records
src/
βββ lib/
β βββ auth/ # OAuth PKCE flow
β βββ api/ # Gmail API client
β βββ parsers/ # Header parsing (List-Unsubscribe, List-Id)
β βββ grouping/ # Message grouping engine
β βββ actions/ # Action runners (unsubscribe, cleanup, filters)
β βββ storage/ # IndexedDB storage layer (Dexie)
β βββ utils/ # Utility functions
βββ components/
β βββ ui/ # shadcn/ui components
βββ routes/ # React Router pages
βββ stores/ # Zustand state management
βββ types/ # TypeScript type definitions
βββ test/ # Test setup
npm run dev # Start development server
npm run build # Build for production
npm run preview # Preview production build
npm run test # Run tests
npm run lint # Run ESLintQuiteInbox uses Vitest for unit testing:
npm run test # Run all tests
npm run test:ui # Run tests with UIKey test suites:
src/lib/parsers/headers.test.ts- Header parsing logicsrc/lib/grouping/engine.test.ts- Grouping and filtering logic
QuiteInbox defends against:
- Malicious unsubscribe links: Verifies HTTPS for one-click unsubscribe; warns if host doesn't match sender domain
- Accidental data loss: Protected keywords prevent bulk deletion of important emails
- CSRF attacks: Uses PKCE with state parameter for OAuth flow
- XSS attacks: Content Security Policy hardened; uses React's built-in XSS protection
- QuiteInbox cannot verify if an unsubscribe link is legitimateβonly that it uses HTTPS and matches expected patterns
- One-click unsubscribe sends a POST request; we accept 2xx/3xx responses per RFC 8058
- Protected keywords are heuristic-based and may not catch all sensitive emails
Please report security vulnerabilities to: [[email protected]]
Yes, QuiteInbox is 100% free and open-source. No paid plans, no upsells.
Not currently. QuiteInbox uses the Gmail API and is designed specifically for Gmail accounts. IMAP support may be added in the future.
All data is stored locally in your browser's IndexedDB. If you clear your browser data or uninstall QuiteInbox, the data is permanently deleted. You can export your data before doing so.
Each device stores its own local data. There's no sync between devices. You can export/import settings and action logs manually.
Yes, as long as your Workspace admin allows third-party OAuth apps and the Gmail API.
- Bulk filter creation
- Keyboard shortcuts
- Advanced filtering and search
- Improved ESP relay handling (SendGrid, Mailchimp)
- IMAP support for non-Gmail accounts
- Optional minimal proxy for CORS-blocked one-click URLs
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Submit a pull request
This project is licensed under the Apache 2.0 License - see the LICENSE file for details.
- Built with React, TypeScript, and Vite
- UI components from shadcn/ui and Radix UI
- State management with Zustand
- Local storage with Dexie.js
- Styled with Tailwind CSS
If you find QuiteInbox useful, please:
- β Star this repository
- π Report bugs via GitHub Issues
- π‘ Suggest features via GitHub Discussions
QuiteInbox β’ Privacy-first subscription management β’ Built with β€οΈ for your inbox