# How to Create a New Tree in treelib: A Complete Guide

> Learn to create a new tree in treelib. Instantiate the Tree class and use create_node to establish a root and attach children. A complete guide for efficient tree management.

- Repository: [Xiaming Chen/treelib](https://github.com/caesar0301/treelib)
- Tags: how-to-guide
- Published: 2026-02-26

---

**Create a new tree in treelib by instantiating the `Tree` class, then call `create_node()` to establish a root without a `parent` parameter, and attach children by specifying their parent identifiers.**

The `treelib` library provides a pure Python implementation for managing hierarchical tree structures. Whether you need to model organizational charts, file systems, or decision trees, understanding how to properly initialize and populate a `Tree` object is essential. This guide walks through the exact implementation details found in the `caesar0301/treelib` repository.

## Core Architecture of treelib

### The Tree Container

The `Tree` class serves as the primary container that manages all nodes, tracks the root identifier, and provides traversal and manipulation APIs. According to the source code in [`treelib/tree.py`](https://github.com/caesar0301/treelib/blob/main/treelib/tree.py) (lines 82-101), the `Tree` class initializes with an internal node dictionary and optional identifier.

### The Node Building Blocks

Each element in the hierarchy is represented by the `Node` class, defined in [`treelib/node.py`](https://github.com/caesar0301/treelib/blob/main/treelib/node.py) (lines 47-60). Nodes store tags, unique identifiers, optional data payloads, and maintain parent/children relationships.

## Instantiating an Empty Tree

To create a new tree in treelib, start by calling the `Tree` constructor with no arguments:

```python
from treelib import Tree

tree = Tree()

```

The `Tree.__init__` method (lines 69-101 in [`treelib/tree.py`](https://github.com/caesar0301/treelib/blob/main/treelib/tree.py)) creates an internal node dictionary (`self._nodes`), generates a unique tree identifier, and prepares a placeholder for the root node. You can optionally pass a `node_class` parameter to use custom node implementations, provided they subclass `Node`.

## Adding the Root Node

The first node added to a tree becomes the root. You must call `create_node` without specifying a `parent` parameter:

```python
tree.create_node(tag="Root", identifier="root")

```

According to the implementation in [`treelib/tree.py`](https://github.com/caesar0301/treelib/blob/main/treelib/tree.py) (lines 825-876), the `create_node` method validates that the tree is empty before allowing a root creation. If you attempt to create a second root without a parent, the library raises a `MultipleRootError` (documented in the method docstring at lines 49-52).

## Building the Hierarchy with Child Nodes

Once the root exists, attach child nodes by specifying the `parent` parameter with the identifier of the existing node:

```python
tree.create_node(tag="Child A", identifier="child_a", parent="root")
tree.create_node(tag="Child B", identifier="child_b", parent="root")

```

The `create_node` method processes the `parent` parameter through the internal `add_node` logic. If the specified parent identifier does not exist in `self._nodes`, the library raises a `NodeIDAbsentError` (see docstring lines 44-53 in [`treelib/tree.py`](https://github.com/caesar0301/treelib/blob/main/treelib/tree.py)). The tree maintains an O(1) lookup table for fast parent validation and node retrieval.

## Complete Working Example

The repository's [`examples/getting_started.py`](https://github.com/caesar0301/treelib/blob/main/examples/getting_started.py) (lines 22-36) demonstrates the complete workflow:

```python
from treelib import Tree

def lesson_1_creating_trees():
    tree = Tree()
    tree.create_node("Root", "root")
    tree.show()
    
    # Add children

    tree.create_node("Child1", "child1", parent="root")
    tree.create_node("Child2", "child2", parent="root")
    tree.show()

if __name__ == "__main__":
    lesson_1_creating_trees()

```

Running this script produces:

```

Root
├── Child1
└── Child2

```

## Advanced Tree Creation Techniques

### Using Custom Node Classes

You can extend the `Node` class to add custom attributes:

```python
from treelib import Tree, Node

class MyNode(Node):
    def __init__(self, tag, identifier=None):
        super().__init__(tag, identifier)
        self.custom_attr = "extra"

tree = Tree(node_class=MyNode)
tree.create_node("Root", "root")
print(tree["root"].custom_attr)  # Output: extra

```

The `Tree` constructor validates that custom node classes subclass `Node` (lines 22-24 in [`treelib/tree.py`](https://github.com/caesar0301/treelib/blob/main/treelib/tree.py)).

### Building from Dictionary Data

Convert nested dictionaries to trees recursively:

```python
import uuid
from treelib import Tree

def dict_to_tree(d, parent_id=None, tree=None):
    if tree is None:
        tree = Tree()
    for key, value in d.items():
        node_id = str(uuid.uuid4())
        tree.create_node(tag=key, identifier=node_id, parent=parent_id)
        if isinstance(value, dict):
            dict_to_tree(value, parent_id=node_id, tree=tree)
    return tree

sample = {"A": {"B": {}, "C": {"D": {}}}}
my_tree = dict_to_tree(sample)
my_tree.show()

```

## Summary

- **Instantiate** a new tree with `Tree()` from [`treelib/tree.py`](https://github.com/caesar0301/treelib/blob/main/treelib/tree.py).
- **Create the root** by calling `create_node()` without a `parent` parameter; this triggers the root assignment logic in lines 825-876.
- **Add children** by specifying the `parent` identifier in subsequent `create_node()` calls.
- **Validate** that parent identifiers exist to avoid `NodeIDAbsentError`, and avoid creating multiple roots to prevent `MultipleRootError`.
- **Customize** node behavior by passing a `node_class` subclass to the `Tree` constructor.

## Frequently Asked Questions

### What happens if I try to create a second root node?

If you call `create_node()` without a `parent` parameter on a tree that already contains a root, the library raises a `MultipleRootError`. According to the source code in [`treelib/tree.py`](https://github.com/caesar0301/treelib/blob/main/treelib/tree.py) (lines 49-52), the tree strictly enforces a single-root hierarchy unless you explicitly create a new `Tree` instance.

### Can I use custom identifiers instead of auto-generated UUIDs?

Yes. The `identifier` parameter in `create_node()` accepts any hashable value, including strings, integers, or UUIDs. The implementation in [`treelib/tree.py`](https://github.com/caesar0301/treelib/blob/main/treelib/tree.py) (lines 825-876) stores these identifiers in the internal `self._nodes` dictionary, requiring only that they remain unique within the tree.

### How do I check if a tree is empty before adding the root?

You can verify that a tree has no nodes by checking `len(tree)` or accessing the `tree.root` property. An empty tree returns `None` for `tree.root` and has a length of zero. The `Tree.__init__` method in [`treelib/tree.py`](https://github.com/caesar0301/treelib/blob/main/treelib/tree.py) (lines 69-101) initializes these empty states before any nodes are added.

### Is treelib thread-safe for concurrent tree creation?

The `treelib` library does not implement internal locking mechanisms. While creating separate `Tree` instances in different threads is safe, concurrently modifying a single `Tree` instance from multiple threads requires external synchronization. The source code in [`treelib/tree.py`](https://github.com/caesar0301/treelib/blob/main/treelib/tree.py) uses standard Python dictionaries for node storage, which are not thread-safe for concurrent writes.