A TypeScript library that converts any JavaScript runtime value into its string source code representation. Supports objects, arrays, functions, circular references, cross-references, and more.
npm install @lopatnov/javascripttostring<script src="https://unpkg.com/@lopatnov/javascripttostring"></script>import javaScriptToString from "@lopatnov/javascripttostring";const javaScriptToString = require("@lopatnov/javascripttostring");const javaScriptToString = window.javaScriptToString;Converts a JavaScript value to its string source code representation.
| Parameter | Type | Description |
|---|---|---|
value |
any |
The value to convert |
options |
IJ2SOptions |
Optional configuration |
Returns: string - Source code representation that can be evaluated back to the original value
| Option | Type | Default | Description |
|---|---|---|---|
includeFunctionProperties |
boolean |
true |
Include function's own properties |
includeFunctionPrototype |
boolean |
true |
Include function's prototype properties |
includeBuffers |
boolean |
true |
Include ArrayBuffer and TypedArray contents |
nestedObjectsAmount |
number |
Infinity |
Max depth for nested objects |
nestedArraysAmount |
number |
Infinity |
Max depth for nested arrays |
nestedFunctionsAmount |
number |
Infinity |
Max depth for nested functions |
throwOnNonSerializable |
boolean |
false |
Throw an error for non-serializable values (Promise, Generator, WeakRef, WeakMap, WeakSet, FinalizationRegistry) |
javaScriptToString("Hello world"); // '"Hello world"'
javaScriptToString(42); // '42'
javaScriptToString(true); // 'true'
javaScriptToString(undefined); // 'undefined'
javaScriptToString(null); // 'null'javaScriptToString(["Hello", "World"]);
// '["Hello", "World"]'javaScriptToString({
name: "Alex",
friends: ["Shurik", "Hola"],
greet: () => {
console.log("How you doing?");
}
});
// '{name: "Alex", friends: ["Shurik", "Hola"], greet: () => { console.log("How you doing?"); }}'function Simple(title) {
this.title = title || "world";
}
Simple.count = 0;
Simple.prototype.show = function () {
Simple.count++;
console.log("title =", this.title);
};
javaScriptToString(Simple);
// '(function(){ var Simple = function Simple(title) { ... }; Simple.count = 0; Simple.prototype.show = function(){ ... }; return Simple; }())'Objects that reference themselves are fully supported:
var x = [1, 2, 3];
x[0] = x;
javaScriptToString(x);
// '(function(){ var ___ref1 = [null, 2, 3]; ___ref1[0] = ___ref1; return ___ref1; }())'Objects shared between different branches are preserved as references:
var shared = { value: 42 };
var obj = { a: shared, b: shared };
javaScriptToString(obj);
// Generates code where obj.a === obj.b (same reference):
// (function(){ var ___ref1 = {
// a: { value: 42 },
// b: null
// }; ___ref1.b = ___ref1.a; return ___ref1; }())Combine with @lopatnov/worker-from-string to serialize functions and data for execution in a Web Worker:
import javaScriptToString from "@lopatnov/javascripttostring";
import workerFromString from "@lopatnov/worker-from-string";
// Function with attached lookup data
function classify(value) {
const range = classify.ranges.find(r => value >= r.min && value < r.max);
return range ? range.label : "unknown";
}
classify.ranges = [
{ min: 0, max: 30, label: "cold" },
{ min: 30, max: 60, label: "warm" },
{ min: 60, max: 100, label: "hot" },
];
// Serialize and send to a worker
// javaScriptToString preserves the function AND its properties:
const code = javaScriptToString(classify);
const worker = workerFromString(`
const classify = ${code};
self.onmessage = (e) => postMessage(classify(e.data));
`);
worker.onmessage = (e) => console.log(e.data);
worker.postMessage(45); // "warm"The generated string can be evaluated back to a working JavaScript value:
var original = { name: "test" };
original.self = original;
var code = javaScriptToString(original);
var restored = Function("return " + code)();
console.log(restored.self === restored); // true
console.log(restored.name); // "test"| Type | Example | Notes |
|---|---|---|
| Primitives | string, number, boolean, undefined, null |
Including -0 and NaN |
| BigInt | BigInt(123) |
|
| Symbol | Symbol("desc"), Symbol.for("key") |
Registry symbols preserved |
| RegExp | /pattern/gi |
lastIndex preserved when non-zero |
| Date | new Date("...") |
Invalid dates → new Date(NaN) |
| Error | new Error(), new TypeError() |
TypeError, RangeError, ReferenceError, SyntaxError, URIError, EvalError |
| Array | [1, 2, 3] |
Sparse arrays preserved |
| Object | { key: "value" } |
Including Object.create(null) |
| Function | function() {}, () => {}, async function() {} |
Properties and prototype included |
| Generator Function | function*() {}, async function*() {} |
|
| Map | new Map([["key", "value"]]) |
|
| Set | new Set([1, 2, 3]) |
|
| TypedArray | Int8Array, Float64Array, etc. |
|
| ArrayBuffer | new ArrayBuffer(8), SharedArrayBuffer |
|
| DataView | new DataView(buffer) |
The following types cannot be serialized and return "undefined" by default. Use throwOnNonSerializable: true to throw an error instead:
Promise, Generator, WeakRef, WeakMap, WeakSet, FinalizationRegistry
Try the library interactively:
| Link | |
|---|---|
| Interactive Demo | demo/index.html |
| RunKit Playground | runkit.com |
| Link | |
|---|---|
| API Reference | docs/index.html |
| Changelog | CHANGELOG.md |
| Package | Description |
|---|---|
| @lopatnov/worker-from-string | Create Web Workers from strings — pairs well with javaScriptToString |
| @lopatnov/get-internal-type | Runtime type detection used internally by this library |
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
Copyright 2019-2026 Oleksandr Lopatnov
Oleksandr Lopatnov
If you find this project useful, please consider giving it a star on GitHub!