mkdir-tree

Generate directory tree from a scheme.

Usage no npm install needed!

<script type="module">
  import mkdirTree from 'https://cdn.skypack.dev/mkdir-tree';
</script>

README

mkdir-tree

npm npm type definitions Snyk Vulnerabilities for GitHub Repo tested with jest License: MIT

Create an entire directory structure in one go.
The tree command setter written in Node.js.

Lightweight, efficient, declarative, opinion-less & extremely easy to use.

Features

  • 📜 License: MIT
  • ⚡️ JS bundle size: ≈3KB minified & ≈1KB gzipped
  • 🛠 Compatibility: Node >= 8
  • ⌨️ Typescript: TypeScript Typings built-in
  • 🧰 Dependencies: 0 dependencies except babel-related

Install

npm i -D mkdir-tree

# or

yarn add mkdir-tree --dev

# or use directly in CLI

npx mkdir-tree --dir ./my-project --scheme '
dist
src
- | constants
- | utils
- | views
- | controllers
'

Use

Import the package:

const mkdirTree = require("mkdir-tree");

// or 

import mkdirTree from "mkdir-tree";

Create the desired directory structure in one function call:

await mkdirTree('.', `
  package.json
  dist
  src
  - | containers
  - | components
  - | constants
  - - | index.ts
  - | store
  - - | reducers
  - - - | README.md  
`);

mkdirTree accepts 2 arguments dirPath & scheme.

Name Type Required Description
dirPath string Yes Relative or absolute path to the target directory where the directory structure specified by the scheme will be created.
scheme string Yes Graphical description of the directory structure to create.

Entry Types

By default each entry that has something similar to an extension in its name is considered to be a file.

For instance, file.txt, index.js & .eslintrc.js are considered to be files while .git, folder, constants considered to be directories.

You can also force entry type if you want to by specifying /file or /dir flag like this:

await mkdirTree('.', `
  files.code /dir
    - | index /file 
`);

Please note that the flag must be preceded by a space-like character.

Notes

Partially created directory trees

It's safe to call mkdirTree on directories that already contain parts of the directory tree specified in scheme. Existing files & directories will not be affected while new files & folders will be created.

Errors

mkdirTree returns a promise that always resolves to an array of objects, however, it might throw synchronously in case if dirPath or scheme is missing or empty.

To avoid this, ensure that both dirPath & scheme are non-empty strings before calling mkdirTree or wrap call to mkdirTree into try...catch block.

Entries names

This package is opinion-less regarding filenames & does not perform any file/directory name validation.

If you specify a name that is invalid on your OS, the creation of the entry & all its children will fail.

If you want to make sure that names of your entries are ok, you might be looking for filenamify.
filenamify could be used together with this package.

Scheme format

Scheme format has only 3 rules:

  • Entries are divided by a new line character(/s).
  • Flags (/dir & /file) must be preceded by a space-like character & must be the last characters (apart from arbitrary space-like characters) in the line.
  • Level indicator (|) must be followed by a space-like character & must be preceded only by a correct number of depth indicators (-) and arbitrary number of space-like characters.

Please note that entries that have an incorrect number of depth indicators will be ignored.

Return

mkdirTree returns a Promise that resolves to an array of objects that look like this:

{
  path: '/absolute-path-part/entry/path.txt',
  status: 'success' /* or */ 'error',
  dirent: {
    name: 'path.txt',
    type: 'dir' /* or */ 'file',
    relativePath: 'entry/path.txt',
    children: [/* Recursive array of children entries that have the same shape as "dirent" property */]
  },
  /* If 'status' is 'error', 'error' property will also be present. It will contain the error that happened while trying to create the entry. */
  error: Error
},

Those objects might be present in any order. No particular order is guaranteed & the current behavior might change in future versions.

Please note, that some entries might not be present in the array due to incorrect number of depth indicators specified or an error in creation of upper-level directories.