mrkeyoor.com_
Wed 23 Sept 00:35 UTC
npmUtilsupdated 22 Sept 2026

@react-dnd/invariant review

@react-dnd/invariant 4.0.2 is a one-function runtime assertion extracted for React DnD's internal packages. `invariant(condition, message, ...values)` returns when the condition is truthy. Otherwise it throws an `Error` named `Invariant Violation` after replacing `%s` markers in the message. It performs no drag-and-drop work and does not validate external data. Our measured full import was only 0.4 KB gzipped, with no dependencies or peers. The current npm release is still the April 2022 ESM package, so its 4.7 million weekly downloads mostly describe React DnD's dependency graph, not a reason to choose it directly.

Verdict

@react-dnd/invariant 4.0.2 installed as 1 package and bundled to 0.4 KB gzipped in our sandbox, but its npm release dates to 2022 and its types do not narrow assertions. Do not add it for its download count; keep it only where exact React DnD error compatibility is already part of the code.

We installed it

Lab card: what happened when we installed @react-dnd/invariantScreenshot of @react-dnd/invariant documentation
Install✓ · 0.9s1 package on disk · 1 MB
ImportESM import works · require() works · ESM package
Browser0.4 KBgzipped (0.6 KB minified), bundled with esbuild
TypesTypeScript types bundled
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does @react-dnd/invariant install cleanly?

Yes. In a fresh container with an empty cache, npm install @react-dnd/invariant finished in 0.9s, leaving 1 package and 1 MB on disk. npm audit reported no known vulnerabilities.

How much does @react-dnd/invariant add to a browser bundle?

0.4 KB gzipped (0.6 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.

Does @react-dnd/invariant work with both ESM and CommonJS?

Yes. Both import '@react-dnd/invariant' and require('@react-dnd/invariant') worked in Node 22 in our run. The package is published as ESM.

Does @react-dnd/invariant include TypeScript types?

Yes, type declarations ship inside the package, so no @types install is needed.

@react-dnd/invariant or tiny-invariant: which should you use?

tiny-invariant: Choose it for a public standalone invariant helper with direct-use documentation. @react-dnd/invariant 4.0.2 installed as 1 package and bundled to 0.4 KB gzipped in our sandbox, but its npm release dates to 2022 and its types do not narrow assertions.

When should you not use @react-dnd/invariant?

You are picking an assertion helper for new application code; this package has no README or package-specific documentation

API stability4/5Version 4.0.2 exports 1 small function whose observable contract is easy to pin: truthy input returns, falsy input throws, `%s` values are consumed in order, and the error name changes to `Invariant Violation`. That surface has little room for churn. The remaining mismatch is type-level: the bundled declaration returns `void`, so TypeScript cannot use the check for narrowing even though runtime execution stops on a false condition.
Docs1/5The npm metadata describes the package only as `invariantx`, provides no homepage, and includes no package README. The repository's top README is about React DnD and sends users to drag-and-drop documentation, not to this helper. A consumer must inspect the source, manifest, and declaration file to learn the `%s` rules, ordinary Error type, missing assertion signature, and module packaging. That is inadequate for a direct dependency even though the code is short.
Maintenance2/5npm published 4.0.2 on April 19, 2022. The broader unarchived React DnD repository was last pushed on July 6, 2025 and currently reports 475 open issues and pull requests, but that activity did not produce a newer invariant package. A tiny stable helper does not need frequent feature releases, yet more than 4 years without a package update leaves module metadata and TypeScript semantics behind current expectations.
Ecosystem2/5The npm endpoint counted 4,687,329 downloads in the latest completed week, and the parent React DnD repository has 21,636 stars. This utility has no plugins, adapters, docs site, or independent integration surface; it throws 1 kind of error. The strong numbers belong to transitive placement inside React DnD packages. Direct adopters gain no drag-and-drop feature and should compare a local typed assertion before treating ecosystem volume as support.

Use it if

  • You maintain React DnD code and must preserve its exact error name and `%s` message substitution
  • Existing tests already depend on `Invariant Violation` rather than a project-owned assertion class
  • A tiny runtime check is enough and TypeScript control-flow narrowing is not required
Skip it if

Setup reality

Our install of @react-dnd/invariant 4.0.2 completed in 0.9 seconds in a clean Node 22 container. It left 1 package using 1 MB, and npm audit reported 0 known vulnerabilities. The package itself was 32 KB unpacked, with 0 direct dependencies and 0 peer dependencies. It declares ESM and has no exports map, yet both require() and ESM import worked in our sandbox. TypeScript declarations are bundled. A full esbuild browser import measured 0.6 KB minified and 0.4 KB gzipped.

There are no credentials, config files, native builds, or runtime setup. Import the named invariant function and always pass a message. The public declaration accepts any condition and returns void; it does not tell TypeScript that a nullable value is now defined. Add a small local wrapper with an asserts value is NonNullable<T> signature if an existing codebase must keep this dependency.

Message formatting replaces %s tokens in order. Too few values put undefined into the text, while surplus values do nothing. The thrown value is a normal Error with its name changed to Invariant Violation; the package exports no dedicated error class. Catching by a name string is fragile, so use invariants for programmer mistakes that should surface, not for expected user-input branches.

The current release is 4.0.2 from April 2022. The wider React DnD repository moved later, but there is no newer npm package to carry those workspace changes. At 0.4 KB gzipped, bundle size is not the objection. The weak direct-use docs, old publication, and missing assertion signature are. A local 4-line assertion often gives a clearer ownership and typing story.

Patterns

Stop on an impossible state assert-condition

import {invariant} from '@react-dnd/invariant';
invariant(items.length > 0, 'Expected at least one item');
process(items[0]);

A false condition throws synchronously with the name `Invariant Violation`; this is for internal bugs.

Insert one value in the message format-one-value

invariant(handlers.has(id), 'Expected handler %s to be registered', id);

Only `%s` is replaced; `%d` and named placeholders have no formatting behavior.

Insert values in order format-two-values

invariant(source === target, 'Cannot connect %s to %s', source, target);

Two `%s` markers consume 2 arguments. A missing value becomes the word `undefined`.

Wrap it with an assertion signature add-type-narrowing

function assertDefined<T>(value: T, label: string): asserts value is NonNullable<T> {
  invariant(value != null, '%s must be defined', label);
}
assertDefined(user, 'user');
console.log(user.id);

The local `asserts` signature narrows the value because version 4.0.2's own declaration does not.

Guard an indexed lookup check-array-result

const item = items[index];
invariant(item !== undefined, 'No item at index %s', index);
handle(item!);

Strict indexed-access checking can still require `!` after the call; prefer the typed wrapper for repeated use.

Identify the invariant error recognize-error

try { invariant(config.ready, 'Configuration is not ready'); }
catch (error) {
  if (error instanceof Error && error.name === 'Invariant Violation') reportBug(error);
  else throw error;
}

There is no exported error subclass, so this check depends on 1 mutable name string.

Test synchronous failure text test-failure-message

expect(() => invariant(false, 'Unknown type %s', 'ghost')).toThrow('Unknown type ghost');

Assert the error name separately if application code depends on `Invariant Violation`.

Keep the message explicit always-pass-message

invariant(connection !== null, 'Expected an active connection');

Version 4.0.2's TypeScript declaration requires the message; do not bypass it with an unsafe cast.

Alternatives

PackageRegistryPick it when
tiny-invariantnpmChoose it for a public standalone invariant helper with direct-use documentation.
invariantnpmChoose it when compatibility with the older Facebook-style message contract matters.
zodnpmChoose it when unknown external data needs typed parsing and structured errors.

More utils guides

lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.