CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-seamless-immutable

Immutable data structures for JavaScript which are backwards-compatible with normal JS Arrays and Objects.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

Seamless Immutable

Seamless Immutable provides backwards-compatible immutable data structures for JavaScript. Unlike other immutable libraries, seamless-immutable objects can be used in for loops, passed to functions expecting vanilla JavaScript data structures, and serialized with JSON.stringify. The library leverages ECMAScript 5 features like Object.defineProperty and Object.freeze to enforce immutability while preserving familiar JavaScript APIs.

Package Information

  • Package Name: seamless-immutable
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install seamless-immutable

Core Imports

const Immutable = require("seamless-immutable");

For static API (recommended to avoid method collision):

const Immutable = require("seamless-immutable").static;

ES6 import:

import Immutable from "seamless-immutable";

Basic Usage

const Immutable = require("seamless-immutable");

// Create immutable array - still works with for loops and JSON.stringify
const array = Immutable(["totally", "immutable", {hammer: "Can't Touch This"}]);

array[1] = "I'm going to mutate you!";
console.log(array[1]); // "immutable" - unchanged

// Works with for loops
for (let index in array) {
  console.log(array[index]);
}

// Works with JSON serialization
JSON.stringify(array); // '["totally","immutable",{"hammer":"Can't Touch This"}]'

// Create immutable object with enhanced methods
const obj = Immutable({status: "good", hypothesis: "plausible", errors: 0});
const updated = obj.merge({status: "funky", hypothesis: "confirmed"});
// Returns: {status: "funky", hypothesis: "confirmed", errors: 0}

Architecture

Seamless Immutable is built around several key principles:

  • Backwards Compatibility: Immutable structures behave like regular Arrays and Objects
  • Non-Destructive Operations: All mutations return new immutable instances
  • Enhanced Methods: Additional methods like merge, set, getIn for common operations
  • Static and Instance APIs: Both obj.method() and Immutable.method(obj) patterns supported
  • Development vs Production: Development build includes freezing and helpful errors, production build optimized for performance

Performance Characteristics

  • Structural Sharing: Reuses existing nested objects rather than deep cloning, providing significant performance benefits for large nested structures
  • Development vs Production: Production build offers ~2x performance improvement by removing freezing and defensive checks
  • Safari Consideration: Frozen objects iterate more slowly in Safari; consider production build for performance-critical Safari applications
  • Memory Efficiency: Only changed parts of data structures are copied, unchanged portions are shared between versions

Usage Guidance

When to Use Static vs Instance API

Use Static API (require("seamless-immutable").static) when:

  • Avoiding method name pollution is important
  • Working in a functional programming style
  • Risk of conflicts with existing object methods
  • Need consistent API across all data types

Use Instance API (default) when:

  • Preferring concise, object-oriented syntax
  • No concerns about method name conflicts
  • Working with existing codebases expecting instance methods

Development vs Production Builds

Use Development Build when:

  • During development and testing
  • Need helpful error messages for debugging
  • Want guaranteed immutability enforcement
  • Performance is not critical

Use Production Build when:

  • In production environments
  • Performance is critical (~2x faster)
  • Bundle size matters
  • Already confident in immutability usage

Capabilities

Core Constructor and Utilities

Primary entry point for creating immutable data structures, plus static utility methods for type checking and configuration.

/**
 * Creates an immutable version of the provided data structure
 * @param {*} obj - Data to make immutable (Array, Object, Date, or primitive)
 * @param {Object} [options] - Configuration options
 * @param {Object} [options.prototype] - Custom prototype for objects
 * @returns {*} Immutable version of the input
 */
function Immutable(obj, options);

/**
 * Alias for Immutable() for linter compatibility
 */
Immutable.from = Immutable;

/**
 * Checks if a value is immutable
 * @param {*} target - Value to check
 * @returns {boolean} True if the value is immutable
 */
function isImmutable(target);

/**
 * Error class thrown when attempting to use mutating methods
 */
class ImmutableError extends Error;

/**
 * Static API version that avoids method pollution
 */
const static;

Core Constructor and Utilities

Object Operations

Methods for working with immutable objects including merging, property manipulation, and nested updates.

/**
 * Merge objects immutably with configurable behavior
 * @param {Object} obj - Target object
 * @param {Object|Array} other - Object(s) to merge
 * @param {Object} [config] - Merge configuration
 * @param {boolean} [config.deep] - Deep merge nested objects
 * @param {string} [config.mode] - Merge mode: 'merge'|'replace'
 * @param {Function} [config.merger] - Custom merger function
 * @returns {Object} New immutable object with merged properties
 */
function merge(obj, other, config);

/**
 * Set a property on an object immutably
 * @param {Object} obj - Target object
 * @param {string} property - Property key to set
 * @param {*} value - Value to set
 * @param {Object} [config] - Configuration options
 * @param {boolean} [config.deep] - Deep merge if value is object
 * @returns {Object} New immutable object with property set
 */
function set(obj, property, value, config);

/**
 * Remove properties from an object immutably
 * @param {Object} obj - Target object
 * @param {...string|Array|Function} keys - Keys to remove or predicate function
 * @returns {Object} New immutable object without specified properties
 */
function without(obj, ...keys);

Object Operations

Array Operations

Methods for working with immutable arrays including functional operations and specialized transformations.

/**
 * Maps and flattens array elements
 * @param {Array} array - Source array
 * @param {Function} iterator - Mapping function
 * @returns {Array} New immutable array with mapped and flattened results
 */
function flatMap(array, iterator);

/**
 * Convert array to object using key-value pairs
 * @param {Array} array - Source array
 * @param {Function} [iterator] - Function returning [key, value] pairs
 * @returns {Object} New immutable object
 */
function asObject(array, iterator);

/**
 * Set element at specific index
 * @param {Array} array - Source array
 * @param {number} idx - Index to set
 * @param {*} value - Value to set
 * @param {Object} [config] - Configuration options
 * @param {boolean} [config.deep] - Deep merge if value is object
 * @returns {Array} New immutable array with element set
 */
function set(array, idx, value, config);

Array Operations

Nested Operations

Methods for working with nested data structures using path-based access patterns.

/**
 * Set nested property using path array
 * @param {Object|Array} obj - Target object or array
 * @param {Array} path - Path to nested property
 * @param {*} value - Value to set
 * @param {Object} [config] - Configuration options
 * @returns {Object|Array} New immutable structure with nested property set
 */
function setIn(obj, path, value, config);

/**
 * Get nested property using path array
 * @param {Object|Array} obj - Target object or array  
 * @param {Array} path - Path to nested property
 * @param {*} [defaultValue] - Default value if path not found
 * @returns {*} Value at path or default value
 */
function getIn(obj, path, defaultValue);

/**
 * Update nested property using updater function
 * @param {Object|Array} obj - Target object or array
 * @param {Array} path - Path to nested property
 * @param {Function} updater - Function to update the value
 * @param {...*} [args] - Additional arguments passed to updater
 * @returns {Object|Array} New immutable structure with updated nested property
 */
function updateIn(obj, path, updater, ...args);

Nested Operations

Types

/**
 * Configuration options for merge operations
 */
interface MergeConfig {
  /** Perform deep merge of nested objects */
  deep?: boolean;
  /** Merge mode: 'merge' preserves existing properties, 'replace' removes unlisted properties */
  mode?: 'merge' | 'replace';
  /** Custom merger function called for each property */
  merger?: (currentValue: any, newValue: any, config: MergeConfig) => any;
}

/**
 * Configuration options for set operations
 */
interface SetConfig {
  /** Deep merge if setting an object value */
  deep?: boolean;
}

/**
 * Configuration options for asMutable operations
 */
interface AsMutableConfig {
  /** Convert nested immutable structures to mutable recursively */
  deep?: boolean;
}

/**
 * Configuration options for Immutable constructor
 */
interface ImmutableOptions {
  /** Custom prototype for created objects */
  prototype?: Object;
}
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/seamless-immutable@7.1.x
Publish Source
CLI
Badge
tessl/npm-seamless-immutable badge