# Unloved Files Unloved Files helps you find the quiet corners of an Obsidian vault: notes and attachments with no incoming links, plus folders that contain nothing. It turns the results into a browsable report so you can reconnect useful material without deleting or moving anything. Requires Obsidian 1.13.0 or newer. Maintained on GitHub by [NameIsKyro](https://github.com/NameIsKyro). ## Features - Finds unlinked Markdown notes, images, PDFs, audio, video, Canvas files, archives, and every other vault-visible file type. - Counts resolved Markdown links and embeds, along with file nodes in Canvas files. - Finds directly empty folders and folder trees that contain no files. - Scans the whole vault or only selected files, folders, nested folders, and glob patterns. - Excludes exact files, complete folder trees, glob patterns, file groups, or individual extensions. - Shows link coverage, total unlinked size, and rankings by folder, category, and extension. - Provides a compact right-sidebar summary and a detailed full-page report. - Keeps at most one sidebar summary and one full report open. - Opens files, copies Obsidian Markdown links, or appends a link to a note you choose. - Refreshes after vault changes with a configurable debounce, or only when requested. - Works on desktop and mobile and follows the active Obsidian theme. ## What “unlinked” means A file is unlinked when no **other** file has a resolved incoming link or embed to it. By default, a note that only links to itself is still considered unlinked. You can count self-links in settings. The scanner uses Obsidian's resolved metadata, so aliases, relative paths, shortest-path links, Markdown links, wiki links, and embeds are handled the same way Obsidian handles them. File nodes inside `.canvas` files also count as incoming references. External URLs and unresolved links do not count. Hidden files that Obsidian does not expose through the Vault API are not scanned. ## Usage 1. Open the command palette. 2. Run **Unloved Files: Open full report** or **Unloved Files: Open sidebar summary**. 3. Review unlinked files, empty folders, or statistics. 4. Use the row actions to: - add a link from a Markdown note you select; - copy an Obsidian Markdown link; or - open the file. 5. Select a folder in the statistics view to filter the file report to that path. The ribbon heart icon opens the full report. **Unloved Files: Refresh report** forces a fresh scan at any time. ## Settings ### Search scope - **Folders and files to search** — one vault-relative path per line. A folder includes all descendants. Leave empty to scan the entire vault. - **Folders and files to ignore** — exact file paths or complete folder trees. - **Ignore patterns** — vault-relative globs. `*` matches within one path segment, `**` crosses folder boundaries, and `?` matches one character. Examples: ```text Projects Reading/Queue.md Areas/**/Sources ``` ```text **/thumbnails/** Archive/*.pdf **/*.excalidraw.md ``` ### File types Every file group can be switched independently. The optional extension allowlist is applied after groups, and the extension denylist is applied last. Write extensions without a leading dot, for example `md, png, pdf`. ### Matching and updates - **Count self-links** — treat a self-reference as an incoming link. - **Find empty folders** — report folders with no children. - **Include empty folder trees** — also report folders that contain only other empty folders. - **Refresh automatically** — rescan after file or metadata changes. - **Refresh delay** — combine bursts of edits into a single scan. - **Maximum visible results** — cap rendered rows without changing totals or statistics. ## Installation ### Community plugins After the plugin is accepted into the Obsidian Community directory: 1. Open **Settings → Community plugins**. 2. Select **Browse** and search for **Unloved Files**. 3. Install and enable it. ### Manual installation 1. Download `main.js`, `manifest.json`, and `styles.css` from a release whose tag exactly matches the manifest version. 2. Create `/.obsidian/plugins/unloved-files/`. 3. Copy the three files into that folder. 4. Reload Obsidian and enable **Unloved Files** under **Community plugins**. ## Privacy and safety Unloved Files runs entirely inside Obsidian. It has no accounts, ads, analytics, telemetry, network requests, or external services. Scanning is read-only. The plugin does not delete, rename, or move vault content. It modifies a Markdown note only after you choose **Add a link**, select the destination note, and confirm that choice by selecting it; the link is appended using Obsidian's safe `Vault.process()` API. ## Performance The initial scan waits until the Obsidian workspace is ready. Later scans are debounced, Canvas reads use Obsidian's read cache, and the display limit prevents very large reports from creating excessive DOM nodes. Statistics always use the complete result set. For unusually large vaults, increase the refresh delay or turn off automatic refresh and use the refresh command manually. ## Development Requirements: Node.js 18 or newer and npm. ```bash npm install npm run dev ``` For development, place or symlink the repository at: ```text /.obsidian/plugins/unloved-files ``` Quality checks: ```bash npm run lint npm test npm run build npm run check ``` `npm run build` produces `main.js` in the repository root and refreshes the three ready-to-upload files in `releases/`. Both locations are Git-ignored so compiled code is uploaded to GitHub Releases instead of committed to source control. ## Releasing 1. Update `CHANGELOG.md` and `RELEASE_NOTES.md`. 2. Run `npm version patch`, `npm version minor`, or `npm version major`. The version script updates `manifest.json` and `versions.json`, runs all checks, and refreshes `releases/`. 3. Push the commit and its tag. The tag must be the exact version with no `v` prefix, for example `1.0.1`. 4. The release workflow checks the tag and uploads `releases/main.js`, `releases/manifest.json`, and `releases/styles.css` to a GitHub release. For the first Community directory submission, publish the `1.0.0` release, make the GitHub repository public, enable issues, and submit the repository through the Obsidian Community directory. The manifest ID is `unloved-files`. ## Contributing Bug reports and focused pull requests are welcome. Read [CONTRIBUTING.md](./CONTRIBUTING.md) before starting a change. Please report security problems through the process in [SECURITY.md](./SECURITY.md). Development and release-maintenance notes are kept in [DEVELOPMENT.md](./DEVELOPMENT.md). ## License [MIT](./LICENSE)