Zero-dependency disposable/burner email detector
Project description
burner-bouncer
Detect disposable / burner email addresses instantly. Zero runtime dependencies. Ships as both an npm package (TypeScript, ESM + CJS) and a Python package, backed by a single shared blocklist of 500+ real disposable-email domains.
Why Burner Bouncer?
- No external requests — the blocklist is bundled at install time; nothing is phoned home at runtime.
- Dual ecosystem — identical API surface in JavaScript/TypeScript and Python so you can use the same library across your stack.
- Always typed — full TypeScript types and a typed Python dataclass result, no
anyguessing. - Tiny — the entire JS bundle is under 10 kB gzipped.
- 500+ domains — covers Mailinator, Guerrilla Mail, YOPmail, 10MinuteMail, Temp-Mail, Maildrop, and hundreds more.
JavaScript / TypeScript
Installation
npm install burner-bouncer
# or
pnpm add burner-bouncer
# or
yarn add burner-bouncer
Usage
import { isDisposable, check, checkMany, getDomain, getBlocklist } from 'burner-bouncer';
// Quick boolean check
isDisposable('user@mailinator.com'); // true
isDisposable('user@gmail.com'); // false
isDisposable('notanemail'); // false
// Full result object
check('test@mailinator.com');
// {
// email: 'test@mailinator.com',
// domain: 'mailinator.com',
// isDisposable: true,
// reason: 'blocklist'
// }
check('user@gmail.com');
// { email: 'user@gmail.com', domain: 'gmail.com', isDisposable: false, reason: null }
check('notanemail');
// { email: 'notanemail', domain: null, isDisposable: false, reason: 'invalid_email' }
// Batch check
checkMany(['a@mailinator.com', 'b@gmail.com', 'bad']);
// [ { isDisposable: true, ... }, { isDisposable: false, ... }, { reason: 'invalid_email', ... } ]
// Extract domain
getDomain('User@YopMail.COM'); // 'yopmail.com'
// Retrieve the full sorted blocklist
getBlocklist(); // ['10minutemail.com', 'guerrillamail.com', ...]
JS API Reference
| Function | Signature | Description |
|---|---|---|
isDisposable |
(email: string) => boolean |
Returns true if the email's domain is on the blocklist. Returns false for invalid emails. |
check |
(email: string) => CheckResult |
Returns a full result object with email, domain, isDisposable, and reason. |
checkMany |
(emails: string[]) => CheckResult[] |
Runs check on each email and returns an array of results. |
getDomain |
(email: string) => string | null |
Extracts and lowercases the domain portion. Returns null for invalid emails. |
getBlocklist |
() => string[] |
Returns a sorted copy of all blocked domains. |
CheckResult interface
interface CheckResult {
email: string;
domain: string | null;
isDisposable: boolean;
reason: 'blocklist' | 'invalid_email' | null;
}
| Field | Type | Description |
|---|---|---|
email |
string |
The original input email. |
domain |
string | null |
The lowercased domain, or null if the email is invalid. |
isDisposable |
boolean |
Whether the domain appears on the blocklist. |
reason |
'blocklist' | 'invalid_email' | null |
'blocklist' if flagged, 'invalid_email' if malformed, null if clean. |
Python
Installation
pip install burner-bouncer
Usage
from burner_bouncer import is_disposable, check, check_many, get_domain, get_blocklist
# Quick boolean check
is_disposable("user@mailinator.com") # True
is_disposable("user@gmail.com") # False
is_disposable("notanemail") # False
# Full result dataclass
result = check("test@mailinator.com")
result.email # 'test@mailinator.com'
result.domain # 'mailinator.com'
result.is_disposable # True
result.reason # 'blocklist'
result.to_dict()
# {'email': 'test@mailinator.com', 'domain': 'mailinator.com',
# 'is_disposable': True, 'reason': 'blocklist'}
check("user@gmail.com").reason # None
check("notanemail").reason # 'invalid_email'
# Batch check
results = check_many(["a@mailinator.com", "b@gmail.com", "bad"])
# Extract domain
get_domain("User@YopMail.COM") # 'yopmail.com'
# Retrieve the full sorted blocklist
get_blocklist() # ['10minutemail.com', 'guerrillamail.com', ...]
Python API Reference
| Function | Signature | Description |
|---|---|---|
is_disposable |
(email: str) -> bool |
Returns True if the email's domain is on the blocklist. |
check |
(email: str) -> CheckResult |
Returns a CheckResult dataclass instance. |
check_many |
(emails: List[str]) -> List[CheckResult] |
Runs check on each email. |
get_domain |
(email: str) -> Optional[str] |
Extracts and lowercases the domain. Returns None for invalid emails. |
get_blocklist |
() -> List[str] |
Returns a sorted list of all blocked domains. |
CheckResult dataclass
@dataclass
class CheckResult:
email: str
domain: Optional[str]
is_disposable: bool
reason: Optional[str] # 'blocklist' | 'invalid_email' | None
def to_dict(self) -> dict: ...
| Field | Type | Description |
|---|---|---|
email |
str |
The original input email. |
domain |
Optional[str] |
The lowercased domain, or None if the email is invalid. |
is_disposable |
bool |
Whether the domain appears on the blocklist. |
reason |
Optional[str] |
'blocklist' if flagged, 'invalid_email' if malformed, None if clean. |
Repository Structure
burner-bouncer/
├── data/
│ └── disposable_domains.json # Shared blocklist (500+ domains)
├── js/
│ ├── src/
│ │ └── index.ts # JS/TS library source
│ ├── tests/
│ │ └── index.test.ts # Jest test suite
│ ├── jest.config.js
│ ├── package.json
│ └── tsconfig.json
├── python/
│ ├── burner_bouncer/
│ │ └── __init__.py # Python library source
│ ├── tests/
│ │ └── test_burner_bouncer.py
│ └── pyproject.toml
├── .github/
│ └── workflows/
│ ├── ci.yml # CI: test JS + Python on every push/PR
│ └── publish.yml # Publish to npm + PyPI on version tag
├── .gitignore
├── LICENSE
└── README.md
Contributing
- Fork the repository and create a feature branch.
- Add domains to
data/disposable_domains.json(keep it sorted and deduplicated). - Run the test suites:
cd js && npm testandcd python && pytest. - Open a pull request — CI will run automatically.
License
MIT © 2025 burner-bouncer contributors
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file burner_bouncer-1.0.0.tar.gz.
File metadata
- Download URL: burner_bouncer-1.0.0.tar.gz
- Upload date:
- Size: 4.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
85eb93b48683f301970897d567d60ee3969bd132b9c7500ec9e3449f6ffdcc77
|
|
| MD5 |
7219635235321501aa2cc7006f4ef3af
|
|
| BLAKE2b-256 |
b124e9e11f0ce8aac9ac652b17e79c57b96cca7000e55d42d1acda7b0f4a2b62
|
Provenance
The following attestation bundles were made for burner_bouncer-1.0.0.tar.gz:
Publisher:
publish.yml on grocerysushi/burner-bouncer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
burner_bouncer-1.0.0.tar.gz -
Subject digest:
85eb93b48683f301970897d567d60ee3969bd132b9c7500ec9e3449f6ffdcc77 - Sigstore transparency entry: 1438771988
- Sigstore integration time:
-
Permalink:
grocerysushi/burner-bouncer@3259613122495d8aee960f8b9c3134dde69d57cf -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/grocerysushi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3259613122495d8aee960f8b9c3134dde69d57cf -
Trigger Event:
push
-
Statement type:
File details
Details for the file burner_bouncer-1.0.0-py3-none-any.whl.
File metadata
- Download URL: burner_bouncer-1.0.0-py3-none-any.whl
- Upload date:
- Size: 4.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
479eeb2c0c85760659dc6e38b71d57e432f17bd915fd7e3bcb414923f0213a07
|
|
| MD5 |
6196c4f02a10e4669c34d3f2522ba66b
|
|
| BLAKE2b-256 |
f57249121be8e05d81ccac4cfa4e3e6e40240441df75d1253385a78d8020640a
|
Provenance
The following attestation bundles were made for burner_bouncer-1.0.0-py3-none-any.whl:
Publisher:
publish.yml on grocerysushi/burner-bouncer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
burner_bouncer-1.0.0-py3-none-any.whl -
Subject digest:
479eeb2c0c85760659dc6e38b71d57e432f17bd915fd7e3bcb414923f0213a07 - Sigstore transparency entry: 1438772004
- Sigstore integration time:
-
Permalink:
grocerysushi/burner-bouncer@3259613122495d8aee960f8b9c3134dde69d57cf -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/grocerysushi
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3259613122495d8aee960f8b9c3134dde69d57cf -
Trigger Event:
push
-
Statement type: