Object Tree Rendering
Render objects as ASCII tree structures
Last updated:
Object Tree Rendering
The renderObjectTree utility function converts JavaScript objects into visually appealing ASCII tree structures. This is useful for debugging, documentation, or displaying hierarchical data.
Installation
renderObjectTree is exported as a separate module to reduce bundle size:
import { renderObjectTree } from "@visulima/pail/object-tree";Basic Usage
import { renderObjectTree } from "@visulima/pail/object-tree";
const user = {
name: "Alice Johnson",
age: 28,
email: "alice@example.com",
active: true,
};
console.log(renderObjectTree(user));Output:
├─ name: Alice Johnson
├─ age: 28
├─ email: alice@example.com
└─ active: trueNested Objects
Works seamlessly with nested object structures:
const config = {
server: {
host: "localhost",
port: 3000,
ssl: {
enabled: true,
cert: "/path/to/cert.pem",
},
},
database: {
type: "postgresql",
connection: {
host: "db.example.com",
port: 5432,
},
},
};
console.log(renderObjectTree(config));Output:
├─ server
│ ├─ host: localhost
│ ├─ port: 3000
│ └─ ssl
│ ├─ enabled: true
│ └─ cert: /path/to/cert.pem
└─ database
├─ type: postgresql
└─ connection
├─ host: db.example.com
└─ port: 5432Custom Styling
Customize the tree appearance:
const data = {
project: "MyApp",
version: "2.1.0",
contributors: 15,
};
console.log(
renderObjectTree(data, {
keyNeighbour: "├── ",
keyNoNeighbour: "└── ",
separator: " → ",
spacerNeighbour: "│ ",
spacerNoNeighbour: " ",
}),
);Custom Render Function
Format values with a custom render function:
const metrics = {
responseTime: 145, // milliseconds
errorRate: 0.02, // percentage
uptime: 99.9, // percentage
requestsPerSecond: 1250,
};
console.log(
renderObjectTree(metrics, {
renderFn: (node) => {
if (typeof node === "number") {
if (node < 1) {
return `${(node * 100).toFixed(2)}%`;
}
if (node > 1000) {
return `${(node / 1000).toFixed(1)}k`;
}
return node.toString();
}
return ["boolean", "string"].includes(typeof node) ? String(node) : undefined;
},
}),
);Output:
├─ responseTime: 145
├─ errorRate: 2.00%
├─ uptime: 99.90%
└─ requestsPerSecond: 1.3kSorting Keys
Sort object keys alphabetically or with a custom function:
const unsorted = {
zebra: "animal",
apple: "fruit",
banana: "fruit",
car: "vehicle",
};
console.log(
renderObjectTree(unsorted, {
sortFn: (a, b) => a.localeCompare(b),
}),
);Circular Reference Handling
Detects and handles circular references:
const circularObj = {
name: "Circular Example",
data: [1, 2, 3],
};
// Create circular reference
circularObj.self = circularObj;
console.log(
renderObjectTree(circularObj, {
breakCircularWith: " [↻ CIRCULAR]",
}),
);Output:
├─ name: Circular Example
├─ data: [1,2,3]
└─ self: [↻ CIRCULAR]Array Output
Get output as an array of lines instead of a single string:
const obj = {
method: "GET",
status: 200,
cached: false,
};
const lines = renderObjectTree(obj, { joined: false });
lines.forEach((line, index) => {
console.log(`${index + 1}: ${line}`);
});Options
ObjectTreeOptions
interface ObjectTreeOptions {
/** Text to display for circular references (default: " (circular ref.)") */
breakCircularWith?: string | null;
/** Whether to return as single string or array of lines (default: true) */
joined?: boolean;
/** Connector for neighbor keys (default: "├─ ") */
keyNeighbour?: string;
/** Connector for non-neighbor keys (default: "└─ ") */
keyNoNeighbour?: string;
/** Function to render node values (default: renders primitives) */
renderFn?: (node: unknown) => string | undefined;
/** Separator between key and value (default: ": ") */
separator?: string;
/** Function to sort object keys (default: natural order) */
sortFn?: (a: string, b: string) => number;
/** Spacer for neighbor branches (default: "│ ") */
spacerNeighbour?: string;
/** Spacer for non-neighbor branches (default: " ") */
spacerNoNeighbour?: string;
}Use Cases
- Debugging: Visualize complex nested objects
- Documentation: Display configuration structures
- CLI Tools: Show hierarchical data in terminal
- Logging: Format object metadata for logs
Browser and Server Support
renderObjectTree works in both Node.js and Browser environments. It's a pure utility function with no platform-specific dependencies.
Related
- Basic Usage - Basic logging operations
- Examples - Real-world examples