How to Import a treelib Tree from JSON: 2 Proven Methods

You can import a treelib tree from JSON by either converting the JSON structure into a child‑parent mapping and calling Tree.from_map(), or by recursively walking the nested dictionary and invoking Tree.create_node() for each entry.

The treelib library represents hierarchical data as a collection of Node objects linked through parent‑child relationships. While the library provides a built‑in export mechanism via Tree.to_json() (implemented in treelib/tree.py at line 1981), it does not ship with a symmetrical from_json() loader. Reconstructing a tree therefore requires manually parsing the JSON and rebuilding the node hierarchy using one of two idiomatic approaches.

Why treelib Lacks a Native JSON Import

Tree.to_json() serializes the entire hierarchy into a nested dictionary format where each node is represented by its tag, optional data payload, and a "children" list. However, the maintainers have not implemented a reverse operation in the core API. According to the source in treelib/tree.py, the from_map() class method (line 2124) is the intended entry point for bulk‑loading flat structures, while complex nested imports are left to user‑land code as demonstrated in examples/json_trees.py (line 202).

Method 1: Import Using Tree.from_map() (Flat Structure)

The fastest way to reconstruct a tree is to flatten the JSON into a child‑parent map—a dictionary where keys are node identifiers and values are their parent identifiers (or None for the root). Tree.from_map() consumes this mapping and automatically creates the corresponding nodes.

This approach works best when your JSON represents a simple hierarchy without deep metadata or when you can easily extract parent references.

import json
from treelib import Tree

# Sample JSON produced by Tree.to_json()

json_str = '{"Company": {"children": [{"Engineering": {"children": []}}, {"Sales": {}}]}}'
tree_dict = json.loads(json_str)

# Flatten nested JSON into {child_id: parent_id}

def build_map(d, parent=None, out=None):
    out = out or {}
    for tag, content in d.items():
        node_id = tag.lower().replace(' ', '_')
        out[node_id] = parent
        if isinstance(content, dict) and "children" in content:
            for child in content["children"]:
                build_map(child, node_id, out)
    return out

child_parent_map = build_map(tree_dict)

# Reconstruct the tree

tree = Tree.from_map(child_parent_map)
tree.show()

Method 2: Recursive Reconstruction (Nested Structure)

When you need to preserve node data payloads or maintain the exact structure produced by Tree.to_json(), use a recursive parser. The official example in examples/json_trees.py demonstrates a parse_dict_node helper that walks the nested dictionary and calls Tree.create_node() for every entry.

This method is more flexible because it handles arbitrary nesting levels and can restore custom data attributes if you exported them with with_data=True.

import json
from treelib import Tree

def json_to_tree(json_str):
    data = json.loads(json_str)
    tree = Tree()

    def parse_dict_node(node_data, parent_id=None):
        """Recursively create nodes from nested dict structure."""
        if isinstance(node_data, str):
            nid = f"node_{len(tree._nodes)}"
            tree.create_node(tag=node_data, identifier=nid, parent=parent_id)
            return

        if isinstance(node_data, dict):
            for tag, content in node_data.items():
                nid = f"node_{len(tree._nodes)}"
                tree.create_node(tag=tag, identifier=nid, parent=parent_id)

                # Recurse into children if present

                if isinstance(content, dict) and "children" in content:
                    for child in content["children"]:
                        parse_dict_node(child, nid)

    # Process single root entry

    for root_tag, root_content in data.items():
        root_id = "root"
        tree.create_node(tag=root_tag, identifier=root_id)
        if isinstance(root_content, dict) and "children" in root_content:
            for child in root_content["children"]:
                parse_dict_node(child, root_id)
        break  # Assume single root

    return tree

# Example usage

json_input = '{"Menu": {"children": [{"Drinks": {"children": []}}, {"Desserts": {}}]}}'
menu_tree = json_to_tree(json_input)
menu_tree.show()

Handling Data Payloads and Custom Attributes

When exporting, Tree.to_json(with_data=True) serializes the optional data attribute of each Node. To round‑trip this information during import, extend the recursive parser to extract the "data" key from the JSON object and pass it to Tree.create_node(data=...).

If you use the from_map() approach, you must maintain a separate lookup for data payloads because the flat mapping only tracks relationships, not content.

Summary

  • treelib exports trees via Tree.to_json() but requires manual reconstruction for imports.
  • Use Tree.from_map() (in treelib/tree.py, line 2124) when you can flatten the JSON into a simple child‑parent dictionary.
  • Use recursive parsing (as shown in examples/json_trees.py, line 202) to handle nested JSON structures and preserve node data payloads.
  • Both methods ultimately rely on Tree.create_node() to populate the tree hierarchy.

Frequently Asked Questions

Does treelib have a built‑in from_json method?

No. The library provides Tree.to_json() for serialization (located in treelib/tree.py at line 1981), but it does not ship with a corresponding from_json() loader. You must implement the import logic using Tree.from_map() or a recursive parser.

What format does Tree.to_json() produce?

The method outputs a nested JSON dictionary where each node is represented by its tag as the key, and the value contains an optional "data" field and a "children" list holding child nodes. This structure mirrors the internal Node hierarchy.

How do I preserve node data when importing from JSON?

When exporting, pass with_data=True to to_json(). During import, extract the "data" field from each JSON node and pass it as the data parameter to Tree.create_node(). The recursive reconstruction method handles this naturally by inspecting the JSON content for data attributes.

Which import method should I use for large trees?

For large trees with thousands of nodes, the Tree.from_map() approach is typically faster because it creates all nodes in bulk without recursive function call overhead. Flatten your JSON into a child‑parent dictionary first, then pass it to from_map().

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →