Skip to main content

Vault Linker

Run Tests PyPI

Overview

Vault Linker links note titles and YAML aliases across your Obsidian vault as wikilinks. Use the CLI (vaultlinker) for batch jobs, parallelism, and automation, or the community plugin for link, audit, and unlink from inside Obsidian.

Linking

Graph before linking: mostly isolated notes Graph after linking: denser connections

Obsidian graph view before and after running Vault Linker on a vault (illustrative).

Features

  • Automatic wikilinks for note titles and YAML aliases
  • Parallel runs with --jobs (read / process / write phases)
  • Dry-run, backup, output copy, globs, and incremental state
  • Audit broken links, pending links, and backlink stats; unlink managed title links
  • Skips metadata, code blocks, embeds, and markdown links (CLI + plugin)
  • Optional case-sensitive matching and first link per phrase per note
  • Path include/exclude globs (CLI flags; plugin settings)

Linking Process

  1. Scan Files: The tool scans all the markdown files in your Obsidian vault.
  2. Extract Filenames: It extracts the filenames from the scanned files.
  3. Match Filenames: It matches the filenames with the content in other files, ignoring the case.
  4. Insert Links: When a match is found, it inserts a Wikilink in the content, preserving the original case of the filename in the link.
  5. Skip Metadata and Code: The tool skips adding links in metadata sections and code blocks to avoid unwanted linking.

Examples

  • Simple Linking: If a file named Object-Oriented Programming.md exists and another file mentions "object-oriented programming", the tool will link it as [[object-oriented programming]].
  • Preserve Case: If the mention is "Object-Oriented Programming", the link will be [[Object-Oriented Programming]].
  • No Links in Code Blocks: Mentions inside code blocks are ignored.
  • No Links in Metadata: Mentions inside metadata sections are ignored.
  • Multiple Links: If multiple files are mentioned, each will be linked appropriately.
  • Partial Matches: If a file named Object.md exists, mentions of "object" will be linked as [[object]], but "objects" will not be linked.
  • Complex Linking: If files named Object-Oriented Programming.md, Functional Programming.md, and Object.md exist, and another file mentions "object-oriented programming", "functional programming", and "object", each will be linked as [[object-oriented programming]], [[functional programming]], and [[object]] respectively. Note "object" will not be added inside "object-oriented programming".

Installation

From PyPI

Package: vaultlinker on PyPI

pip install vaultlinker
vaultlinker /path/to/vault/ --help

From source

Clone the repository and install the package (recommended):

git clone https://github.com/arshad115/vault-linker.git
cd vault-linker
pip install -e ".[dev]"

For a quick script-only install without the console command:

pip install -r requirements.txt

Usage

Vault Linker CLI dry run with parallel jobs

vaultlinker dry run with verbose progress (-v) and eight workers (--jobs 8).

After installation:

vaultlinker /path/to/vault/

Or run the module directly:

python vaultlinker.py /path/to/vault/

Use -v / --verbose for progress bars and scan details (default is quiet except warnings and the summary).

Parallel processing (read, link, and write phases):

vaultlinker /path/to/vault/ --jobs 8
vaultlinker /path/to/vault/ --jobs 0   # automatic worker count

Safety options

Preview changes without writing files:

python vaultlinker.py /path/to/vault/ --dry-run

Write linked copies to another directory (vault files stay unchanged):

python vaultlinker.py /path/to/vault/ --output /path/to/linked-vault/

Create a .bak copy of each file before overwriting it in the vault:

python vaultlinker.py /path/to/vault/ --backup

Skip linking a note's title inside its own file (e.g. do not turn README into [[README]] in README.md):

python vaultlinker.py /path/to/vault/ --no-self-links

By default, markdown under .obsidian, .git, attachments, and similar folders is skipped. Add more directory names with --exclude DIRNAME, or pass --no-default-excludes to scan everything.

Limit which notes are processed with vault-relative globs:

vaultlinker /path/to/vault/ --include-glob 'notes/**' --exclude-glob 'templates/**'

Obsidian-aware linking

  • Aliases: YAML alias / aliases in front matter are link phrases; matches use [[Note Title|alias]] when the visible text differs from the note title.
  • Embeds & markdown links: Text inside ![[...]] and [label](url) is not linked.
  • Headings: Text on # heading lines is skipped unless you pass --link-headings.
  • Duplicate filenames: If two notes share the same filename in different folders, the tool warns and uses the note with the longest path as the link target for that title.
  • --use-headings: Also link phrases taken from each note's first # H1 heading.
  • --no-aliases: Only use filenames, not front matter aliases.

Vault Linker audit report in the terminal

Audit the vault (no file changes):

vaultlinker /path/to/vault/ --audit
vaultlinker /path/to/vault/ --audit -v   # include pending link details

Reports pending links (same rules as a dry run), broken [[wikilinks]] with no matching note, notes with zero incoming links, and the most-linked titles.

Remove wikilinks that this tool would create (title and alias forms only; manual links to other targets are kept):

vaultlinker /path/to/vault/ --unlink --dry-run
vaultlinker /path/to/vault/ --unlink --backup

Incremental and blocklist

Re-run only notes that changed since the last successful incremental run (state is stored in .obsidian/vault-linker-state.json). If notes are added or removed, every note is processed again so new titles can link correctly.

vaultlinker /path/to/vault/ --incremental

Skip noisy short titles or specific words:

vaultlinker /path/to/vault/ --ignore-phrase README --min-title-length 4
vaultlinker /path/to/vault/ --ignore-file ./linker-ignore.txt
vaultlinker /path/to/vault/ --case-sensitive --first-link-per-phrase

CI / GitHub Actions

See docs/github-actions.md and the example workflow .github/workflows/vault-linker-example.yml.

Obsidian plugin

Install Vault Linker from Settings → Community plugins, or build from plugin/ (source). Release assets (manifest.json, versions.json, main.js) live at the repo root for Obsidian’s directory scanner.

Vault Linker plugin settings

See plugin/README.md and PUBLISHING.md.

Make sure to back up your vault before using this tool, as in-place runs can make irreversible edits unless you use --dry-run or --output.

Running Tests

To run tests for Vault Linker, use the following command:

pytest

This will execute all the tests and provide you with a summary of the results. Make sure you have all the necessary dependencies installed before running the tests.

TODO

  • Add support for alias links
  • Multithreading
  • Write additional tests for edge cases
  • Make it into a plugin for Obsidian

Contributors

Contributing

We welcome contributions to Vault Linker! If you have an idea for a new feature or have found a bug, please open an issue or submit a pull request.

Steps to Contribute

  1. Fork the repository.
  2. Create a new branch for your feature or bugfix:
    git checkout -b feature-name
    
  3. Make your changes and commit them:
    git commit -m "Description of your changes"
    
  4. Push your changes to your fork:
    git push origin feature-name
    
  5. Open a pull request on the main repository.

License

This project is licensed under the MIT License. See the LICENSE file for more details. © Arshad Mehmood

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

vaultlinker-0.5.1.tar.gz (21.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vaultlinker-0.5.1-py3-none-any.whl (22.4 kB view details)

Uploaded Python 3

File details

Details for the file vaultlinker-0.5.1.tar.gz.

File metadata

  • Download URL: vaultlinker-0.5.1.tar.gz
  • Upload date:
  • Size: 21.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for vaultlinker-0.5.1.tar.gz
Algorithm Hash digest
SHA256 5f07a92a8ef67db2f6dcc1fd32af45bff4f9e0c2b8e7913b0e5e4b0cf4368233
MD5 e6b6a761b06f29dcd62fd0a1cbbebba0
BLAKE2b-256 a4b38aefc9073e75152054bcd97ea261d6e446701e111f5faff77baac4c9e330

See more details on using hashes here.

Provenance

The following attestation bundles were made for vaultlinker-0.5.1.tar.gz:

Publisher: release.yml on arshad115/vault-linker

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file vaultlinker-0.5.1-py3-none-any.whl.

File metadata

  • Download URL: vaultlinker-0.5.1-py3-none-any.whl
  • Upload date:
  • Size: 22.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for vaultlinker-0.5.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b52e8bd4e3df10d5221357c416abf9b3caa308407a0736318917423e7d2967ac
MD5 994e76622506b335b6005b67a6689599
BLAKE2b-256 ef6325077842a58b534e029b6cd1948bfbab1ab9b0a50f3722ac0b5cc5600bc6

See more details on using hashes here.

Provenance

The following attestation bundles were made for vaultlinker-0.5.1-py3-none-any.whl:

Publisher: release.yml on arshad115/vault-linker

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.5.1 This release

2 files

0.5.0

2 files

0.4.3

2 files

0.4.2

2 files

0.4.1

2 files

0.4.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page