Detect temporary email addresses in Node.js

May 19, 2026 · 6 min read

A temporary (or “disposable”) email address is a throwaway inbox that expires within minutes. Users reach for them to grab a verification link without handing over a real address. If your Node.js backend accepts them, you end up with users you can never email again. This guide covers detecting them in any Node.js framework.

The naive approach — and why it fails

The obvious idea is to keep a hand-written list of bad domains:

naive.jstypescript
const blocked = ['mailinator.com', 'tempmail.com'];
const domain = email.split('@')[1];
if (blocked.includes(domain)) reject();

This breaks fast. There are over 160,000 disposable domains and dozens appear every week. A static three-line list catches almost none of them. You need a maintained list — and ideally one that updates itself.

Install isDisposable

@isdisposable/js bundles the full blocklist and exposes a synchronous check. It has zero dependencies and works in any Node.js runtime, including serverless and edge.

Terminalbash
npm install @isdisposable/js

Express

server.jstypescript
import express from 'express';
import { isDisposable } from '@isdisposable/js';

const app = express();
app.use(express.json());

app.post('/signup', (req, res) => {
  if (isDisposable(req.body.email)) {
    return res.status(422).json({
      error: 'Disposable email addresses are not allowed.',
    });
  }
  // ...create the user
});

Fastify

server.jstypescript
import Fastify from 'fastify';
import { isDisposable } from '@isdisposable/js';

const app = Fastify();

app.post('/signup', async (req, reply) => {
  const { email } = req.body;
  if (isDisposable(email)) {
    return reply.code(422).send({
      error: 'Disposable email addresses are not allowed.',
    });
  }
  // ...create the user
});

NestJS — a reusable validator

In NestJS, wrap the check in a custom validation decorator so it works on any DTO with one annotation.

is-not-disposable.decorator.tstypescript
import { registerDecorator, ValidationOptions } from 'class-validator';
import { isDisposable } from '@isdisposable/js';

export function IsNotDisposable(options?: ValidationOptions) {
  return (object: object, propertyName: string) => {
    registerDecorator({
      name: 'isNotDisposable',
      target: object.constructor,
      propertyName,
      options,
      validator: {
        validate: (value: string) => !isDisposable(value),
        defaultMessage: () => 'Disposable email addresses are not allowed.',
      },
    });
  };
}

Checking many addresses at once

Cleaning an existing user table? isDisposableBulk takes an array and returns a boolean for each entry, with no per-item overhead.

audit.jstypescript
import { isDisposableBulk } from '@isdisposable/js';

const emails = users.map((u) => u.email);
const flags = isDisposableBulk(emails);

const suspicious = users.filter((_, i) => flags[i]);

Want live detection?

The offline package catches known domains instantly. To also catch brand-new domains and verify MX records in real time, the isDisposable API adds those signals — same blocklist underneath, so upgrading is a drop-in change.

Block disposable emails today

isDisposable is free and open source — add it to your signup flow in one line.

Keep reading