Shard Icons

approved

by 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.

1 downloadsUpdated todayMIT

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:

TabIdsWhat it is
Foldersfolder-src, folder-docs, …The Material Icon Theme's own folder icons
Logoslogo-fastapi, logo-godotengine, …A folder in the brand color with the Simple Icons logo as its emblem
Symbolssymbol-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)

  1. Install BRAT from Community Plugins.
  2. BRAT → Add beta pluginhttps://github.com/cachewraith-labs/shard-icons.
  3. 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

SettingDefaultWhat it does
Automatic folder iconsonFolders with no chosen icon get one matched from their name
File iconsoffFiles get an icon from their name and extension
Icon size16 pxBetween 12 and 28
Clear all custom iconsAsks 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.json at the repository root with id, name, version, minAppVersion, description, author, isDesktopOnly
  • id (shard-icons) and name do not contain "Obsidian" or "plugin"
  • versions.json maps each version to its minimum Obsidian version
  • A GitHub release tagged with the bare version, with main.js, manifest.json and styles.css as assets
  • LICENSE at the repository root
  • main.js and src/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:

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.