or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

index.mddocs/

Directory Tree

Directory Tree is a Node.js library that converts directory structures into JavaScript objects. It provides flexible scanning of file system hierarchies with support for filtering by file extensions, excluding specific paths, and customizing output attributes including file size, modification time, and type information.

Package Information

  • Package Name: directory-tree
  • Package Type: npm
  • Language: JavaScript with TypeScript definitions
  • Installation: npm install directory-tree
  • Node.js Support: Requires Node.js 10.0+

Core Imports

const directoryTree = require("directory-tree");

For TypeScript:

import directoryTree = require("directory-tree");
import { DirectoryTree, DirectoryTreeOptions, DirectoryTreeCallback } from "directory-tree";

Basic Usage

const directoryTree = require("directory-tree");

// Basic directory scan
const tree = directoryTree("/path/to/directory");

// Scan with file extension filtering
const filteredTree = directoryTree("/path/to/directory", {
  extensions: /\.(js|ts|md)$/
});

// Scan with additional attributes
const detailedTree = directoryTree("/path/to/directory", {
  attributes: ["size", "type", "extension", "mtime"]
});

console.log(JSON.stringify(tree, null, 2));

Architecture

Directory Tree is built around several key components:

  • Core Function: Single main function that recursively traverses directories
  • Options System: Comprehensive configuration for filtering, attributes, and behavior
  • Callback System: Optional callbacks for processing files and directories during traversal
  • TypeScript Support: Full type definitions for all interfaces and function signatures
  • CLI Interface: Command-line tool for generating JSON representations of directory structures
  • Error Handling: Graceful handling of permission errors and filesystem access issues

Capabilities

Directory Scanning

Core directory scanning functionality that converts filesystem hierarchies into JavaScript objects with configurable filtering and attribute collection.

/**
 * Scans a directory and returns a JavaScript object representation
 * @param path - The directory path to scan
 * @param options - Configuration options for scanning behavior
 * @param onEachFile - Optional callback executed for each file
 * @param onEachDirectory - Optional callback executed for each directory
 * @returns DirectoryTree object or null if path is inaccessible
 */
declare function directoryTree<
  TCustomFile extends Record<string, any> = Record<string, any>,
  TCustomDir extends Record<string, any> = Record<string, any>,
  TCustomResult extends Record<string, any> = TCustomFile & TCustomDir
>(
  path: string,
  options?: DirectoryTreeOptions,
  onEachFile?: DirectoryTreeCallback<TCustomFile>,
  onEachDirectory?: DirectoryTreeCallback<TCustomDir>
): DirectoryTree<TCustomResult> | null;

Usage Examples:

const directoryTree = require("directory-tree");

// Basic usage
const tree = directoryTree("./src");

// With options
const tree = directoryTree("./src", {
  extensions: /\.(js|ts)$/,
  attributes: ["size", "type", "extension"],
  depth: 3,
  exclude: /node_modules/
});

// With callbacks
const tree = directoryTree("./src", { extensions: /\.js$/ }, 
  (item, path, stats) => {
    console.log(`File: ${item.name} (${stats.size} bytes)`);
  },
  (item, path, stats) => {
    console.log(`Directory: ${item.name}`);
  }
);

Configuration Options

Comprehensive options for controlling directory scanning behavior.

interface DirectoryTreeOptions {
  /** Normalize Windows paths to Unix-style paths (/ instead of \\) */
  normalizePath?: boolean;
  /** RegExp or array of RegExp patterns to exclude directories/files */
  exclude?: RegExp | RegExp[];
  /** Array of fs.Stats attributes to include in output plus 'type' and 'extension' */
  attributes?: (keyof Stats | "type" | "extension")[];
  /** RegExp pattern to filter files by extension */
  extensions?: RegExp;
  /** Whether to follow symbolic links (default: true) */
  followSymlinks?: boolean;
  /** Maximum directory depth to scan (undefined = unlimited) */
  depth?: number;
}

Supported Attributes:

  • Built-in: "type", "extension"
  • fs.Stats: "size", "mode", "mtime", "atime", "ctime", "birthtime", "dev", "ino", "nlink", "uid", "gid", "rdev", "blksize", "blocks"

Usage Examples:

// Filter by multiple extensions
const tree = directoryTree("./docs", {
  extensions: /\.(md|txt|html)$/
});

// Exclude multiple patterns
const tree = directoryTree("./project", {
  exclude: [/node_modules/, /\.git/, /dist/]
});

// Include file attributes
const tree = directoryTree("./assets", {
  attributes: ["size", "mtime", "type", "extension"]
});

// Limit scanning depth
const tree = directoryTree("./deep-structure", {
  depth: 2,
  attributes: ["type"] // Note: 'size' cannot be used with 'depth'
});

// Normalize paths for cross-platform compatibility
const tree = directoryTree("./src", {
  normalizePath: true,
  followSymlinks: false
});

Result Structure

The structure of objects returned by directory scanning.

interface DirectoryTree<C extends Record<string, any> = Record<string, any>> {
  /** Full path to the file or directory */
  path: string;
  /** Name of the file or directory (basename) */
  name: string;
  /** Size in bytes (only if 'size' attribute is requested) */
  size: number;
  /** Type of item: 'file' or 'directory' (only if 'type' attribute is requested) */
  type: "directory" | "file";
  /** Array of child items (directories only, when children exist) */
  children?: DirectoryTree<C>[];
  /** File extension including the dot (files only, if 'extension' attribute is requested) */
  extension?: string;
  /** Whether the item is a symbolic link */
  isSymbolicLink?: boolean;
  /** Custom properties added via callbacks */
  custom: C;
}

Example Result:

{
  "path": "photos",
  "name": "photos",
  "size": 600,
  "type": "directory",
  "children": [
    {
      "path": "photos/vacation.jpg",
      "name": "vacation.jpg", 
      "size": 400,
      "type": "file",
      "extension": ".jpg"
    },
    {
      "path": "photos/family",
      "name": "family",
      "size": 200,
      "type": "directory",
      "children": [
        {
          "path": "photos/family/portrait.png",
          "name": "portrait.png",
          "size": 200,
          "type": "file",
          "extension": ".png"
        }
      ]
    }
  ]
}

Callback Functions

Optional callback functions for processing files and directories during traversal.

// Import from Node.js fs module
import { Stats } from "fs";

/**
 * Callback function executed for each file or directory
 * @param item - The DirectoryTree item being processed
 * @param path - Full path to the item
 * @param stats - Node.js fs.Stats object for the item
 */
type DirectoryTreeCallback<TCustom extends Record<string, any> = Record<string, any>> = (
  item: DirectoryTree<TCustom>,
  path: string,
  stats: Stats
) => void;

Usage Examples:

const crypto = require('crypto');
const directoryTree = require("directory-tree");

// Add custom IDs to all items
const tree = directoryTree("./src", {}, 
  (item, path, stats) => {
    // File callback
    item.custom = {
      id: crypto.createHash('sha1').update(path).digest('base64'),
      lastModified: stats.mtime.toISOString()
    };
  },
  (item, path, stats) => {
    // Directory callback  
    item.custom = {
      id: crypto.createHash('sha1').update(path).digest('base64'),
      itemCount: item.children ? item.children.length : 0
    };
  }
);

// Log processing progress
const tree = directoryTree("./large-directory", {}, 
  (item, path) => console.log(`Processing file: ${path}`),
  (item, path) => console.log(`Entering directory: ${path}`)
);

Command Line Interface

CLI tool for generating JSON representations of directory structures from the command line.

# Basic usage
npx directory-tree /path/to/directory

# With options
npx directory-tree --path /home/user/docs --attributes type,extension,size --pretty --output result.json

# Available options:
# -p, --path <string>      Input folder path (required)
# -e, --exclude <string>   Exclude pattern (regex string)
# -o, --output <string>    Output file path
# -d, --depth <number>     Maximum directory depth
# --attributes <string>    Comma-separated attributes list
# --pretty                 Pretty-print JSON output
# -h, --help              Show help

CLI Examples:

# Scan current directory with file types and extensions
npx directory-tree . --attributes type,extension --pretty

# Exclude certain directories and save to file
npx directory-tree /project --exclude "node_modules|\.git|dist" --output tree.json

# Limit depth and include file sizes
npx directory-tree /deep/structure --depth 2 --attributes type,extension

# Scan and format for readability
npx directory-tree ~/Documents --pretty --attributes type,size,mtime

Error Handling and Limitations

Permission Handling

  • Directory Access Denied: Directories without read permissions are skipped entirely (returns null for that branch)
  • File Access Denied: Files without read permissions are included in the tree but may have limited stat information

Restrictions

  • Size + Depth Limitation: Cannot use size attribute when depth option is specified (throws an Error)
  • Symbolic Links: Cyclic symbolic links are detected and skipped to prevent infinite loops
  • Device Files: Device, FIFO, and socket files are ignored

Error Examples

// This will throw an error
try {
  const tree = directoryTree("./src", {
    depth: 2,
    attributes: ["size"] // Error: size cannot be used with depth
  });
} catch (error) {
  console.error(error.message); // "usage of size attribute with depth option is prohibited"
}

// Permission errors are handled gracefully
const tree = directoryTree("/root"); // Returns null if no permission

TypeScript Integration

Full TypeScript support with generic types for custom callback data.

import { createHash } from 'crypto';
import { Stats } from 'fs';
import directoryTree = require('directory-tree');
import { DirectoryTree, DirectoryTreeOptions, DirectoryTreeCallback } from 'directory-tree';

// Generic usage with custom types
interface CustomData {
  id: string;
  processed: boolean;
}

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

const tree: DirectoryTree<CustomData> = directoryTree(
  "./src",
  { attributes: ["type", "size"] },
  callback,
  callback
);

// Access custom properties with type safety
if (tree?.custom?.processed) {
  console.log(`Processed with ID: ${tree.custom.id}`);
}