@hyperfrontend/immutable-api-utilsView on npm →API Reference →

@hyperfrontend/immutable-api-utils

Decorators and utilities for creating immutable, tamper-proof object APIs with built-in prototype pollution defense.

What is @hyperfrontend/immutable-api-utils?

@hyperfrontend/immutable-api-utils provides low-level utilities for locking object properties and methods to prevent modification. Using JavaScript's property descriptors (Object.defineProperty), it creates truly immutable APIs where neither values nor method bindings can be altered after definition.

The library offers three approaches: a TypeScript decorator (@locked()) for class methods, a functional API (lockedProps()) for bulk property locking, and descriptor builders (lockedPropertyDescriptors()) for granular control. All utilities enforce non-writable, non-configurable descriptors while maintaining correct this binding through per-instance caching.

Additionally, the library provides safe built-in copies—pre-captured references to JavaScript built-in methods that mitigate prototype pollution attacks when loaded early.

Key Features

  • @locked() decorator for TypeScript classes—prevents method overwriting and ensures correct this binding
  • Bulk property locking via lockedProps() for multiple properties in one call
  • Property descriptor creation with lockedPropertyDescriptors() for custom locking patterns
  • Safe built-in copies via secondary entrypoints—captured at module load time before any pollution can occur
  • Per-instance binding cache to avoid repeated .bind() calls
  • Zero runtime dependencies - pure JavaScript property descriptor manipulation

Architecture Highlights

The @locked() decorator uses Symbol-based caching to store bound methods per instance, avoiding the performance cost of repeated .bind() calls. Properties are marked configurable: false to prevent deletion or descriptor modification, and writable: false to block reassignment.

The safe built-in copies are captured at module initialization time. Important: This only works if the module loads before any malicious code runs—it mitigates pollution, not prevents it retroactively.

Why Use @hyperfrontend/immutable-api-utils?

Prevents Accidental API Tampering in Shared Contexts

When exposing objects to third-party code, plugin systems, or sandboxed environments, you need guarantees that critical methods won't be overwritten. @locked() makes methods truly immutable—attempting reassignment throws a TypeError. This protects public APIs from accidental or malicious modification.

Eliminates this Binding Bugs Without Arrow Functions

Arrow functions in class fields break inheritance and bloat bundle sizes due to per-instance function creation. The @locked() decorator provides correct this binding (like arrow functions) while using efficient prototype methods. Methods are bound once per instance and cached with Symbol keys.

Simplifies Immutable Object Construction

Building frozen objects with Object.freeze() is shallow and doesn't prevent descriptor modification. lockedProps() provides deep immutability for specific properties while allowing controlled mutability elsewhere—ideal for partially frozen configs or API surfaces.

TypeScript-First with Runtime Enforcement

Unlike TypeScript readonly (compile-time only), these utilities enforce immutability at runtime. This catches bugs in JavaScript-land, during deserialization, or when interfacing with dynamically typed code. Type safety and runtime safety in one decorator.

Installation

npm install @hyperfrontend/immutable-api-utils

Quick Start

import { locked, lockedProps, lockedPropertyDescriptors } from '@hyperfrontend/immutable-api-utils'

// Decorator usage: lock methods in classes
class Counter {
  private count = 0

  @locked()
  increment() {
    this.count++
    return this.count
  }

  @locked()
  getValue() {
    return this.count
  }
}

const counter = new Counter()
counter.increment() // Works: 1
counter.increment = () => 0 // Throws: Cannot overwrite locked method

// Ensure correct `this` binding even when method is extracted
const { increment } = counter
increment() // Still works correctly, `this` remains bound

// Functional API: lock multiple properties
const config = {}
lockedProps(config, [
  ['apiKey', 'secret-key-12345'],
  ['timeout', 5000],
  ['retries', 3],
])

config.apiKey = 'hacked' // Silent fail in non-strict mode, throws in strict mode
Object.defineProperty(config, 'apiKey', { writable: true }) // Throws: cannot redefine

// Low-level descriptor creation
const obj = {}
Object.defineProperty(obj, 'version', lockedPropertyDescriptors('1.0.0', true))
// Property is non-writable, non-configurable, but enumerable

API Overview

Decorator

  • @locked() - TypeScript decorator that makes class methods immutable with correct this binding

Functions

  • lockedProps(object, pairs) - Lock multiple properties on an object with key-value pairs
  • lockedPropertyDescriptors(value, enumerable?) - Create a locked property descriptor for manual use with Object.defineProperty

Safe Built-in Copies

Pre-captured references to JavaScript built-ins via secondary entrypoints. Available modules:

Entrypoint Description
built-in-copy/object Object static methods (freeze, keys, entries, etc.)
built-in-copy/array Array static methods (isArray, from, of)
built-in-copy/json JSON methods (parse, stringify)
built-in-copy/promise Promise static methods and factory (createPromise, all, race, etc.)
built-in-copy/console Console methods (log, warn, error, info, debug, etc.)
built-in-copy/timers Timer functions (setTimeout, setInterval, queueMicrotask, requestAnimationFrame, etc.)
built-in-copy/messaging Messaging APIs (structuredClone, createMessageChannel, createBroadcastChannel, postMessage* helpers)
built-in-copy/encoding Encoding APIs (createTextEncoder, createTextDecoder, atob, btoa)
built-in-copy/typed-arrays Typed arrays and buffers (createUint8Array, createArrayBuffer, createDataView, etc.)
built-in-copy/url URL APIs (createURL, createURLSearchParams, canParse, createObjectURL, etc.)
built-in-copy/websocket WebSocket factory (createWebSocket, ready state constants)
built-in-copy/math Math methods and constants (random, floor, ceil, PI, etc.)
built-in-copy/number Number methods and constants (isNaN, parseInt, parseFloat, MAX_SAFE_INTEGER, etc.)
built-in-copy/string String static methods (fromCharCode, fromCodePoint, raw)
built-in-copy/reflect Reflect methods
built-in-copy/function Function utilities
built-in-copy/symbol Symbol static methods
built-in-copy/map Map constructor factory
built-in-copy/set Set constructor factory
built-in-copy/weak-map WeakMap constructor factory
built-in-copy/weak-set WeakSet constructor factory
built-in-copy/regexp RegExp constructor factory
built-in-copy/date Date constructor factory
built-in-copy/error Error constructor factories

Limitations:

  • Only effective if imported before any untrusted code executes
  • Does not protect against pollution that occurred before module load
  • Best used as an early import in application entry points
// Import early in your entry point
import { freeze, keys } from '@hyperfrontend/immutable-api-utils/built-in-copy/object'
import { parse } from '@hyperfrontend/immutable-api-utils/built-in-copy/json'
import { log, warn } from '@hyperfrontend/immutable-api-utils/built-in-copy/console'
import { setTimeout } from '@hyperfrontend/immutable-api-utils/built-in-copy/timers'
import { structuredClone, createMessageChannel } from '@hyperfrontend/immutable-api-utils/built-in-copy/messaging'

const config = freeze({ api: 'https://example.com' })
const data = parse('{"key": "value"}')
log('Config loaded:', config)
setTimeout(() => log('Delayed message'), 1000)

Use Cases

  • Plugin APIs: Prevent plugins from modifying core library methods
  • Sandboxed execution: Expose safe APIs to untrusted code
  • Configuration objects: Lock critical config values after initialization
  • Public library interfaces: Protect exported classes from mutation
  • Event emitters: Prevent handler list manipulation
  • Prototype pollution mitigation: Safe built-in copies reduce attack surface when loaded early
  • Secure logging: Use safe console copies to prevent tampered log output
  • Safe timers: Prevent timer functions from being hijacked
  • Cross-origin messaging: Secure postMessage wrappers with captured references

Compatibility

Platform Support
Browser
Node.js
Web Workers
Deno, Bun, Cloudflare Workers

Output Formats

Format File Tree-Shakeable
ESM index.esm.js
CJS index.cjs.js
IIFE bundle/index.iife.min.js
UMD bundle/index.umd.min.js

Secondary entrypoints (built-in-copy/*) are individually tree-shakeable—import only the built-ins you need.

CDN Usage

<!-- unpkg -->
<script src="https://unpkg.com/@hyperfrontend/immutable-api-utils"></script>

<!-- jsDelivr -->
<script src="https://cdn.jsdelivr.net/npm/@hyperfrontend/immutable-api-utils"></script>

<script>
  const { locked, lockedProps, lockedPropertyDescriptors } = HyperfrontendImmutableApiUtils
</script>

Global variable: HyperfrontendImmutableApiUtils

Dependencies

None — zero external dependencies.

Part of hyperfrontend

This library is part of the hyperfrontend monorepo.

📖 Full documentation

License

MIT

API Reference§

View:
Organized by entry point

Module Structure

|

28 modules · 289 total exports

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils

@hyperfrontend/immutable-api-utils Decorators and utilities for creating immutable, tamper-proof object APIs. This package provides: - Safe copies of built-in JavaScript objects and methods - Utilities for locking object properties - Property descriptor utilities

1 fn3 type20 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/array

Safe copies of Array built-in static methods. These references are captured at module initialization time to protect against prototype pollution attacks. Import only what you need for tree-shaking.

4 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/console

Safe copies of Console built-in methods. These references are captured at module initialization time to protect against prototype pollution attacks. Import only what you need for tree-shaking.

19 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/date

Safe copies of Date built-in via factory function and static methods.

1 fn4 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/encoding

Safe copies of encoding built-ins for TextEncoder, TextDecoder, atob, and btoa.

4 fn1 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/error

Safe copies of Error built-ins via factory functions. Since constructors cannot be safely captured via Object.assign, this module provides factory functions that use Reflect.construct internally. These references are captured at module initialization time to protect against prototype pollution attacks. Import only what you need for tree-shaking.

8 fn1 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/function

Safe copies of Function constructor and prototype methods.

1 fn5 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/json

Safe copies of JSON built-in methods. These references are captured at module initialization time to protect against prototype pollution attacks. Import only what you need for tree-shaking.

3 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/map

Safe Map factory with optional groupBy for ES2024+.

1 fn2 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/math

Safe copies of Math built-in methods. These references are captured at module initialization time to protect against prototype pollution attacks. Import only what you need for tree-shaking.

44 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/messaging

Safe copies of Messaging/Communication built-in functions and constructors. These references are captured at module initialization time to protect against prototype pollution attacks. Import only what you need for tree-shaking. Note: `postMessage` is a method on specific objects (Window, Worker, MessagePort) rather than a global. This module provides factory functions for MessageChannel and BroadcastChannel, whose instances have safe postMessage methods.

4 fn1 int4 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/number

Safe copies of Number built-in methods and constants. These references are captured at module initialization time to protect against prototype pollution attacks. Import only what you need for tree-shaking.

17 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/object

Safe copies of Object built-in methods. These references are captured at module initialization time to protect against prototype pollution attacks. Import only what you need for tree-shaking.

2 fn22 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/promise

Safe Promise factory and bound static methods.

1 fn8 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/reflect

Safe copies of Reflect built-in methods. These references are captured at module initialization time to protect against prototype pollution attacks. Import only what you need for tree-shaking.

14 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/regexp

Safe RegExp factory for protected regex construction.

1 fn1 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/set

Safe Set factory for protected set construction.

1 fn1 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/string

Safe copies of String built-in static methods. These references are captured at module initialization time to protect against prototype pollution attacks. Import only what you need for tree-shaking.

4 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/symbol

Safe Symbol factory and well-known symbols.

1 fn16 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/timers

Safe copies of Timer/Scheduling built-in functions. These references are captured at module initialization time to protect against prototype pollution attacks. Import only what you need for tree-shaking.

5 fn3 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/typed-arrays

Safe TypedArray and ArrayBuffer factories for protected array construction.

14 fn24 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/url

Safe copies of URL built-ins via factory functions. Provides safe references to URL and URLSearchParams. These references are captured at module initialization time to protect against prototype pollution attacks. Import only what you need for tree-shaking.

2 fn5 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/weak-map

Safe WeakMap factory for protected weak map construction.

1 fn1 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/weak-set

Safe WeakSet factory for protected weak set construction.

1 fn1 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/built-in-copy/websocket

Safe copies of WebSocket built-ins via factory functions. Provides safe references to WebSocket. These references are captured at module initialization time to protect against prototype pollution attacks. Import only what you need for tree-shaking.

1 fn5 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/locked

Decorator for binding methods with immutable this context.

1 fn1 type

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/locked-prop-descriptors

Non-writable, non-configurable property descriptor utilities.

1 type1 var

@hyperfrontend/immutable-api-utils/@hyperfrontend/immutable-api-utils/locked-props

Decorator for locking object properties to prevent modification.

1 type1 var

Related