tree Command: Visualizing Directory Structure

tree Command: Visualizing Directory Structure

What You'll Learn

  • How to grasp a directory structure at a glance with tree
  • How to limit depth with -L so even huge folders stay readable
  • How to narrow output with -d, -a, and -I
  • How to move from repeated ls calls to a single structural view

Who this is for: Linux beginners, and anyone tired of ls and cd to navigate folders

Intro: Lina's "Lost in ls" Moment

Lina: Linny-senpai, I wanted to check how a project folder is organized, so I keep doing ls, then cd, then ls again... but I just can't picture the whole structure.
Linny-senpai: Ah, the classic "lost in ls" problem. Diving in one level at a time and backing out makes you lose track of where you are.
Lina: Exactly! I want to draw it out on paper.
Linny-senpai: That "drawn-out diagram" is exactly what the tree command gives you in one shot. It shows a folder's contents as a branching diagram. Let's learn it today.

Quick Summary

  • tree = a command that visualizes directory structure as a tree (branching diagram)
  • Run tree for the current location, or tree PATH to target a specific place
  • For huge folders, tree -L 2 (limit depth) and tree -I 'node_modules' (exclude) are essential

1. What Is tree?

Conclusion: tree displays a folder's contents as a branching diagram, so you see the whole hierarchy without running ls over and over.

Lina: How is tree different from ls?
Linny-senpai: ls lists only the contents of one location. tree walks down through all the levels below and shows them as a branching diagram.
Lina: So it's like running ls automatically in every folder?
Linny-senpai: That's the right idea. And because parent-child relationships are drawn with connecting lines, you instantly see which folder a given config file lives under.

Here is what the output looks like.

.
├── README.md
├── src
│   ├── index.js
│   └── utils
│       └── format.js
└── tests
    └── index.test.js

3 directories, 4 files

How to read the diagram

  • ├── / └──: a file or folder at that level (└── is the last item)
  • : a vertical line showing the branch continues below
  • Indentation depth = hierarchy depth
  • Last line: the total number of directories and files

2. Installation

Conclusion: tree is often not installed by default. Install it with apt or dnf.

Lina: I want to try it right away! How do I install it?
Linny-senpai: On some distributions it isn't there out of the box. If tree prints "command not found," install it.
# Ubuntu / Debian
$ sudo apt install tree

# RHEL / Fedora
$ sudo dnf install tree

# macOS (Homebrew)
$ brew install tree

The package name is tree on every distribution. After installing, run tree --version to confirm the version.

3. Basic Usage

Conclusion: Run tree with no arguments to show the current directory; use tree PATH to target a specific location.

Linny-senpai: Usage is very simple. Let's start with no arguments.

Show the current directory

# Show the contents below your current location
$ tree

Target a specific path

# Show a given directory
$ tree /etc

# Show your home directory
$ tree ~
Lina: Just typing tree printed everything down to the deepest level! ...Though it scrolled off the screen a bit.
Linny-senpai: Right, that's the first pitfall. By default, tree walks all the way down to the bottom level. So running it as-is on a large folder makes the screen scroll like a waterfall. Next let's learn how to rein that in.

4. Limit the Depth (-L)

Conclusion: Use tree -L NUMBER to limit how many levels are shown. For huge folders, start with -L 1 or -L 2 to grasp the big picture.

Lina: How do I stop it from printing too much like before?
Linny-senpai: Use -L (Level). -L 2 shows only down to the second level. That lets you quickly see just the overall shape.
# One level only (direct contents, close to ls)
$ tree -L 1

# Down to two levels
$ tree -L 2 /var/log
/var/log
├── apt
│   ├── history.log
│   └── term.log
├── journal
├── syslog
└── dpkg.log

2 directories, 4 files

When to use -L

  • For a folder you're seeing for the first time, drill down from shallow to deep: tree -L 1 then -L 2
  • Specify depth as an integer of 1 or more (-L 0 is an error)
  • Go shallow when you want a "map," deeper for a specific folder's details

5. Narrow Down What's Shown

Conclusion: -d shows directories only, -a includes hidden files, and -I excludes unwanted folders.

Linny-senpai: After depth, the next step is choosing what to show. Master this and tree becomes far more practical.

Directories only (-d)

# When you only want the folder structure
$ tree -d -L 2
Lina: That looks handy when there are too many files and I only want the folder skeleton!
Linny-senpai: Exactly. -d (directory) hides every file and shows only the folder skeleton. It's great when explaining how a project is organized.

Include hidden files (-a)

# Show dot-prefixed entries like .git and .env too
$ tree -a -L 1

tree hides hidden files by default

Files starting with a dot (.), like .bashrc or .git, are not shown unless you add -a (all). If a config file seems missing, check whether you forgot -a.

Exclude unwanted folders (-I)

# Exclude node_modules from the output
$ tree -I 'node_modules'

# Exclude several, separated by |
$ tree -I 'node_modules|.git|dist'
Lina: node_modules has tens of thousands of files, so tree just scrolls forever, right...
Linny-senpai: That's the one! So -I (Ignore) is the standard fix. Separate patterns with | (pipe) to exclude several. node_modules, .git, and dist are the usual suspects.

Conversely, to see "only these," use -P

When you want to show only a certain pattern, use -P (Pattern). tree -P '*.js' keeps only .js files. If empty folders get in the way, add --prune to drop folders that don't contain a matching file.

6. Make It Readable and Show Sizes

Conclusion: -F adds type indicators, -h --du shows cumulative directory sizes, and -o FILE saves the output to a file.

Lina: Is there a way to add a bit more information?
Linny-senpai: Plenty. Showing file types and sizes alongside the tree makes investigation much easier.

Add type indicators (-F)

# Append / to directories and * to executables
$ tree -F -L 1

You get the same indicators as ls -F. A trailing / means a folder, and * marks an executable file at a glance.

Show sizes (-h / --du)

# Show each file's size in human-readable units
$ tree -h

# Also show directory sizes (cumulative)
$ tree -h --du -L 1

What --du means

--du shows each directory's size as the sum of the files beneath it (the same idea as the du command). Combined with -h (human readable), you get readable units like 1.2K or 3.4M. It's handy for a rough sense of which folder is eating space.

Lina: If it shows sizes, can I use it for disk usage like ncdu?
Linny-senpai: As a static snapshot, sure. But for interactive investigation, drilling down with arrow keys or deleting on the spot, ncdu is the better fit. Think of tree as "draw the structure" and ncdu as "hunt down and clean up space."

Save the result to a file (-o)

# Write the tree to a text file
$ tree -L 2 -o structure.txt

When adding a "Directory structure" section to a README, paste the output of tree -L 2 for an instant layout diagram. Strip noise with -I before pasting for a clean result.

7. Mini Exercises: Try It in Your Own Environment

Conclusion: Three tasks (depth limit, directories only, exclude) lock in tree's practical options.

Linny-senpai: To cement what you've learned, try these in your own environment.

Task 1: Run tree -L 1 on your home directory to see what sits directly under it.

Task 2: Run tree -d -L 2 ~ to show only the folder skeleton under your home.

Task 3: In any project folder, run tree -I '.git' and confirm that .git is excluded.

Hint for Task 1
tree -L 1 ~

Limiting to a single level with -L 1 lists just the direct contents as a tree, like ls.

Hint for Task 2
tree -d -L 2 ~

-d hides files and -L 2 limits depth to two levels, so only the folder skeleton shows.

Hint for Task 3
tree -I '.git'

Write the name to exclude after -I. .git disappears, leaving just the source structure. To exclude several, separate them with |, like '.git|node_modules'.

8. Common Pitfalls

Conclusion: Watch out for running unlimited depth on huge folders, forgetting hidden files, and forgetting to quote exclude patterns.

Three frequent mistakes

  1. Running without -L on a large folder -> the screen scrolls like a waterfall on node_modules and friends. Start with -L 1 or -L 2.
  2. Panicking when hidden files don't appear -> tree hides dot-prefixed entries by default. Check whether you forgot -a.
  3. Forgetting to quote the exclude pattern -> without single quotes, as in -I node_modules|.git, the shell interprets | as a pipe and you get unexpected behavior. The correct form is -I 'node_modules|.git'.

Safe, practical patterns

  • First look at a folder: tree -L 2 (shallow overview)
  • Explaining a layout: tree -d -L 2 (skeleton only)
  • Browsing a repo: tree -L 2 -I 'node_modules|.git|dist' (drop the noise)

Next Reading