{"_id":"bloommx","_rev":"5-2ac69dd70cd0139c211f2e4985311c73","name":"bloommx","dist-tags":{"latest":"1.0.3"},"versions":{"0.0.1":{"name":"bloommx","version":"0.0.1","keywords":["oidc","trusted-publishing","setup"],"_id":"bloommx@0.0.1","maintainers":[{"name":"rafaeelaudibert","email":"rafaeelaudibert@gmail.com"}],"dist":{"shasum":"71429ba9e407c805e7307fa4a6827fce0d17f955","tarball":"https://registry.npmjs.org/bloommx/-/bloommx-0.0.1.tgz","fileCount":2,"integrity":"sha512-MC+g6djs8wGJo8So/V5mK89jVxalwtK5PTc8C4XI7p7DUd1izWqz3NwnidYkV/7MQw+gYyCL8KXRJlQsBCDsZA==","signatures":[{"sig":"MEUCIFVVYxcJsRjWmfJR9RZ1/xAT5mcYRWO5jwUg3Ov6ZJ3UAiEA66w95pYNuk1QetKSdTv9HaZtBVBYLvLlhB/AgHAQZq0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1991},"_npmUser":{"name":"rafaeelaudibert","email":"rafaeelaudibert@gmail.com"},"_npmVersion":"11.6.2","description":"OIDC trusted publishing setup package for bloommx","directories":{},"_nodeVersion":"24.12.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/bloommx_0.0.1_1771970050047_0.11430539022716335","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"bloommx","version":"1.0.0","keywords":["email","free-email","disposable","bloom-filter","domain","validation"],"author":"","license":"MIT","_id":"bloommx@1.0.0","maintainers":[{"name":"rafaeelaudibert","email":"rafaeelaudibert@gmail.com"}],"dist":{"shasum":"2b7859530a05b192b15bddb7bf8c308ea7e26df3","tarball":"https://registry.npmjs.org/bloommx/-/bloommx-1.0.0.tgz","fileCount":23,"integrity":"sha512-FARvP37ZiNv/D4Ap8VJPQkkCIquTDWUji054EiuYlz230iU4hBvab2oLpQOIFYA0U2RnsoPyKpG3LnABalP4SQ==","signatures":[{"sig":"MEYCIQD9SPvbh3saWDINGCzz7+bGDiQCCwL5zx1MT8eK3ujmMAIhAPQURuBUILYqTnH38oeuGxZz8eMG+a+TFDg9FNO9KJTm","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":90351},"type":"module","exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"},"./micro":{"types":"./dist/src/micro.d.ts","import":"./dist/src/micro.js"},"./compact":{"types":"./dist/src/compact.d.ts","import":"./dist/src/compact.js"},"./precise":{"types":"./dist/src/precise.d.ts","import":"./dist/src/precise.js"},"./balanced":{"types":"./dist/src/balanced.d.ts","import":"./dist/src/balanced.js"}},"gitHead":"76930ee7e0229ad9c19aa3dabdf37106d407c403","scripts":{"test":"bun test","build":"bun run generate && tsc","release":"bun run build && npm publish --provenance --access public","version":"changeset version","generate":"bun run scripts/generate.ts","changeset":"changeset"},"_npmUser":{"name":"rafaeelaudibert","email":"rafaeelaudibert@gmail.com"},"_npmVersion":"11.6.2","description":"Lightweight free email domain checker via Bloom filter","directories":{},"sideEffects":false,"_nodeVersion":"24.12.0","_hasShrinkwrap":false,"devDependencies":{"@types/bun":"^1.2.4","typescript":"^5.7.3","bloomfilter":"^1.0.0","@changesets/cli":"^2.29.4","free-email-domains":"^1.2.14","@changesets/changelog-github":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/bloommx_1.0.0_1771971317204_0.5401013606963132","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"bloommx","version":"1.0.1","keywords":["email","free-email","disposable","bloom-filter","domain","validation"],"author":"","license":"MIT","_id":"bloommx@1.0.1","maintainers":[{"name":"rafaeelaudibert","email":"rafaeelaudibert@gmail.com"}],"dist":{"shasum":"bbd8b679977b0313d4a6653e0c82b66d9b9c61ad","tarball":"https://registry.npmjs.org/bloommx/-/bloommx-1.0.1.tgz","fileCount":23,"integrity":"sha512-R0Ueq2am4mb7Y4gLdFyPbjftvW/uW7F0aP7nf2Q6zdwCDmC+cJ4HfTd3Vc/zNzAvIM9fhqwhXVMaAE2h0a06pg==","signatures":[{"sig":"MEYCIQCIWOBE8Y6zYeJJPQ0T+IeOJ/y9vDBxsKZ7eMeHq5mqhQIhAKEBSgkIy0660wqiI33hZeT8vtTSJi3WhUETXrmrz02H","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":90420},"main":"./dist/src/index.js","type":"module","types":"./dist/src/index.d.ts","exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"},"./micro":{"types":"./dist/src/micro.d.ts","import":"./dist/src/micro.js"},"./compact":{"types":"./dist/src/compact.d.ts","import":"./dist/src/compact.js"},"./precise":{"types":"./dist/src/precise.d.ts","import":"./dist/src/precise.js"},"./balanced":{"types":"./dist/src/balanced.d.ts","import":"./dist/src/balanced.js"}},"gitHead":"f32dbb8b3c09179b67baaea5d9ff1776ba6d233a","scripts":{"test":"bun test","build":"bun run generate && tsc","release":"bun run build && npm publish --provenance --access public","version":"changeset version","generate":"bun run scripts/generate.ts","changeset":"changeset"},"_npmUser":{"name":"rafaeelaudibert","email":"rafaeelaudibert@gmail.com"},"_npmVersion":"11.6.2","description":"Lightweight free email domain checker via Bloom filter","directories":{},"sideEffects":false,"_nodeVersion":"24.12.0","_hasShrinkwrap":false,"devDependencies":{"@types/bun":"^1.2.4","typescript":"^5.7.3","bloomfilter":"^1.0.0","@changesets/cli":"^2.29.4","free-email-domains":"^1.2.14","@changesets/changelog-github":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/bloommx_1.0.1_1771975173716_0.9548717281130035","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"bloommx","version":"1.0.2","keywords":["email","free-email","disposable","bloom-filter","domain","validation"],"author":"","license":"MIT","_id":"bloommx@1.0.2","maintainers":[{"name":"rafaeelaudibert","email":"rafaeelaudibert@gmail.com"}],"dist":{"shasum":"eaf291f9d2dd250af3ee4ee1afe9019a65052682","tarball":"https://registry.npmjs.org/bloommx/-/bloommx-1.0.2.tgz","fileCount":34,"integrity":"sha512-TPcDe1XFClsbL17fZ+EDi4jbYUxrlsRi+5XhfN4Ok7v1NxhKPgJ4OhhkKz8D9WyyGfcvFOW1mSsY5RmSDcVLLg==","signatures":[{"sig":"MEUCIQD4oIL4XpFDkRcsez1mofWp1rlASE+/7whJPkOg1ce7wgIgQ6h84E7YjBcbEET4dNGBa5M0sIiG13nu9XslP2ILC7I=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":135675},"main":"./dist/cjs/src/index.js","type":"module","types":"./dist/src/index.d.ts","exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js","require":"./dist/cjs/src/index.js"},"./micro":{"types":"./dist/src/micro.d.ts","import":"./dist/src/micro.js","require":"./dist/cjs/src/micro.js"},"./compact":{"types":"./dist/src/compact.d.ts","import":"./dist/src/compact.js","require":"./dist/cjs/src/compact.js"},"./precise":{"types":"./dist/src/precise.d.ts","import":"./dist/src/precise.js","require":"./dist/cjs/src/precise.js"},"./balanced":{"types":"./dist/src/balanced.d.ts","import":"./dist/src/balanced.js","require":"./dist/cjs/src/balanced.js"}},"gitHead":"05b70271c8a425e86847f697ff08720781f19296","scripts":{"test":"bun test","build":"bun run generate && tsc && tsc -p tsconfig.cjs.json && cp cjs.package.json dist/cjs/package.json","release":"bun run build && npm publish --provenance --access public","version":"changeset version","generate":"bun run scripts/generate.ts","changeset":"changeset"},"_npmUser":{"name":"rafaeelaudibert","email":"rafaeelaudibert@gmail.com"},"_npmVersion":"11.6.2","description":"Lightweight free email domain checker via Bloom filter","directories":{},"sideEffects":false,"_nodeVersion":"24.12.0","_hasShrinkwrap":false,"devDependencies":{"@types/bun":"^1.2.4","typescript":"^5.7.3","bloomfilter":"^1.0.0","@changesets/cli":"^2.29.4","free-email-domains":"^1.2.14","@changesets/changelog-github":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/bloommx_1.0.2_1771995443220_0.2393970525478002","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"bloommx","version":"1.0.3","description":"Lightweight free email domain checker via Bloom filter","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./micro":{"types":"./dist/micro.d.ts","import":"./dist/micro.js","require":"./dist/micro.cjs"},"./compact":{"types":"./dist/compact.d.ts","import":"./dist/compact.js","require":"./dist/compact.cjs"},"./balanced":{"types":"./dist/balanced.d.ts","import":"./dist/balanced.js","require":"./dist/balanced.cjs"},"./precise":{"types":"./dist/precise.d.ts","import":"./dist/precise.js","require":"./dist/precise.cjs"}},"sideEffects":false,"scripts":{"generate":"bun run scripts/generate.ts","build":"bun run generate && tsup","test":"bun test","changeset":"changeset","version":"changeset version","release":"bun run build && npm publish --provenance --access public"},"keywords":["email","free-email","disposable","bloom-filter","domain","validation"],"author":"","license":"MIT","devDependencies":{"@changesets/changelog-github":"^0.5.1","@changesets/cli":"^2.29.4","@types/bun":"^1.2.4","bloomfilter":"^1.0.0","free-email-domains":"^1.2.14","tsup":"^8.5.1","typescript":"^5.7.3"},"gitHead":"96b9a528588a0af81fa3503b7d4aa6bce80d9e86","_id":"bloommx@1.0.3","_nodeVersion":"24.12.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-fRW++DisJvVVuPdkyn+zVjnnX4bBrnwVLRjtqomsuWZgVHf77rUCYg7BnX6hxVIj90miqNBoiHwNSXgx32wdfg==","shasum":"82085205646dda1a9adc6d3561602ee87dbb8df0","tarball":"https://registry.npmjs.org/bloommx/-/bloommx-1.0.3.tgz","fileCount":25,"unpackedSize":116073,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDrmIs++lI9mi9r+eDYJF72fE3rJ8zMB2loCVbBgiJOuAiEA2YcjIAiLrWeZKlCeRiNujgjjMvvQ0z9tHzo2AnKs4Rw="}]},"_npmUser":{"name":"rafaeelaudibert","email":"rafaeelaudibert@gmail.com"},"directories":{},"maintainers":[{"name":"rafaeelaudibert","email":"rafaeelaudibert@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/bloommx_1.0.3_1771996270355_0.27277431599746516"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-24T21:54:10.046Z","modified":"2026-02-25T05:11:10.619Z","0.0.1":"2026-02-24T21:54:10.213Z","1.0.0":"2026-02-24T22:15:17.352Z","1.0.1":"2026-02-24T23:19:33.890Z","1.0.2":"2026-02-25T04:57:23.387Z","1.0.3":"2026-02-25T05:11:10.510Z"},"license":"MIT","keywords":["email","free-email","disposable","bloom-filter","domain","validation"],"description":"Lightweight free email domain checker via Bloom filter","maintainers":[{"name":"rafaeelaudibert","email":"rafaeelaudibert@gmail.com"}],"readme":"# bloommx\n\nLightweight free email domain checker using a [Bloom filter](https://en.wikipedia.org/wiki/Bloom_filter). Check if an email address belongs to a free provider (Gmail, Yahoo, Outlook, etc.) with a tiny bundle — no full domain lists shipped to the client.\n\n## Why?\n\nLibraries like `free-email-domains` ship the entire domain list (~4,800 entries). That's fine on the server, but heavy for client-side bundles. A Bloom filter trades a small, configurable false positive rate for a dramatically smaller payload. Zero false negatives — if a domain is free, bloommx will always say so.\n\nInspired by [swot-bloom](https://www.npmjs.com/package/swot-bloom) (same concept for academic emails).\n\n## Install\n\n```bash\nnpm install bloommx\n```\n\n## Usage\n\n```ts\nimport { isFreeEmail, isFreeDomain } from \"bloommx\";\n\nisFreeEmail(\"user@gmail.com\");    // true\nisFreeEmail(\"ceo@posthog.com\");   // false\n\nisFreeDomain(\"yahoo.com\");        // true\nisFreeDomain(\"stripe.com\");       // false\n```\n\n## Tiers\n\nbloommx ships 4 tiers as separate subpath exports. Each tier is independently tree-shakeable — importing `bloommx/micro` won't pull in the data for other tiers.\n\n| Import | FP Rate | Data Size | Best For |\n|--------|---------|-----------|----------|\n| `bloommx/micro` | ~5% | ~5 KB | Smallest possible, rough filtering |\n| `bloommx/compact` | ~1% | ~8 KB | Most frontend apps |\n| `bloommx` (default) | ~0.1% | ~11 KB | Balanced default |\n| `bloommx/precise` | ~0.01% | ~15 KB | Near-exact matching |\n\n**False positive** means a non-free domain is incorrectly identified as free. **False negative** never happens — every domain in the source list is guaranteed to match.\n\n### Choosing a tier\n\n- **`bloommx/micro`** (~5% FP, ~5 KB): Use when you just need a rough signal and bundle size is critical. About 1 in 20 corporate domains may be misclassified as free. Good for soft UI hints, not hard filtering.\n\n- **`bloommx/compact`** (~1% FP, ~8 KB): Good balance for most frontend use cases. About 1 in 100 corporate domains may be misclassified. Suitable for form validation where the occasional false positive is acceptable.\n\n- **`bloommx`** (~0.1% FP, ~11 KB): The default. About 1 in 1,000 corporate domains may be misclassified. Recommended when accuracy matters but you still want a small bundle.\n\n- **`bloommx/precise`** (~0.01% FP, ~15 KB): Near-exact. About 1 in 10,000 corporate domains may be misclassified. Use when you need high confidence and the extra few KB are acceptable.\n\n### Using a specific tier\n\n```ts\nimport { isFreeEmail } from \"bloommx/micro\";\nimport { isFreeEmail } from \"bloommx/compact\";\nimport { isFreeEmail } from \"bloommx\";          // balanced (default)\nimport { isFreeEmail } from \"bloommx/precise\";\n```\n\nAll tiers export the same API: `isFreeEmail(email)` and `isFreeDomain(domain)`.\n\n## API\n\n### `isFreeEmail(email: string): boolean`\n\nReturns `true` if the email's domain is a known free email provider. Handles parsing, lowercasing, and trimming. Returns `false` for invalid inputs (no `@`, empty string).\n\n### `isFreeDomain(domain: string): boolean`\n\nReturns `true` if the domain is a known free email provider. Input is lowercased and trimmed.\n\n## How it works\n\n1. At build time, all ~4,800 domains from [`free-email-domains`](https://github.com/Kikobeats/free-email-domains) are inserted into a [Bloom filter](https://en.wikipedia.org/wiki/Bloom_filter) using the [`bloomfilter`](https://www.npmjs.com/package/bloomfilter) package.\n\n2. The filter's bit array is serialized as a base64 string and embedded in a JS module.\n\n3. At runtime, a minimal ~60-line checker (FNV-1a hash + enhanced double hashing) tests membership against the decoded bit array. Only the read path ships — no write/add capability.\n\n4. The domain list is updated weekly via GitHub Actions. When `free-email-domains` publishes a new version, filters are regenerated and a new patch is published automatically.\n\n## Data source\n\nDomain list: [`free-email-domains`](https://github.com/Kikobeats/free-email-domains) by Kikobeats — actively maintained, MIT licensed, ~4,800 free email domains.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}