The Tree widget visualizes hierarchical data structures with parent-child relationships using Unicode tree characters.
When to Use
Use Tree when you need to display hierarchical data with parent-child relationships. Common scenarios:
- File system navigation: Show directory structures, project files
- Organizational hierarchies: Display team structures, reporting relationships
- Data exploration: Visualize nested JSON, XML documents, or object graphs
- Menu systems: Represent nested navigation menus or configuration options
For tabular data with rows and columns, use Table instead. For structured JSON visualization, consider Json which provides syntax highlighting.
Basic Usage
Create a tree with a root label and add child nodes using AddNode(). The method returns the added node, allowing you to chain further children.
var tree = new Tree("Project Files");
var src = tree.AddNode("src");
src.AddNode("Program.cs");
src.AddNode("Config.cs");
var docs = tree.AddNode("docs");
docs.AddNode("README.md");
docs.AddNode("API.md");
AnsiConsole.Write(tree);
Building Nested Structures
Call AddNode() on returned nodes to create deeper hierarchies. Each node can have its own children, creating multi-level trees.
var tree = new Tree("Project Structure");
var src = tree.AddNode("src");
var controllers = src.AddNode("Controllers");
controllers.AddNode("HomeController.cs");
controllers.AddNode("UserController.cs");
var models = src.AddNode("Models");
models.AddNode("User.cs");
models.AddNode("Product.cs");
var tests = tree.AddNode("tests");
tests.AddNode("UnitTests.cs");
tests.AddNode("IntegrationTests.cs");
AnsiConsole.Write(tree);
Styling Node Labels
With Markup
Use markup in node labels to apply colors, styles, and formatting to individual nodes.
var tree = new Tree("[yellow]Web Application[/]");
var frontend = tree.AddNode("[blue]Frontend[/]");
frontend.AddNode("[green]index.html[/]");
frontend.AddNode("[green]styles.css[/]");
frontend.AddNode("[green]app.js[/]");
var backend = tree.AddNode("[blue]Backend[/]");
backend.AddNode("[red]server.js[/]");
backend.AddNode("[red]database.js[/]");
AnsiConsole.Write(tree);
With Tree-Wide Styling
Use Style() to apply a consistent style to all tree guide lines, which helps create a cohesive visual appearance.
var tree = new Tree("Styled Tree")
.Style(Style.Parse("blue bold"));
tree.AddNode("Item 1");
tree.AddNode("Item 2");
tree.AddNode("Item 3");
AnsiConsole.Write(tree);
Guide Styles
The tree guide controls the appearance of the connecting lines between nodes. Choose a style based on your terminal capabilities and aesthetic preferences.
Ascii Guide
Use TreeGuide.Ascii for maximum compatibility with terminals that don't support Unicode, or when output needs to be plain text.
var tree = new Tree("Root")
.Guide(TreeGuide.Ascii);
var child1 = tree.AddNode("Child 1");
child1.AddNode("Grandchild 1.1");
child1.AddNode("Grandchild 1.2");
var child2 = tree.AddNode("Child 2");
child2.AddNode("Grandchild 2.1");
AnsiConsole.Write(tree);
Line Guide
Use TreeGuide.Line (the default) for clean Unicode box-drawing characters that work in most modern terminals.
var tree = new Tree("Root")
.Guide(TreeGuide.Line);
var child1 = tree.AddNode("Child 1");
child1.AddNode("Grandchild 1.1");
child1.AddNode("Grandchild 1.2");
var child2 = tree.AddNode("Child 2");
child2.AddNode("Grandchild 2.1");
AnsiConsole.Write(tree);
DoubleLine Guide
Use TreeGuide.DoubleLine for a more prominent appearance with double-line Unicode characters.
var tree = new Tree("Root")
.Guide(TreeGuide.DoubleLine);
var child1 = tree.AddNode("Child 1");
child1.AddNode("Grandchild 1.1");
var child2 = tree.AddNode("Child 2");
child2.AddNode("Grandchild 2.1");
AnsiConsole.Write(tree);
BoldLine Guide
Use TreeGuide.BoldLine for heavy Unicode characters that stand out in dense tree structures.
var tree = new Tree("Root")
.Guide(TreeGuide.BoldLine);
var child1 = tree.AddNode("Child 1");
child1.AddNode("Grandchild 1.1");
var child2 = tree.AddNode("Child 2");
child2.AddNode("Grandchild 2.1");
AnsiConsole.Write(tree);
Note
See the Tree Guide Reference for a complete visual comparison of all available guide styles.
Controlling Node Expansion
Collapsing Individual Nodes
Use Collapse() on individual nodes to hide their children, which is useful for large trees where you want to show only top-level structure initially.
var tree = new Tree("Project");
var expanded = tree.AddNode("Expanded Folder");
expanded.AddNode("File1.cs");
expanded.AddNode("File2.cs");
var collapsed = tree.AddNode("Collapsed Folder");
collapsed.Collapse();
collapsed.AddNode("Hidden1.cs");
collapsed.AddNode("Hidden2.cs");
AnsiConsole.Write(tree);
Collapsing the Entire Tree
Set Expanded = false on the tree itself to collapse all nodes, showing only the root.
var tree = new Tree("Project")
{
Expanded = false
};
var src = tree.AddNode("src");
src.AddNode("File1.cs");
src.AddNode("File2.cs");
var tests = tree.AddNode("tests");
tests.AddNode("Test1.cs");
AnsiConsole.Write(tree);
Advanced Usage
Adding Multiple Nodes
Use AddNodes() to add several sibling nodes at once, which is more concise than multiple AddNode() calls.
var tree = new Tree("Shopping List");
tree.AddNodes(
"Fruits",
"Vegetables",
"Dairy",
"Bakery"
);
AnsiConsole.Write(tree);
Embedding Other Renderables
Add any IRenderable (panels, tables, text) as node content to create rich, composite visualizations.
var tree = new Tree("Components");
var headerPanel = new Panel("Application Header")
.BorderColor(Color.Blue)
.Expand();
tree.AddNode(headerPanel);
var contentPanel = new Panel("Main Content Area")
.BorderColor(Color.Green)
.Expand();
tree.AddNode(contentPanel);
var footerPanel = new Panel("Footer")
.BorderColor(Color.Grey)
.Expand();
tree.AddNode(footerPanel);
AnsiConsole.Write(tree);
Building from Data Structures
Dynamically construct trees from dictionaries, file systems, or other hierarchical data sources.
var fileSystem = new Dictionary<string, string[]>
{
["Configuration"] = new[] { "appsettings.json", "secrets.json" },
["Source Code"] = new[] { "Main.cs", "Helper.cs", "Utilities.cs" },
["Documentation"] = new[] { "README.md", "CHANGELOG.md" },
};
var tree = new Tree("Application");
foreach (var (folder, files) in fileSystem)
{
var folderNode = tree.AddNode($"[yellow]{folder}[/]");
foreach (var file in files)
{
folderNode.AddNode($"[grey]{file}[/]");
}
}
AnsiConsole.Write(tree);
See Also
- Display Hierarchical Data - Step-by-step guide for tree tasks
- Tree Guide Reference - All guide styles with visual examples
- Building a Rich Console App - Learn Spectre.Console basics
- Understanding Spectre.Console's Rendering Model - How widgets measure and render
API Reference
Representation of non-circular tree data. Each node added to the tree may only be present in it a single time, in order to facilitate cycle detection.
Constructors
Tree(IRenderable renderable)Initializes a new instance of the class.
Parameters:
renderable (IRenderable)Tree(string label)Initializes a new instance of the class.
Parameters:
label (string)Properties
Expanded
: boolGets or sets a value indicating whether or not the tree is expanded or not.
Guide
: TreeGuideGets or sets the tree guide lines.
Nodes
: List<TreeNode>Gets the tree's child nodes.
Style
: StyleGets or sets the tree style.
Extension Methods
IEnumerable<Segment> GetSegments(IAnsiConsole console)Gets the segments for a renderable using the specified console.
Parameters:
console (IAnsiConsole)Returns:
An enumerable containing segments representing the specified .
Tree Guide(TreeGuide guide)Sets the tree guide line appearance.
Parameters:
guide (TreeGuide)Returns:
The same instance so that multiple calls can be chained.
Tree Style(Style style)Sets the tree style.
Parameters:
style (Style)Returns:
The same instance so that multiple calls can be chained.