What Is Uint16Array?
Uint16Array is a typed array that represents an array of 16-bit unsigned integers in the platform byte order. The contents are initialized to 0 unless initialization data is explicitly provided. As a subclass of the TypedArray class, Uint16Array shares numerous methods and properties with other typed arrays like Int8Array, Uint8ClampedArray, Int16Array, Uint32Array, Float32Array, and Float64Array.
The "Uint" prefix stands for "unsigned integer," meaning this type can only represent non-negative whole numbers. The "16" indicates that each element occupies exactly 16 bits (2 bytes) of memory. This fixed-size representation allows JavaScript engines to optimize storage and numeric operations, providing significant performance benefits over regular arrays for appropriate use cases.
For developers building high-performance web applications, understanding typed arrays like Uint16Array is essential for efficient binary data handling. These specialized data structures form the foundation for many modern web technologies, from WebGL graphics rendering to canvas-based image manipulation.
Value Range and Data Representation
Each Uint16Array element can hold values from 0 to 65,535 (2^16 - 1), which is the maximum value representable with 16 binary digits. This range makes Uint16Array suitable for storing values like color component values (0-255 extended to 0-65535), timestamps, flags, and any unsigned 16-bit data from external sources like files, network protocols, or hardware interfaces.
When values exceed this range, JavaScript performs modulo arithmetic, wrapping around the maximum value. For example, storing 65,536 in a Uint16Array actually stores 0, and storing 65,537 stores 1. This behavior differs from regular JavaScript arrays where numbers can grow arbitrarily large without overflow.
Code Example: Basic Uint16Array Creation
const uint16 = new Uint16Array(5);
console.log(uint16.length); // 5
console.log(uint16[0]); // 0
console.log(uint16.BYTES_PER_ELEMENT); // 2
Visual: Diagram showing 16-bit binary representation from 0000000000000000 to 1111111111111111 with decimal equivalents (0 to 65,535)
Creating Uint16Array Instances
The Uint16Array() constructor offers multiple ways to create instances, each serving different use cases. Understanding these patterns helps developers choose the most appropriate approach for their specific needs.
Creating from Length
// Create a Uint16Array with 5 elements, all initialized to 0
const uint16 = new Uint16Array(5);
console.log(uint16.length); // 5
console.log(uint16[0]); // 0
console.log(uint16.BYTES_PER_ELEMENT); // 2
This approach pre-allocates memory for the specified number of 16-bit elements. The array is zero-initialized, meaning all elements start at 0. This pattern is useful when you know the required size upfront and will populate the values programmatically.
Creating from Array or Iterable
// Create Uint16Array from a regular array
const fromArray = new Uint16Array([100, 200, 300, 400]);
console.log(fromArray[2]); // 300
// Create Uint16Array from any iterable (including generators)
const iterable = (function* () {
yield 10;
yield 20;
yield 30;
})();
const fromIterable = new Uint16Array(iterable);
console.log(fromIterable); // Uint16Array [10, 20, 30]
This pattern automatically converts values to the Uint16Array format, with overflow wrapping as needed.
Creating from ArrayBuffer
// Create an ArrayBuffer with 16 bytes (enough for 8 Uint16 elements)
const buffer = new ArrayBuffer(16);
// Create a Uint16Array viewing the entire buffer
const fullView = new Uint16Array(buffer);
// Create a Uint16Array viewing from byte offset 2, for 4 elements
const partialView = new Uint16Array(buffer, 2, 4);
console.log(partialView.byteOffset); // 2
The byteOffset parameter allows you to skip initial bytes, while the length parameter specifies how many elements to include. This flexibility is essential when working with binary file formats or network protocols that have structured layouts. When building web applications that process binary data, working with ArrayBuffer and typed arrays efficiently is crucial for performance.
Creating from Another TypedArray
const source = new Uint16Array([1000, 2000, 3000]);
const copy = new Uint16Array(source);
console.log(copy[1]); // 2000
This creates a copy of the source typed array's values, not a view into the same memory.
Core Properties and Constants
Uint16Array provides several important properties that are essential for working effectively with the type.
BYTES_PER_ELEMENT
This static and instance property returns the element size in bytes, which is always 2 for Uint16Array. This constant is useful when calculating buffer sizes or byte offsets programmatically:
const uint16 = new Uint16Array(100);
console.log(uint16.BYTES_PER_ELEMENT); // 2
console.log(uint16.byteLength); // 200 (100 elements × 2 bytes)
length and byteLength
The length property returns the number of elements in the array, while byteLength returns the total size in bytes:
const uint16 = new Uint16Array(50);
console.log(uint16.length); // 50
console.log(uint16.byteLength); // 100 (50 × 2)
byteOffset
This property indicates the starting byte offset of the Uint16Array within its underlying ArrayBuffer:
const buffer = new ArrayBuffer(32);
const uint16 = new Uint16Array(buffer, 8, 4);
console.log(uint16.byteOffset); // 8
console.log(uint16.length); // 4
buffer
The buffer property returns the underlying ArrayBuffer that the Uint16Array views:
const buffer = new ArrayBuffer(16);
const uint16 = new Uint16Array(buffer);
console.log(uint16.buffer === buffer); // true
Working with Uint16Array Data
Basic Element Access
Elements can be accessed and modified using standard array bracket notation:
const uint16 = new Uint16Array(3);
uint16[0] = 1000;
uint16[1] = 2000;
uint16[2] = 3000;
console.log(uint16[0]); // 1000
console.log(uint16[1]); // 2000
The set() Method
The set() method copies values from another typed array or regular array into the Uint16Array:
const uint16 = new Uint16Array(5);
// Set all values at once from a regular array
uint16.set([100, 200, 300, 400, 500]);
console.log(uint16); // Uint16Array [100, 200, 300, 400, 500]
// Set values starting at offset 2
uint16.set([1000, 2000], 2);
console.log(uint16); // Uint16Array [100, 200, 1000, 2000, 500]
The subarray() Method
The subarray() method returns a new Uint16Array view into the same ArrayBuffer, sharing the underlying memory:
const uint16 = new Uint16Array([10, 20, 30, 40, 50]);
const sub = uint16.subarray(1, 4);
console.log(sub.length); // 3
console.log(sub[0]); // 20 (same as uint16[1])
sub[0] = 999;
console.log(uint16[1]); // 999 (modification affects original)
copyWithin()
This method copies a sequence of elements within the array to another position:
const uint16 = new Uint16Array([1, 2, 3, 4, 5]);
// Copy element at index 0 to index 3
uint16.copyWithin(3, 0);
console.log(uint16); // Uint16Array [1, 2, 3, 1, 2]
Iteration Methods
Uint16Array supports standard iteration methods like forEach(), map(), filter(), reduce(), and others inherited from TypedArray:
const uint16 = new Uint16Array([10, 20, 30, 40, 50]);
// forEach iteration
uint16.forEach((value, index) => {
console.log(`Element ${index}: ${value}`);
});
// map to create new array
const doubled = uint16.map(value => value * 2);
console.log(doubled); // Uint16Array [20, 40, 60, 80, 100]
Where Uint16Array excels in real-world applications
Image Data Processing
Ideal for high-depth image processing, scientific imaging, and HDR graphics where pixel values exceed standard 8-bit (0-255) ranges.
WebGL and Graphics
Commonly used for index buffers in WebGL to reference vertices efficiently in triangle meshes and other graphics data structures.
Binary Protocol Handling
Perfect for parsing and serializing binary network protocols and file formats with 16-bit unsigned integer fields.
Audio Processing
Directly applicable for 16-bit sample audio data found in many audio systems and file formats like WAV.
Performance Benefits
Using Uint16Array and other typed arrays provides several performance advantages over regular JavaScript arrays when working with numeric data.
Memory Efficiency
Typed arrays use contiguous memory allocation with fixed-size elements. This compact representation uses less memory than regular JavaScript arrays, which must store additional metadata for each element due to JavaScript's dynamic typing. For large datasets, this memory savings can be substantial. Applications built with performance-optimized JavaScript techniques leverage typed arrays for efficient memory management.
Type Enforcement
The typed array enforces that all elements are numbers within the specified range. This eliminates the overhead of type checking and coercion that JavaScript engines must perform with regular arrays containing arbitrary values.
SIMD Optimization
Modern JavaScript engines can apply SIMD (Single Instruction, Multiple Data) optimizations to typed arrays. This allows the engine to perform the same operation on multiple elements simultaneously, significantly speeding up numeric computations.
Binary Data Efficiency
When working with binary data from files, network responses, or hardware, typed arrays eliminate the need for conversion between binary representations and JavaScript numbers. The data can be read and written directly in its native binary form. This efficiency is crucial for modern AI-powered web applications that process large volumes of data in real-time.
Uint16Array by the Numbers
16
Bits per element
2
Bytes per element
65535
Maximum value
2015
Baseline support since
Browser Compatibility and Baseline Support
Uint16Array has been widely available across all modern browsers since July 2015, making it part of the Baseline established compatibility set. The feature is supported in:
- Chrome and Edge (all versions since Chrome 7)
- Firefox (all versions since Firefox 4)
- Safari (all versions since Safari 5.1)
- Opera (all versions since Opera 12)
- All modern mobile browsers
This widespread support means Uint16Array can be used in production applications without concerns about browser compatibility for core functionality. However, some advanced features or methods may have varying support, so consulting the MDN compatibility tables is recommended for specific use cases.
Comparison with Other Typed Arrays
JavaScript provides several typed array types, each designed for specific data ranges and representations:
| Type | Element Size | Range |
|---|---|---|
| Int8Array | 1 byte | -128 to 127 |
| Uint8Array | 1 byte | 0 to 255 |
| Uint8ClampedArray | 1 byte | 0 to 255 (clamped) |
| Int16Array | 2 bytes | -32,768 to 32,767 |
| Uint16Array | 2 bytes | 0 to 65,535 |
| Int32Array | 4 bytes | ~-2.1 billion to ~2.1 billion |
| Uint32Array | 4 bytes | 0 to ~4.3 billion |
| Float32Array | 4 bytes | IEEE 754 single precision |
| Float64Array | 8 bytes | IEEE 754 double precision |
Choosing the appropriate typed array depends on your data's characteristics: signed versus unsigned values, required range, precision needs, and the native format of your data source. Understanding these options helps developers build robust, cross-platform web solutions that perform efficiently across all environments.
Best Practices
Use for Appropriate Data
Uint16Array is optimal when working with data that naturally fits within 16-bit unsigned integer representation. Using it for arbitrary data that doesn't match this pattern adds unnecessary constraints without benefit.
Consider Byte Order
Uint16Array uses the platform's native byte order (little-endian on x86/x64 systems). When working with data from different systems or in cross-platform applications, use DataView for byte-level control.
Understand Overflow Behavior
Values outside the 0-65,535 range wrap around using modulo arithmetic. If your application requires different overflow behavior, implement explicit checks before assignment.
Leverage ArrayBuffer for Memory Sharing
When multiple views of the same data are needed (for example, interpreting the same memory as both 16-bit and 8-bit data), create multiple typed array views into a single ArrayBuffer rather than copying data.
Conclusion
Uint16Array provides a specialized, efficient way to work with 16-bit unsigned integer data in JavaScript. Its fixed-size element representation, memory efficiency, and performance characteristics make it ideal for applications involving binary data processing, image manipulation, graphics programming, and numerical computation. With universal browser support and straightforward usage patterns, Uint16Array is a valuable tool for any JavaScript developer working with structured numeric data.
When building modern web applications that involve any form of binary data manipulation, from canvas image processing to WebGL graphics to network protocol handling, Uint16Array offers the performance and memory efficiency that regular JavaScript arrays cannot match. Consider using Uint16Array whenever your data naturally fits the 16-bit unsigned integer range, and you'll benefit from optimized memory usage and faster numeric operations. Our web development team specializes in implementing these performance optimizations for client projects.
Frequently Asked Questions
What is the difference between Uint16Array and regular JavaScript arrays?
Uint16Array uses contiguous memory allocation with fixed 16-bit elements, while regular JavaScript arrays are dynamic and can hold any value type. Uint16Array is more memory-efficient and faster for numeric operations, but less flexible.
What happens if I try to store a value larger than 65,535?
Values overflow using modulo arithmetic. For example, storing 65,536 results in 0, and 65,537 results in 1. This differs from regular arrays where numbers can grow arbitrarily large.
Can Uint16Array be used with big-endian systems?
Uint16Array uses platform byte order. For cross-platform binary data, use DataView which allows explicit control over byte order when reading/writing multi-byte values.
Is Uint16Array supported in all modern browsers?
Yes, Uint16Array has universal browser support since 2015. It's part of the Baseline compatibility set and works in Chrome, Firefox, Safari, Edge, and all modern mobile browsers.
When should I use Uint16Array instead of Uint8Array?
Use Uint16Array when your data values exceed 255 (Uint8Array's maximum) but fit within 65,535. This includes larger counters, color values in HDR imaging, and binary protocol fields.
How do I convert between typed arrays and regular arrays?
Use the Array.from() method to convert typed arrays to regular arrays: Array.from(uint16). To create a typed array from a regular array, pass it to the constructor: new Uint16Array(regularArray).