Recursive Length Prefix (RLP) encoding and decoding library for Node.js and browser environments, fundamental for Ethereum ecosystem data serialization
npx @tessl/cli install tessl/npm-rlp@3.0.0RLP is a comprehensive implementation of Recursive Length Prefix encoding and decoding for Node.js and browser environments. RLP is a fundamental serialization method used throughout the Ethereum ecosystem for encoding arbitrarily nested arrays of binary data. This zero-dependency library provides a simple API with encode() and decode() functions that handle arrays, Uint8Arrays, strings, numbers, and nested data structures with high performance.
npm install rlpimport RLP from "rlp";
import { encode, decode, Input, NestedUint8Array, Decoded, utils } from "rlp";For CommonJS:
const RLP = require("rlp");
const { encode, decode, utils } = require("rlp");import RLP from "rlp";
// Encode various data types
const encodedString = RLP.encode("hello");
const encodedNumber = RLP.encode(42);
const encodedArray = RLP.encode(["cat", "dog"]);
const encodedNested = RLP.encode([[], [[]], [[], [[]]]]);
// Decode RLP data
const decoded = RLP.decode(encodedArray);
// Result: ["cat", "dog"] as Uint8Array | NestedUint8Array
// Stream decoding (returns remainder)
const streamResult = RLP.decode(encodedData, true);
// Result: { data: Uint8Array | NestedUint8Array, remainder: Uint8Array }RLP implements the Recursive Length Prefix specification with several key components:
Encodes various JavaScript data types into RLP format according to the Ethereum specification.
/**
* RLP Encoding based on https://eth.wiki/en/fundamentals/rlp
* This function takes in data, converts it to Uint8Array if not,
* and adds a length for recursion.
* @param input - Will be converted to Uint8Array
* @returns Uint8Array of encoded data
*/
function encode(input: Input): Uint8Array;Usage Examples:
import { encode } from "rlp";
// Encode a string
const encodedString = encode("hello");
// Encode a number
const encodedNumber = encode(42);
// Encode an array
const encodedArray = encode(["cat", "dog"]);
// Encode nested arrays
const encodedNested = encode([[], [[]], [[], [[]]]]);
// Encode mixed types
const encodedMixed = encode([42, "hello", [1, 2, 3]]);Decodes RLP-encoded data back to nested Uint8Array structures. Supports both complete and stream decoding modes.
/**
* RLP Decoding based on https://eth.wiki/en/fundamentals/rlp
* @param input - Will be converted to Uint8Array
* @param stream - Is the input a stream (false by default)
* @returns decoded Array of Uint8Arrays containing the original message
*/
function decode(input: Input, stream?: false): Uint8Array | NestedUint8Array;
function decode(input: Input, stream?: true): Decoded;Usage Examples:
import { decode } from "rlp";
// Standard decoding (throws if remainder exists)
const decoded = decode(encodedData);
// Stream decoding (returns data and remainder)
const streamResult = decode(encodedData, true);
console.log(streamResult.data);
console.log(streamResult.remainder);
// Decode from hex string
const decodedFromHex = decode("0xc88363617483646f67");The library provides a default export object containing both encode and decode functions.
const RLP: {
encode: (input: Input) => Uint8Array;
decode: {
(input: Input, stream?: false): Uint8Array | NestedUint8Array;
(input: Input, stream?: true): Decoded;
};
};Usage Example:
import RLP from "rlp";
const encoded = RLP.encode(["hello", "world"]);
const decoded = RLP.decode(encoded);Helper functions for byte manipulation and data conversion operations.
const utils: {
/** Convert Uint8Array to hexadecimal string representation */
bytesToHex: (uint8a: Uint8Array) => string;
/** Concatenate multiple Uint8Arrays into a single Uint8Array */
concatBytes: (...arrays: Uint8Array[]) => Uint8Array;
/** Convert hexadecimal string to Uint8Array */
hexToBytes: (hex: string) => Uint8Array;
/** Convert UTF-8 string to Uint8Array using TextEncoder */
utf8ToBytes: (utf: string) => Uint8Array;
};Usage Examples:
import { utils } from "rlp";
// Convert bytes to hex
const hex = utils.bytesToHex(new Uint8Array([72, 101, 108, 108, 111]));
// Result: "48656c6c6f"
// Convert hex to bytes
const bytes = utils.hexToBytes("48656c6c6f");
// Result: Uint8Array([72, 101, 108, 108, 111])
// Convert UTF-8 string to bytes
const utf8Bytes = utils.utf8ToBytes("hello");
// Concatenate byte arrays
const combined = utils.concatBytes(
new Uint8Array([1, 2, 3]),
new Uint8Array([4, 5, 6])
);
// Result: Uint8Array([1, 2, 3, 4, 5, 6])Command-line interface for encoding and decoding RLP data directly from the terminal.
# Encode JSON data to RLP
rlp encode '["cat", "dog"]'
# Output: 0xc88363617483646f67
# Decode RLP data to JSON
rlp decode 0xc88363617483646f67
# Output: ["cat","dog"]
# Encode simple values
rlp encode '5'
# Output: 0x05
# Encode nested arrays
rlp encode '[5]'
# Output: 0xc105/** Union type for all valid RLP input data types */
type Input = string | number | bigint | Uint8Array | Array<Input> | null | undefined;
/** Nested array structure of Uint8Arrays representing decoded RLP data */
type NestedUint8Array = Array<Uint8Array | NestedUint8Array>;
/** Result structure for stream decoding operations */
interface Decoded {
/** The decoded data as Uint8Array or nested structure */
data: Uint8Array | NestedUint8Array;
/** Any remaining bytes not consumed during decoding */
remainder: Uint8Array;
}The library throws descriptive errors for various invalid conditions:
Common Error Examples:
import { decode } from "rlp";
try {
decode("invalid-hex");
} catch (error) {
// Error: hexToBytes: received invalid unpadded hex
}
try {
decode(new Uint8Array([0xef, 0xde, 0xbd]));
} catch (error) {
// Error: invalid RLP (safeSlice): end slice of Uint8Array out-of-bounds
}