# Obsidian Icon Folder Migrator

Move Obsidian Icon Folder plugin icon assignments from data.json into note YAML frontmatter.

Canonical: https://tools.karlquinsland.com/tools/python/obsidian-icon-folder-migrator/
Published: 2026-06-21
Updated: 2026-06-21
Tags: obsidian, markdown, yaml, frontmatter, migration, python


---


# Obsidian Icon Folder Migrator

![Tool icon](https://tools.karlquinsland.com/tools/python/obsidian-icon-folder-migrator/images/tool-icon.svg)

Migrate icon assignments from the old Obsidian Icon Folder plugin data file into each note's YAML frontmatter.
The tool reads `.obsidian/plugins/obsidian-icon-folder/data.json`, resolves each vault-relative entry to an existing Markdown note, and adds `icon: ...` to that note.

It is designed for cautious cleanup work: dry-run is the default, files are never created or moved, existing `icon` values are preserved unless you explicitly pass `--update-existing`, and successfully migrated JSON entries can optionally be removed with `--remove-from-json`.

## Example Usage

```shell
uv run "https://tools.karlquinsland.com/tools/python/obsidian-icon-folder-migrator/tool.py"

```

```shell
# Preview what would change in the current directory vault.
uv run ./tool.py --vault-root ~/Notes

# Write note frontmatter updates after reviewing the dry run.
uv run ./tool.py --vault-root ~/Notes --no-dry-run

# Replace differing existing frontmatter icon values.
uv run ./tool.py --vault-root ~/Notes --update-existing --no-dry-run

# Remove data.json entries after they are migrated or already match.
uv run ./tool.py --vault-root ~/Notes --remove-from-json --no-dry-run

# Also remove data.json keys that no longer resolve to notes.
uv run ./tool.py --vault-root ~/Notes --on-missing remove --remove-from-json --no-dry-run
```

## Behavior

- Reads string icon values and object values with `iconName`.
- Resolves note paths directly, folder paths through `index.md`, and extensionless paths through `<path>.md`.
- Adds `icon` as the last frontmatter key when it is missing.
- Leaves an existing matching `icon` untouched.
- Skips a differing existing `icon` unless `--update-existing` is passed.
- Skips unsafe absolute paths and paths containing `..`.

## Dependencies


This tool relies on 3 dependencies.

| # | Library | Version | Via |
| ---: | --- | --- | --- |
| 1 | click | >=8.1 | - |
| 2 | ruamel.yaml | >=0.18 | - |
| 3 | structlog | >=24 | - |

## Changelog



## `dbdf1e2` - June 21, 2026 14:20

- feat: add obsidian icon folder migrator

[view history on github](https://github.com/kquinsland/tools/commits/main/content/tools/python/obsidian-icon-folder-migrator/tool.py)

[View full changelog (1 commit)](https://tools.karlquinsland.com/tools/python/obsidian-icon-folder-migrator/changelog/index.md)


