Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>File Structure GeneratorNew to Visual Studio Code? Get it now.
File Structure Generator

File Structure Generator

ADITHYA-LOCHANA

|
621 installs
| (0) | Free
Keeps a clean, always up-to-date project tree in a text file. Skips node_modules, virtual environments, build output and anything in .gitignore. Great for docs, onboarding and AI context.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

File Structure Generator

A clean, always up-to-date map of your project, in one text file.

Open a folder and the extension writes a filestructure.txt that shows your project's files and folders. Add, rename or delete files and the tree updates on its own. It leaves out the noise (node_modules, virtual environments, build output, caches and anything in your .gitignore), so what's left is the part of the project people actually need to read.

For a Node.js project, filestructure.txt looks like this:

|-- .eslintrc.json
|-- .gitignore
|-- package.json
|-- public
    |-- index.html
    |-- styles.css
|-- README.md
|-- src
    |-- index.js
    |-- middleware
        |-- logger.js
    |-- routes
        |-- auth.js
        |-- users.js
    |-- utils
        |-- format.js
|-- tests
    |-- auth.test.js
    |-- users.test.js

Why use it

  • Onboarding: new teammates see how the project is laid out at a glance.
  • Documentation: drop the tree into a README, a wiki or a pull request description.
  • AI assistants: give a chat assistant a compact picture of your project instead of pasting folders by hand.
  • Always current: no manual copying, so the structure never goes stale.

Quick start

  1. Install the extension.
  2. Open a project folder.
  3. Look in the root of the folder for filestructure.txt.

That's it. To change anything, search for fsGenerator in Settings (Ctrl+,).

Features

  • Updates automatically as files and folders are added, removed or renamed.
  • Works across languages. Dependency, build, cache and IDE folders are left out at any depth, including node_modules, .venv, __pycache__, vendor, target, dist, .gradle, Pods and .git. Compiled files (*.class, *.o), JavaScript lock files and any Python virtual environment (found by its pyvenv.cfg, whatever the folder is called) are skipped too.
  • Respects your .gitignore, and picks up edits to it straight away.
  • No empty leftovers. A folder whose contents were all skipped is not listed. Folders that really are empty are still shown.
  • Customizable. Add your own exclusions, keep folders the defaults would hide, and choose the file name, tree style, depth and size limit.
  • Status bar menu. Click Structure in the status bar to switch between the Simple and Tree styles, toggle folders first, regenerate, copy, or fix Git, without opening Settings.
  • Git friendly. It only writes when the content really changed, waits while Git is switching branches, and can stop Git from tracking the generated file. It only ever stages a change when you ask, and never commits or pushes.
  • Multi-root workspaces. Every folder gets its own file.
  • Private. Everything runs locally. The extension collects no data and makes no network requests.

In that same project, this is what is listed and what is left out:

.vscode/           1 file    skipped (built-in rule)
coverage/          1 file    skipped (built-in rule)
dist/              1 file    skipped (built-in rule)
node_modules/      80 files  skipped (built-in rule)
public/            2 files   listed
src/               5 files   listed
tests/             2 files   listed
.env                         skipped (.gitignore)
.eslintrc.json               listed
.gitignore                   listed
package-lock.json            skipped (built-in rule)
package.json                 listed
README.md                    listed

Status bar menu

Click Structure in the status bar to open a menu:

  • Tree style: switch between Simple and Tree. The choice is saved for this project in .vscode/settings.json, and the file is regenerated right away.
  • Folders first: turn it on or off.
  • Git: choose Track in Git, Keep out of Git, or Keep out of Git on this computer only. The current state has a check mark, and unlike a notification the choices are always there. Choosing one only stages the change; nothing is committed.
  • More: Regenerate now, Copy to clipboard and More settings….

Each block has its own heading (TREE STYLE, LAYOUT, GIT, MORE), and the title bar shows which project the menu is for. When the generated file is kept out of Git through .gitignore, the menu looks like this:

── TREE STYLE · how the file looks, saved for this project ──
   ✓ Simple                                  |-- name
   ○ Tree                                    ├── name

── LAYOUT ──
   ○ Folders first                           off

── GIT · filestructure.txt is kept out (listed in .gitignore) ──
   ○ Track in Git                            removes its ignore line, stages the file
   ✓ Keep out of Git                         adds it to .gitignore
   ○ Keep out of Git on this computer only   .git/info/exclude

── MORE ──
   ⟳ Regenerate now
   ⧉ Copy to clipboard
   ⚙ More settings…

When the generated file is committed to Git, the status bar item turns into a warning (⚠) and stays that way until you deal with it, so the notification can't be missed.

Commands

Open the Command Palette (Ctrl+Shift+P, or Cmd+Shift+P on macOS):

Command What it does
File Structure: Generate Writes the file now.
File Structure: Options Opens the options menu, the same one you get by clicking Structure in the status bar.
File Structure: Copy to Clipboard Copies the tree to the clipboard without writing a file.
File Structure: Stop Tracking in Git Stages the removal of the generated file from Git and ignores it. Nothing is committed.
File Structure: Show Log Opens a log that explains what the extension found and decided, for example why a Git prompt did or didn't appear.

Settings

All settings can be set per folder in settings.json.

For example, with treeStyle set to tree, foldersFirst turned on, maxDepth set to 3 and exclude set to ["tests/"], a Django project comes out like this. Its virtual environment, __pycache__, htmlcov and db.sqlite3 are skipped automatically:

├── config
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── shop
│   ├── migrations
│   │   ├── __init__.py
│   │   └── 0001_initial.py
│   ├── templates
│   │   └── shop
│   ├── __init__.py
│   ├── admin.py
│   ├── models.py
│   ├── urls.py
│   └── views.py
├── .gitignore
├── manage.py
├── README.md
└── requirements.txt
Setting Default Description
fsGenerator.autoUpdate true Update the file automatically. When off, it is only written when you run File Structure: Generate.
fsGenerator.outputFile "filestructure.txt" File name, relative to the workspace folder. Can include folders, such as docs/structure.md. A .md file gets the tree in a code block.
fsGenerator.showStatusBar true Show the status bar item.
fsGenerator.promptGitignore true In a Git project, point out once if the generated file is committed or not ignored, and offer to fix it. The extension never commits or pushes.
fsGenerator.useDefaultExcludes true Leave out the built-in list of dependency, build, cache and IDE folders.
fsGenerator.respectGitignore true Also leave out everything in the workspace folder's .gitignore.
fsGenerator.exclude [] Extra patterns to leave out, such as ["*.log", "env/"].
fsGenerator.include [] Patterns to keep even if the defaults or .gitignore would leave them out, such as ["build"].
fsGenerator.treeStyle "simple" simple draws plain ASCII lines. tree draws ├── and └── connectors. You can also switch it from the status bar menu.
fsGenerator.foldersFirst false List folders before files.
fsGenerator.maxDepth 0 How many levels deep to list. 0 means no limit.
fsGenerator.maxEntries 20000 Stop after this many entries so a huge project can't produce a giant file. 0 means no limit.

Patterns

exclude and include use .gitignore syntax:

  • *.log matches by wildcard at any depth.
  • build/ matches folders only.
  • /docs matches only at the workspace root.
  • **/generated matches at any depth.

Rules apply in this order, and later ones win: built-in defaults, then .gitignore, then exclude, then include.

Example:

{
  "fsGenerator.exclude": ["env/", "*.min.js"],
  "fsGenerator.include": ["build"],
  "fsGenerator.treeStyle": "tree",
  "fsGenerator.maxDepth": 4
}

Using it with Git

The generated file is rebuilt from the files on disk, so in a Git project it shows up as a change whenever files are added or removed, and it differs between branches. The extension points this out once per project and offers a fix:

  • The file is already committed: ignoring it is not enough, because Git keeps tracking a committed file. The extension offers Stop tracking and ignore, which stages the file's removal from Git (the file stays on your disk) and adds it to .gitignore.
  • The file is not committed yet: it offers Add to .gitignore, or Ignore on this computer only, which uses .git/info/exclude and leaves the project's own files untouched.

The extension never commits or pushes. A fix only stages a change, and only after you click a button. You review it in Source Control and commit whenever you're ready. If your .gitignore already has other uncommitted changes, the extension edits it but leaves it unstaged, so your own edits are never swept in.

Prefer to keep the file in your repository? Choose Track in Git in the status bar menu. It removes the file's own line from .gitignore (or from your local exclude file), stages the file, and remembers your choice so the warning and the prompts stay quiet for that project. If another rule still matches the file, such as *.txt, it is staged with git add -f and the extension tells you. Choosing Keep out of Git later reverses it.

You can run the "keep out" fix any time with File Structure: Stop Tracking in Git, or from the status bar menu. To turn the one-time prompt off, set fsGenerator.promptGitignore to false. This needs Git on your PATH.

If Git can't run for a project (it isn't installed, or it refuses the folder), the extension says so, and the reason is in the log (File Structure: Show Log). "Don't ask again" is remembered per project, separately for the committed-file prompt and the ignore offer, and the status bar warning stays either way.

Good to know

  • Only the .gitignore in the workspace folder root is read, not ones in subfolders.
  • Symlinked folders are listed but not followed.
  • The built-in list matches names, so a real project folder called build, logs, out or temp is hidden by default. Use fsGenerator.include to keep it.
  • A plain bin folder is shown, because it is often real source (Go and Ruby projects, for example). To hide it, add "bin/" to fsGenerator.exclude.
  • Turning off fsGenerator.useDefaultExcludes also turns off the virtual environment detection.
  • It needs a real folder on disk, so it does not work in virtual workspaces such as github.dev.

Feedback

Found a bug or have an idea? Please use the Q & A tab on this page.

License

This project is licensed under the MIT License. The full text is shown under License in this page's sidebar.

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
  • Your Privacy Choices
  • Consumer Health Privacy
© 2026 Microsoft