Johannes Kaindl28 downloadsHides empty and irrelevant folders from the file explorer without deleting them: ignore patterns, per-folder pins, optional Sync exclusion.
🇬🇧 English · 🇩🇪 Deutsch
Hides empty and irrelevant folders from the file explorer without deleting them: ignore patterns, per-folder pins, optional Sync exclusion.
Open a folder full of code repositories as a vault and the file explorer fills up with node_modules, build output and folders that never held a note. Shadow Tree filters that view. A folder disappears from the file explorer when nothing below it counts as content (by default Markdown, Canvas and Base files) or when an ignore pattern in .gitignore style matches it. Notes inside a folder that a pattern hides do not count for its parents, so a repository whose only Markdown sits in node_modules disappears as a whole. Nothing is deleted, moved or renamed: the folders are still there, they are just not drawn. One click on the ribbon icon shows everything again.
md, canvas, base by default), so a folder that only holds images or code disappears..gitignore — one rule per line: node_modules matches at any depth, repo-a/dist is anchored at the vault root, * stays inside a folder name, ** crosses folders, ! undoes an earlier rule. Matching folders are hidden even if they contain notes. Defaults: node_modules, dist, build, coverage, __pycache__.
Install AnySource Sideloader, add the catalog https://git.jkaindl.de/jkaindl/obsidian-catalog/raw/branch/main/catalog.json, then install Shadow Tree from it and enable it under Settings → Community plugins.
Download main.js, manifest.json and styles.css from the latest release, put them into <vault>/.obsidian/plugins/shadow-tree/, then enable Shadow Tree under Settings → Community plugins.
git clone https://github.com/johannes-kaindl/shadow-tree
cd shadow-tree && npm install && npm run build
# copy main.js, manifest.json and styles.css into <vault>/.obsidian/plugins/shadow-tree/
| Setting | Effect | Default |
|---|---|---|
| Hide empty folders | Hides folders with no relevant file anywhere below them. | on |
| Relevant file types | Extensions that count as content, separated by commas or spaces. | md, canvas, base |
| Ignore patterns | One rule per line in .gitignore style; matching folders are hidden even with notes inside. See Ignore patterns. |
node_modules, dist, build, coverage, __pycache__ |
| Pinned folders | Per-folder overrides: Always show or Always hide. Added from the folder context menu or here. | none |
| Also exclude hidden folders from Obsidian Sync | Writes the folders hidden by a pattern or an "always hide" pin into Sync's excluded folders (per device) and removes them again later; folders hidden only because they are empty are left alone. Disabled when Sync is off or not connected to a remote vault. Turn it off before disabling the plugin. | off |
The plugin never touches the DOM of the file explorer. It reads the vault's folder tree through the Obsidian API, computes the topmost hidden folders, and installs one stylesheet (a Constructable Stylesheet on the main window) with one rule per hidden folder, keyed on the folder's data-path attribute. The tree is recomputed a quarter second after the last create, delete or rename. Because the plugin only hides, the worst case of an Obsidian update that changes the explorer's markup is that folders reappear; nothing is lost. The code layout is described in AGENTS.md.
.obsidian are never shown by Obsidian's file explorer; the plugin cannot reveal them.Issues and pull requests on GitHub. Test-driven (npm run gate); see AGENTS.md and CONTRIBUTING.md.
LICENSE).LICENSE-DOCS).Copyright © 2026 Johannes Kaindl.