tree Command in Linux: Display Directory Structure

The ls command
shows the contents of one directory at a time. When you want to see how a whole project is laid out, running ls in every subdirectory gets old fast. The tree command solves this by listing a directory and everything below it as an indented tree, so you can take in the entire hierarchy at a glance.
This guide explains how to install tree and use it to display directory structures, limit depth, filter files, show sizes, and save the output to a file.
Installing tree
tree is a small utility that is not installed by default on most distributions, but it is available in the standard repositories.
On Ubuntu, Debian, and derivatives:
sudo apt update
sudo apt install treeOn Fedora, RHEL, and derivatives:
sudo dnf install treeOnce installed, verify the version:
tree --versionBasic Usage
The general syntax of the tree command is as follows:
tree [OPTIONS] [DIRECTORY]When invoked without arguments, tree lists the current directory recursively. For example, running it inside a small Node.js project produces output like this:
tree.
├── package.json
├── README.md
└── src
├── app.js
└── utils
└── helpers.js
3 directories, 4 filesEach level of nesting is indented and connected with line-drawing characters, so helpers.js is clearly inside src/utils. The report line at the bottom counts everything in the listing, and since tree 2.1 that count includes the starting directory itself.
To list a different directory, pass its path as an argument:
tree /etc/nginxLimiting the Depth
On a large directory the default recursive listing can print thousands of lines. The -L option limits how many levels deep tree descends:
tree -L 2 /var/logWith -L 2, tree shows the contents of /var/log and one level of subdirectories, then stops. This is usually the first option to reach for when a plain tree floods the terminal.
Showing Hidden Files
Like ls, tree skips hidden files by default. Use -a to include entries that start with a dot:
tree -a.
├── .env
├── .git
│ ├── config
│ └── HEAD
├── package.json
├── README.md
└── src
├── app.js
└── utils
└── helpers.js
4 directories, 7 filesNotice that .env and the .git directory now show up in the listing. Combining -a with -L 1 is a quick way to audit what actually lives in a directory, dotfiles included.
Listing Directories Only
When you only care about the folder structure and not the files, use -d:
tree -d.
└── src
└── utils
3 directoriesThe files are gone and only the directory skeleton remains, which is handy for documenting a project layout.
Displaying File Sizes
The -s option prints the size of each file in bytes. In practice you will almost always use -h instead, which prints the sizes in human-readable units:
tree -h[4.0K] .
├── [ 412] package.json
├── [1.2K] README.md
└── [4.0K] src
├── [3.4K] app.js
└── [4.0K] utils
└── [ 890] helpers.js
3 directories, 4 filesThe size shown next to a directory is the size of the directory entry itself, not its contents. To get cumulative directory sizes, add --du:
tree --du -hWith --du, each directory reports the total size of everything inside it, similar to the du command
. This option reads the full hierarchy before printing, so it can take time and consume extra memory on a large directory tree.
Filtering by Pattern
The -P option lists only files that match a wildcard pattern. Quote the pattern so the shell does not expand it first:
tree -P "*.js"Directories are still shown even when they contain no matching files. Add --prune to remove the empty branches:
tree -P "*.js" --prune.
└── src
├── app.js
└── utils
└── helpers.js
3 directories, 2 filesOnly the JavaScript files and the directories that lead to them remain. The patterns follow the same rules as shell globs; see our guide to Linux wildcards and globbing for the full syntax.
The -I option does the opposite and excludes matching entries. Multiple patterns are separated with |:
tree -I "node_modules|.git"This is the most common tree invocation in day-to-day work, since it hides the noise of dependency and VCS directories. In tree 2.0 and later you can also pass --gitignore to skip everything that the project’s .gitignore files exclude.
Printing Full Paths
By default each entry shows only its own name. The -f option prints the full path prefix instead:
tree -f srcsrc
├── src/app.js
└── src/utils
└── src/utils/helpers.js
2 directories, 2 filesFull paths are useful in saved listings because each entry keeps its context even when you view the output away from the original directory.
Sorting the Output
Entries are sorted alphabetically by default. The most useful alternatives are:
-t- Sort by last modification time, oldest first.-r- Reverse the current sort order.-v- Sort version strings naturally, sofile2comes beforefile10.--sort=size- Sort by file size.
Note that -t places the oldest entries first, which is the opposite of what ls -t does. To see the most recently modified files at the top of each directory, combine it with -r:
tree -t -rSaving the Output to a File
The -o option writes the tree to a file instead of the terminal:
tree -o structure.txtThe line-drawing characters are UTF-8 by default. If the file is destined for an environment that cannot render them, force plain ASCII connectors:
tree --charset=ascii -o structure.txttree can also emit structured formats directly: -J produces JSON, -X produces XML, and -H <baseHref> produces a browsable HTML listing:
tree -J -L 2 > structure.jsonQuick Reference
| Command | Description |
|---|---|
tree | List the current directory recursively |
tree -L 2 | Limit the listing to two levels |
tree -a | Include hidden files |
tree -d | Directories only |
tree -h --du | Human-readable cumulative sizes |
tree -P "*.js" --prune | Only files matching a pattern |
tree -I "node_modules|.git" | Exclude matching entries |
tree -f | Print full paths |
tree -o file.txt | Write the output to a file |
tree -J | Output JSON |
Conclusion
The tree command turns a nested directory hierarchy into a single readable listing, and options such as -L, -I, and --du keep the output focused on what you actually need. If you want the same tree-style view for running processes instead of files, take a look at the pstree command
.
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page