DEV Community

dpm_bush
dpm_bush

Posted on Originally published at sshflow.com

Use the Linux tree Command to Understand a Project’s Structure

ls is useful when you need to see what’s in one directory. But when you need to understand how a project’s folders fit together, a flat listing can hide the structure. The tree command displays files and directories as a branching outline.

Get a focused overview

Run tree with no arguments to start at your current directory, or pass a path to inspect a specific folder:

tree
tree ./project
Enter fullscreen mode Exit fullscreen mode

A small project might look like this:

project
├── README.md
├── src
│   └── app.py
└── tests
    └── test_app.py
Enter fullscreen mode Exit fullscreen mode

The branches make the parent-child relationships visible: src and tests are inside project, and each file appears beneath its parent directory.

A full recursive listing can quickly become unwieldy, especially in a repository with generated files or dependencies. Use -L to limit how many levels are shown:

tree -L 2 ./project
Enter fullscreen mode Exit fullscreen mode

That gives you a useful first pass without expanding every nested folder. If the result is still noisy, start from a narrower path or combine the depth limit with filters below.

Install it if the command is missing

Check whether tree is available:

tree --version
Enter fullscreen mode Exit fullscreen mode

If your shell reports that the command cannot be found, install the tree package using the package manager for your distribution:

# Ubuntu or Debian
sudo apt install tree

# Fedora
sudo dnf install tree

# Arch Linux
sudo pacman -S tree

# openSUSE
sudo zypper install tree
Enter fullscreen mode Exit fullscreen mode

These commands install software system-wide and typically require administrator privileges. Afterward, verify the command with tree --version.

Shape the output around your task

A few options make the listing more useful without changing anything on disk:

# Show directories, not files
tree -d ./project

# Include hidden entries, such as .git
tree -a -L 2 ./project

# Skip bulky or irrelevant directories
tree -I 'node_modules|.git' ./project

# Show matching filenames while keeping their location in the tree
tree -P '*.conf' ./project
Enter fullscreen mode Exit fullscreen mode

Use -d for a quick map of the folder layout. Add -a when hidden files matter; these are omitted by default. For a large repository, -I can leave out names you don’t want to inspect. -P selects names matching a pattern.

Quote wildcard patterns such as '*.conf'. The quotes stop your shell from expanding the wildcard before tree receives it. In the ignore example, patterns are separated with |.

You can also show extra file details:

tree -p -h -D ./project
Enter fullscreen mode Exit fullscreen mode

This adds permissions, human-readable sizes, and modification dates to the listing.

Choose the right listing tool

Use tree when the relationships between nested folders matter. For a quick view of just the current directory, ls has options for hidden files, long-format details, and sorting. If you need to locate files by conditions rather than browse the hierarchy, find can search by name, type, size, and other criteria.

tree is also different from pstree: the former shows files and directories, while pstree shows running processes.

Save a listing to share or review later

Redirect the output to a text file:

tree -L 2 ./project > project-tree.txt
Enter fullscreen mode Exit fullscreen mode

The > operator creates the file or replaces its existing contents. To append instead, use >>:

tree -L 2 ./project >> project-tree.txt
Enter fullscreen mode Exit fullscreen mode

If you don’t want the report to appear in the listing, save it outside the directory you’re inspecting. Be careful with > if the destination file already contains something you need.

A few common surprises

The output is too long: specify the directory you care about and use -L to cap the depth. Try -d for a directory-only view or -I to skip noisy folders.

Some entries are missing: hidden names are excluded unless you use -a. Entries can also be inaccessible if your user cannot read the relevant directories. Check permissions on the path in question rather than automatically running the command with elevated privileges.

A filter doesn’t behave as expected: -P selects matching names; -I ignores matching names. Quote patterns so the shell passes them to tree unchanged. These filters affect the display, not the files themselves.

The command is installed but unavailable: you might be in a different system or container than expected, or its executable may not be on your shell’s PATH.

For most project inspections, start small: pick the directory, add a depth limit, then include hidden entries or filters only if the task calls for them. That produces a readable map without turning a quick check into a scroll through every file.

I originally published a more detailed version of this guide on the SSHFlow blog.

I'm also building SSHFlow — an SSH client where every server gets its own workspace for terminals, SFTP, code, and databases.

Top comments (0)