# directory-tree

> Convert a directory tree to a JS object.

Latest version **3.6.0** (published 2026-01-24) · MIT license · 0 weekly downloads

## Install

```sh
npm install directory-tree
pnpm add directory-tree
yarn add directory-tree
bun add directory-tree
```

Provides the command `directory-tree`.

## Health

**Score 45/100 (D)** — status: stable.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

## Facts

| | |
|---|---|
| Version | 3.6.0 |
| Published | 2026-01-24 |
| First published | 2014-03-11 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Node | >=10.0 |
| Dependencies | 2 |
| Unpacked size | 28.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 540 |
| Author | Mihnea Dobrescu-Balaur |
| Maintainers | mihneadb |
| Keywords | directory, tree |

## Links

- npm: https://www.npmjs.com/package/directory-tree
- Repository: https://github.com/mihneadb/node-directory-tree
- Issues: https://github.com/mihneadb/node-directory-tree/issues
- npm.io page: https://npm.io/package/directory-tree

## Dependencies (2)

- [command-line-args](https://npm.io/package/command-line-args.md) ^5.2.0
- [command-line-usage](https://npm.io/package/command-line-usage.md) ^6.1.1

## Recent versions

- 3.6.0 (latest) — 2026-01-24
- 3.5.2 — 2024-07-15
- 3.5.1 — 2022-12-21
- 3.5.0 — 2022-12-20
- 3.4.0 — 2022-11-18
- 3.3.2 — 2022-11-07
- 3.3.1 — 2022-09-01
- 3.3.0 — 2022-05-21
- 3.2.2 — 2022-02-21
- 3.2.1 — 2022-02-11
- 3.2.0 — 2022-02-08
- 3.1.0 — 2022-02-01
- 3.0.1 — 2021-11-17
- 3.0.0 — 2021-09-22
- 2.4.0 — 2021-09-15
- … 22 more at https://npm.io/package/directory-tree/versions

## README

# directory-tree

Creates a JavaScript object representing a directory tree.

This library gets [~100k downloads per week](http://npm-stats.org/#/directory-tree). If you find it useful, feel free to <a href="https://www.buymeacoffee.com/pxhxnsxsbn"><img height="40" src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" /></a> .

## Install

```bash
$ npm install directory-tree
```

## Usage

```js
const dirTree = require("directory-tree");
const tree = dirTree("/some/path");
```

And you can also filter by an extensions regex:
This is useful for including only certain types of files.

```js
const dirTree = require("directory-tree");
const filteredTree = dirTree("/some/path", { extensions: /\.txt/ });
```

Example for filtering multiple extensions with Regex.

```js
const dirTree = require("directory-tree");
const filteredTree = dirTree("/some/path", {
  extensions: /\.(md|js|html|java|py|rb)$/
});
```

You can also exclude paths from the tree using a regex:

```js
const dirTree = require("directory-tree");
const filteredTree = dirTree("/some/path", { exclude: /some_path_to_exclude/ });
```

You can also specify which additional attributes you would like to be included about each file/directory:

```js
const dirTree = require('directory-tree');
const filteredTree = dirTree('/some/path', {attributes:['mode', 'mtime']});
```

The default attributes are `[name, path]` for Files and `[name, path, children]` for Directories

A callback function can be executed with each file that matches the extensions provided:

```js
const PATH = require('path');
const dirTree = require('directory-tree');

const tree = dirTree('./test/test_data', {extensions:/\.txt$/}, (item, PATH, stats) => {
  console.log(item);
});
```

The callback function takes the directory item (has path, name, size, and extension) and an instance of [node path](https://nodejs.org/api/path.html) and an instance of [node FS.stats](https://nodejs.org/api/fs.html#fs_class_fs_stats).

You can also pass a callback function for directories:
```js
const PATH = require('path');
const dirTree = require('directory-tree');

const tree = dirTree('./test/test_data', {extensions:/\.txt$/}, null, (item, PATH, stats) => {
  console.log(item);
});
```

## Options

`exclude` : `RegExp|RegExp[]` - A RegExp or an array of RegExp to test for exclusion of directories.

`extensions` : `RegExp` - A RegExp to test for exclusion of files with the matching extension.

`attributes` : `string[]` - Array of [FS.stats](https://nodejs.org/api/fs.html#fs_class_fs_stats) attributes.

`normalizePath` : `Boolean` - If true, Windows style paths will be normalized to UNIX style paths (/ instead of \\).

`depth` : `number` - Limits directory traversal to the specified depth level. When combined with `size`, directories at the depth limit have `size: undefined` (see "Using size with depth" below).

## Result

Given a directory structured like this:

```
photos
├── summer
│   └── june
│       └── windsurf.jpg
└── winter
    └── january
        ├── ski.png
        └── snowboard.jpg
```

`directory-tree` with `attributes: ["size", "type", "extension"]`  will return this JS object:

```json
{
  "path": "photos",
  "name": "photos",
  "size": 600,
  "type": "directory",
  "children": [
    {
      "path": "photos/summer",
      "name": "summer",
      "size": 400,
      "type": "directory",
      "children": [
        {
          "path": "photos/summer/june",
          "name": "june",
          "size": 400,
          "type": "directory",
          "children": [
            {
              "path": "photos/summer/june/windsurf.jpg",
              "name": "windsurf.jpg",
              "size": 400,
              "type": "file",
              "extension": ".jpg"
            }
          ]
        }
      ]
    },
    {
      "path": "photos/winter",
      "name": "winter",
      "size": 200,
      "type": "directory",
      "children": [
        {
          "path": "photos/winter/january",
          "name": "january",
          "size": 200,
          "type": "directory",
          "children": [
            {
              "path": "photos/winter/january/ski.png",
              "name": "ski.png",
              "size": 100,
              "type": "file",
              "extension": ".png"
            },
            {
              "path": "photos/winter/january/snowboard.jpg",
              "name": "snowboard.jpg",
              "size": 100,
              "type": "file",
              "extension": ".jpg"
            }
          ]
        }
      ]
    }
  ]
}
```

## Using size with depth

The `size` attribute can be used together with the `depth` option, but with an important caveat:

**When depth limiting is active:**
- **Files** always have accurate sizes
- **Directories at the depth limit** (whose children are not traversed) will have `size: undefined`
- **Parent directories** containing depth-limited directories will also have `size: undefined`

This is because directory sizes are calculated by recursively summing all child sizes. When depth limits prevent full traversal, the size would be incomplete and potentially misleading, so `undefined` is returned instead.

**Example:**

```js
const dirTree = require('directory-tree');
const tree = dirTree('/some/path', {
  depth: 1,
  attributes: ['size', 'type']
});
```

Given this structure:
```
folder/
├── file1.txt (100 bytes)
├── file2.txt (200 bytes)
└── subfolder/
    └── file3.txt (300 bytes)
```

The result will be:
```js
{
  "path": "folder",
  "name": "folder",
  "size": undefined,
  "type": "directory",
  "children": [
    {
      "path": "folder/file1.txt",
      "name": "file1.txt",
      "size": 100,
      "type": "file"
    },
    {
      "path": "folder/file2.txt",
      "name": "file2.txt",
      "size": 200,
      "type": "file"
    },
    {
      "path": "folder/subfolder",
      "name": "subfolder",
      "size": undefined,
      "type": "directory"
    }
  ]
}
```

**Note:** When serializing to JSON (e.g., `JSON.stringify(tree)`), `undefined` values are omitted. Properties with `undefined` will not appear in the JSON string.

## Adding custom fields
You can easily extend a `DirectoryTree` object with custom fields by adding them to the custom field.
For example add an `id` based on the path of a `DirectoryTree` object for each directory and file like so:
```
import { createHash } from 'crypto';
import * as directoryTree from 'directory-tree';
import { DirectoryTree, DirectoryTreeOptions, DirectoryTreeCallback } from 'directory-tree';

const callback: DirectoryTreeCallback = (
            item: DirectoryTree,
            path: string
        ) => {
            item.custom = {id: createHash('sha1').update(path).digest('base64')};
        };

const dirTree: DirectoryTree & { id?: string } = directoryTree(
    "<your-directory-path>",
    {},
    callback,
    callback
);

// to explore the object with the new custom fields
console.log(JSON.stringify(dirTree, null, 2));

```

## Note

Device, FIFO and socket files are ignored.

Files to which the user does not have permissions are included in the directory
tree, however, directories to which the user does not have permissions, along
with all of its contained files, are completely ignored.

## Dev

To run tests go the package root in your CLI and run,

```bash
$ npm test
```

Make sure you have the dev dependencies installed (e.g. `npm install .`)

## CLI usage

You can use script directly from command line for generating json data.

```bash
$ npx directory-tree --help
```
```bash
$ npx directory-tree --path /Users/user/target --attributes type,extension --pretty -o ./xz.json --depth 1 
```

### Available options
-p, --path string      🗂 The input folder to process. Required.                                     
-e, --exclude string   🐒 Exclude some folders from processing by regexp string. Ex -e "test_data/some_dir$|js|.DS_Store"                                            
-o, --output string    📝 Put result into file provided by this options. Overwrites if exists.       
-d, --depth number     ☞ Limits directory traversal to specified depth. Combined with size, directories at depth limit have size: undefined.
--attributes string    ℹ️ Grab file attributes. Example: --attributes size,type,extension. With depth, directories at limit have size: undefined.                                
--pretty               💎 Json pretty print

---
_Source: https://npm.io/package/directory-tree · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
