{"id":12176,"library":"ts-invariant","title":"ts-invariant: TypeScript Assertions","description":"ts-invariant is a TypeScript-first implementation of the widely used `invariant(condition, message)` assertion pattern. It's designed for validating preconditions and ensuring consistent program state, primarily in development builds. The current stable version is 0.10.3. Actively maintained as part of the Apollo GraphQL ecosystem, its release cadence is tied to broader project needs rather than a fixed schedule. Key differentiators include robust TypeScript typing for compile-time safety, extended logging capabilities (`invariant.log`, `invariant.warn`, `invariant.error`), and configurable verbosity via `setVerbosity`. A significant feature is its compatibility with bundler plugins (like `rollup-plugin-invariant`, though that plugin is now archived), which can strip assertion messages from production bundles to reduce file size, making it a performance-conscious choice for assertions.","status":"active","version":"0.10.3","language":"javascript","source_language":"en","source_url":"https://github.com/apollographql/invariant-packages","tags":["javascript","invariant","assertion","precondition","TypeScript","typescript"],"install":[{"cmd":"npm install ts-invariant","lang":"bash","label":"npm"},{"cmd":"yarn add ts-invariant","lang":"bash","label":"yarn"},{"cmd":"pnpm add ts-invariant","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The core `invariant` function is a named export, not a default export.","wrong":"import invariant from 'ts-invariant';","symbol":"invariant","correct":"import { invariant } from 'ts-invariant';"},{"note":"CommonJS `require` for ESM-first packages can lead to module resolution issues, especially in newer Node.js environments or with strict bundler configurations.","wrong":"const { setVerbosity } = require('ts-invariant');","symbol":"setVerbosity","correct":"import { setVerbosity } from 'ts-invariant';"},{"note":"Used for `instanceof` checks when catching errors thrown by `invariant`.","symbol":"InvariantError","correct":"import { InvariantError } from 'ts-invariant';"}],"quickstart":{"code":"import { invariant, setVerbosity, InvariantError } from \"ts-invariant\";\n\n// Default verbosity is 'log'\nconsole.log(\"--- Default verbosity (log) ---\");\n\n// This will throw an InvariantError if the condition is false\ntry {\n  const username: string | undefined = undefined;\n  invariant(username, \"Username must be defined and not empty.\");\n} catch (e) {\n  if (e instanceof InvariantError) {\n    console.error(\"Invariant failed as expected:\", e.message);\n  } else {\n    console.error(\"Unexpected error:\", e);\n  }\n}\n\n// Log a warning message\ninvariant.warn(\"This is a warning message that will be displayed by default.\");\n\n// Change verbosity to suppress log messages\nconsole.log(\"\\n--- Setting verbosity to 'warn' ---\");\nsetVerbosity(\"warn\");\n\n// This log will now be suppressed and not appear in the console\ninvariant.log(\"This log message should be suppressed at 'warn' verbosity.\");\n\n// This warning will still show\ninvariant.warn(\"This warning message should still show at 'warn' verbosity.\");\n\n// This error will still show\ninvariant.error(\"This error message should still show at 'warn' verbosity.\");\n\n// Revert verbosity to default for further operations or tests\nsetVerbosity(\"log\");\nconsole.log(\"\\n--- Verbosity reverted to 'log' ---\");\n\n// Example of how invariants are often handled for production builds\n// In production, bundlers might strip these messages for smaller bundles.\nif (process.env.NODE_ENV === 'production') {\n  // In a real production build, this invariant message might be stripped.\n  invariant(false, \"This message is for dev only. Production build will strip it if configured.\");\n} else {\n  invariant.log(\"In development, invariant messages (like the one above) are usually active for debugging.\");\n}\n","lang":"typescript","description":"Demonstrates importing `invariant`, `setVerbosity`, and `InvariantError`, showing basic assertion, logging levels, and the effect of verbosity settings. It also highlights `process.env.NODE_ENV` behavior."},"warnings":[{"fix":"Ensure `process.env.NODE_ENV` is correctly set to 'development' during development builds to retain messages. For production debugging, either temporarily disable stripping or rely on stack traces and code context.","message":"Error messages from `invariant` and its logging methods (`invariant.log`, `invariant.warn`, `invariant.error`) can be stripped from production bundles. This is typically done by bundler plugins (e.g., `rollup-plugin-invariant`, though now archived). While beneficial for bundle size, it means production builds might not show detailed assertion messages, making debugging production issues challenging if unaware.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"When bundling for browsers, ensure your bundler (e.g., Webpack, Rollup, Vite) correctly defines or polyfills `process.env.NODE_ENV`. For Webpack, use `DefinePlugin`; for Rollup, use `@rollup/plugin-replace`.","message":"`ts-invariant` often relies on `process.env.NODE_ENV` to determine its behavior, especially regarding message stripping. If `process.env` is not properly polyfilled or replaced by a bundler in non-Node.js environments (like browsers), it might lead to unexpected runtime behavior or errors.","severity":"gotcha","affected_versions":">=0.1.0"},{"fix":"Consider migrating to alternative bundler plugins or custom configurations that achieve similar dead-code elimination if you rely on stripping invariant messages. Verify continued compatibility if you remain on `rollup-plugin-invariant`.","message":"The `rollup-plugin-invariant` package, which was commonly used to strip `ts-invariant` messages in production, has been moved to an archived directory by the Apollo GraphQL team. While its functionality might still work, it indicates a lack of active maintenance and potential for future compatibility issues with newer Rollup versions or other tooling.","severity":"breaking","affected_versions":">=0.10.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Configure your bundler to provide a `process.env` polyfill or replacement. For Webpack, use `new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) });`. For Rollup, use `@rollup/plugin-replace`.","cause":"This error occurs when `process` is accessed in a browser environment, and it has not been properly polyfilled or defined by the bundler.","error":"TypeError: Cannot read properties of undefined (reading 'env')"},{"fix":"During development, this is a signal to fix the underlying condition. In production, if messages are not stripped, verify your bundler's configuration for `process.env.NODE_ENV` and the invariant stripping plugin.","cause":"This is the expected runtime error when an `invariant` condition evaluates to false. If this occurs in a production environment where messages are typically stripped, it implies that the stripping mechanism is not active or correctly configured.","error":"Invariant Violation: Username must be defined and not empty."},{"fix":"Change your import statement from `import invariant from 'ts-invariant';` to `import { invariant } from 'ts-invariant';`. If using CommonJS, ensure transpilation or use `const { invariant } = require('ts-invariant');` (though ESM is preferred).","cause":"This usually indicates an incorrect import statement, where `invariant` is attempted to be imported as a default export rather than a named export, especially in CommonJS contexts or misconfigured ESM.","error":"TypeError: (0, ts_invariant__WEBPACK_IMPORTED_MODULE_0__.invariant) is not a function"}],"ecosystem":"npm"}