Shard Icons
approvedby Somonor Hong
Give folders an icon from the Material Icon Theme, a brand logo or a symbol, right from the file explorer. - This plugin has not been manually reviewed by Obsidian staff.
Shard Icons
Folder icons for the Obsidian file explorer, in the style of VS Code's Material Icon Theme.
Right-click any folder → Change icon…, and pick from three sets:
| Tab | Ids | What it is |
|---|---|---|
| Folders | folder-src, folder-docs, … | The Material Icon Theme's own folder icons |
| Logos | logo-fastapi, logo-godotengine, … | A folder in the brand color with the Simple Icons logo as its emblem |
| Symbols | symbol-game, symbol-money, … | A folder with a Lucide glyph, using the icons Obsidian already ships |
Folders you have not touched can be matched automatically: src, docs, images, .github
and a few thousand other names get the icon the theme would give them. Files can do the same,
by name and extension, if you turn that on.
The ids are the same ones cachewraith-explorer stores, so a folder looks the same in both.
Install
With BRAT (now)
- Install BRAT from Community Plugins.
- BRAT → Add beta plugin →
https://github.com/cachewraith-labs/shard-icons. - Enable Shard Icons in Settings → Community plugins.
BRAT follows GitHub releases, so it picks up new versions the same way the official installer does.
Manually
Download main.js, manifest.json and styles.css from the
latest release into
<your vault>/.obsidian/plugins/shard-icons/, then reload Obsidian.
From Community Plugins (later)
Once the plugin is accepted, Settings → Community plugins → Browse → Shard Icons.
Using it
- Change an icon — right-click a folder in the file explorer → Change icon…. Search, or
switch tabs with the mouse; the arrow keys move through the grid, Enter picks and
Esc closes. The icon the theme would have guessed from the folder name is shown
first, badged
match. - Reset one folder — right-click → Reset icon to default, or Reset to default in the dialog.
- From the keyboard — the command Change icon of the active file's folder opens the same dialog for whatever note you are in.
- Renaming and moving keeps icons, including every subfolder's. Deleting a folder drops them.
Settings
| Setting | Default | What it does |
|---|---|---|
| Automatic folder icons | on | Folders with no chosen icon get one matched from their name |
| File icons | off | Files get an icon from their name and extension |
| Icon size | 16 px | Between 12 and 28 |
| Clear all custom icons | — | Asks first; cannot be undone |
Everything lives in .obsidian/plugins/shard-icons/data.json: your settings and a plain
path → icon id map. Nothing else is stored, and the plugin makes no network requests and
collects nothing.
An icon id this version does not recognise — from a newer release, or from a vault synced the other way — draws a plain folder and is kept, not deleted.
Development
npm install
npm run dev # rebuild main.js on change
npm run build # lint-clean production bundle
npm test
npm run lint
npm run typecheck
To try it in a vault, symlink the repository into the vault's plugin folder:
ln -s "$PWD" "<your vault>/.obsidian/plugins/shard-icons"
Use a scratch vault rather than your real one: Obsidian writes data.json straight into this
folder when the plugin runs.
How the icons get into the bundle
An Obsidian plugin ships as one main.js, so there is no server to fetch SVGs from.
scripts/build-icons.ts reads material-icon-theme and simple-icons out of node_modules
and writes src/generated/icons.ts: the lookup table, the folder and file SVGs, and the
brand-logo folders it draws itself from the theme's folder shape. That file is generated by
npm run build, npm run dev and npm test, and is git-ignored — the icon packages are the
source of truth, pinned in package-lock.json.
Symbols cost nothing: they are Obsidian's own Lucide icons, fetched at runtime with getIcon.
SHARD_ICONS_FILE_ICONS=0 npm run build leaves the file icons out, which takes the bundle from
about 1.2 MB down to roughly 0.6 MB, at the cost of the File icons setting.
Layout
src/
main.ts lifecycle, events and commands — wiring only
icons/ ids, the FolderIcon union, the theme's lookup rules, rendering
explorer/ deciding what each row shows, and putting it there
picker/ the modal
settings/ settings types, validation, the settings tab
store/ path → icon assignments, persisted through loadData/saveData
generated/ build output (git-ignored)
scripts/build-icons.ts
tests/ vitest, no Obsidian required
Everything except icons/render.ts, explorer/FileExplorerIcons.ts, picker/, settings/ SettingsTab.ts and store/IconStore.ts is free of the Obsidian API, which is what lets the
rules be tested directly.
Releases
npm version <x.y.z> bumps package.json, then the version script copies that into
manifest.json and records the minimum Obsidian version in versions.json, and npm commits
and tags the three together. The tag is the bare version with no v prefix — that is what
Obsidian expects, and .npmrc sets tag-version-prefix="" so npm does not add one.
npm version 0.2.0
git push --follow-tags
Pushing that tag runs release.yml: lint, tests, build, a
check that the tag matches manifest.json, then a GitHub release with main.js,
manifest.json and styles.css attached. That release is what Obsidian's updater and BRAT
read.
The very first release is the exception — package.json already says 0.1.0, and npm version refuses to set the version it is already on, so tag it by hand:
git tag 0.1.0
git push origin 0.1.0
update-icons.yml bumps the two icon packages weekly,
rebuilds, runs the tests and opens a PR, so new icons arrive on their own. Dependabot handles
the rest of the toolchain.
Community plugin submission checklist
-
manifest.jsonat the repository root withid,name,version,minAppVersion,description,author,isDesktopOnly -
id(shard-icons) andnamedo not contain "Obsidian" or "plugin" -
versions.jsonmaps each version to its minimum Obsidian version - A GitHub release tagged with the bare version, with
main.js,manifest.jsonandstyles.cssas assets -
LICENSEat the repository root -
main.jsandsrc/generated/are git-ignored, not committed - No network requests, no telemetry, no bundled analytics
- Styling through Obsidian's CSS variables; no hard-coded colors outside the icon art
-
isDesktopOnly: false, and no Node or Electron API in the shipped bundle - Everything the plugin injects is removed in
onunload - Submit the plugin at community.obsidian.md — sign in,
link the GitHub account, add the repository. Submission is no longer a pull request to
obsidianmd/obsidian-releases; that repository has pull requests disabled.
Licenses
This plugin is MIT (see LICENSE). The icons it bundles are not:
- Material Icon Theme — MIT, © Philipp Kief and contributors.
licenses/material-icon-theme-LICENSE.txt - Simple Icons — CC0-1.0.
licenses/simple-icons-LICENSE.md - Lucide — ISC, shipped by Obsidian itself and not bundled here.
Brand logos are trademarks of their respective owners; the CC0 waiver covers the icon files,
not the marks. See licenses/ for the full notices, which the build copies from
node_modules so they always match the versions in the bundle.
For plugin developers
Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.