Runtime validation is a critical component of defensive programming, ensuring that application states remain consistent and predictable. While many libraries offer assertion capabilities, they often introduce unnecessary bloat or complex dependencies. The tiny-invariant library provides a minimal, zero-dependency solution designed specifically for modern JavaScript and TypeScript environments where bundle size and performance are paramount.
Core Functionality and API Design
At its heart, tiny-invariant exposes a single function that eavluates a truthy condition. If the condition evaluates to false, the function throws an error; otherwise, it exits silently. Unlike heavier alternatives that utilize sprintf for string formatting, this library leverages native ES6 template literals. This design choice removes the overhead of string parsing logic while maintaining the flexibility to construct dynamic error messages.
import invariant from 'tiny-invariant';
function processTransaction(transaction) {
// Validate that the amount is positive and a valid number
invariant(
transaction.amount > 0,
`Transaction amount must be positive, received: ${transaction.amount}`
);
// Ensure a reference ID exists
invariant(transaction.id, 'Transaction ID is required for processing');
// Proceed with logic
return submitToGateway(transaction);
}
TypeScript Integration and Type Narrowing
When working with strict type systems like TypeScript or Flow, manual type casting can often be unsafe. tiny-invariant is designed to function as a type guard. When a check passes, the compiler understands that the variable must conform to the asserted type, effectively narrowing the type scope for the remainder of the block.
type UserProfile = {
id: string;
email: string;
settings?: {
notifications: boolean;
};
};
function toggleNotifications(profile: UserProfile | null) {
// Assert that the profile object exists
invariant(profile, 'User profile cannot be null');
// TypeScript now knows 'profile' is definitely 'UserProfile'
// and allows safe access to nested properties
invariant(profile.settings, 'User settings are not initialized');
profile.settings.notifications = !profile.settings.notifications;
}
Bundle Optimization and Tree Shaking
One of the primary advantages of using tiny-invariant in performance-critical applications is its compatibility with code minification tools. When configured correctly, bundlers like Webpack or Terser can strip the invariant calls entirely from production builds if the environment variable is set (e.g., process.env.NODE_ENV === 'production'). This results in zero runtime cost for the end-user while retaining full debugging capabilities during development.
Installation
To integrate this library into your project, install it via your preferred package manager:
npm install tiny-invariant
# or
yarn add tiny-invariant
This utility is particularly effective in scenarios such as validating component props in UI libraries, sanitizing API responses, or enforcing preconditions in complex algorithms without inflating the final bundle size.