by Jesus
Show the number of files and subfolders contained in each folder in the file explorer.
Folder Child Count
An Obsidian plugin that shows the number of files and subfolders contained in each folder, right next to the folder name in the file explorer.
Features
- Shows a small count badge next to every folder in the file explorer.
- Count files and folders, files only, or folders only.
- Optionally hide the badge for empty folders.
- Customizable color, style (badge / plain / outline), size and bold.
- Optionally show the count only while hovering a folder.
- Updates automatically when files/folders are created, deleted or renamed.
- Works on desktop and mobile.
Usage
- Enable the plugin in Settings → Community plugins.
- Open the file explorer: each folder now shows its child count.
- Configure it under Settings → Folder Child Count.
Customization
The count can be styled from the plugin settings or with a CSS snippet.
From settings
Under Settings → Folder Child Count → Appearance:
| Setting | What it does |
|---|---|
| Use a custom color | Use your own color instead of the theme's muted text color. |
| Color | The color to use (shown when "Use a custom color" is on). |
| Style | Badge (default), Plain text (no background) or Outline. |
| Size | Small, Normal or Large. |
| Bold | Render the count in bold. |
| Show only on hover | Reveal the count when hovering the folder row (desktop only). |
With a CSS snippet
Create <your-vault>/.obsidian/snippets/folder-count.css and enable it under
Settings → Appearance → CSS snippets:
.folder-child-count {
color: var(--text-accent);
background-color: transparent;
font-weight: 600;
font-family: var(--font-monospace);
font-size: 0.7em;
}
/* Reveal the count only while hovering a folder */
.nav-folder-title .folder-child-count {
opacity: 0;
transition: opacity 120ms ease-in-out;
}
.nav-folder-title:hover .folder-child-count {
opacity: 1;
}
By default the badge uses Obsidian's CSS variables, so it follows your theme without extra effort.
Requirements
- Obsidian 1.13.0 or later.
- Node.js 24 or later (development only; see
.nvmrc).
The plugin's settings tab is built with Obsidian's declarative settings API
(getSettingDefinitions, available since 1.13.0), which keeps the settings
searchable and avoids the deprecated imperative display() method. If you need
to support older app versions, you can lower minAppVersion in manifest.json
and add a display() fallback that renders the same options with new Setting().
Development
This project uses TypeScript and esbuild.
# Install dependencies
npm install
# Compile and watch for changes (development)
npm run dev
# Run the unit tests
npm run test
# Type-check and produce a production build
npm run build
# Lint the source
npm run lint
Testing in a vault
The built plugin must live in the vault's plugins folder:
<your-vault>/.obsidian/plugins/folder-child-count/
There is a helper script that builds the destination folder and links the
required files (main.js, manifest.json, styles.css) for you:
npm run build
npm run install:vault -- /path/to/your/vault
# or set the path once:
OBSIDIAN_VAULT=/path/to/your/vault npm run install:vault
# copy real files instead of symlinks:
npm run install:vault -- /path/to/your/vault --copy
By default the files are symlinked, so npm run dev rebuilds are picked up
as soon as you reload Obsidian (Ctrl/Cmd + R). Then enable the plugin under
Settings → Community plugins.
Project structure
.
├── src/
│ ├── main.ts # Plugin entry point, file-explorer integration, observers
│ ├── badge.ts # Renders the count badge in a folder title
│ ├── settings.ts # Settings interface, defaults and settings tab
│ └── folder-count.ts # Pure counting logic
├── tests/
│ ├── folder-count.test.ts # Unit tests for the counting logic
│ ├── badge.test.ts # DOM tests for the badge (jsdom)
│ ├── plugin.test.ts # Integration tests for main.ts + observers
│ ├── helpers.ts # Test factories for folders/files
│ ├── obsidian-mock.ts # Runtime stub for the types-only obsidian package
│ └── setup-dom.ts # jsdom shim for Obsidian's DOM helpers
├── .github/ # CI, release workflow, templates and FUNDING
├── esbuild.config.mjs # Build configuration
├── vitest.config.ts # Test configuration
├── manifest.json # Obsidian plugin manifest
├── styles.css # Badge styling
└── versions.json # Version -> minimum app version map
Testing
Tests run with Vitest in a jsdom environment. The
obsidian package only ships type declarations, so:
vitest.config.tsaliasesobsidiantotests/obsidian-mock.ts, a tiny runtime stub exposing the classes the source imports.tests/setup-dom.tsshims the handful ofElement.prototypehelpers Obsidian adds (createSpan,createDiv,setText) sobadge.tsruns under jsdom.
npm run test # run once
npm run test:watch # watch mode
Continuous integration
.github/workflows/ci.ymlruns lint, tests and build on pushes and pull requests..github/workflows/release.ymlbuilds and publishes a GitHub release when a tag is pushed (the tag must matchmanifest.json'sversion).
Releasing
-
Update the version with
npm version patch|minor|major(this runsversion-bump.mjsto keepmanifest.jsonandversions.jsonin sync). -
Tag and push. The release workflow builds, attests and publishes:
npm version patch # updates manifest.json + versions.json git push --follow-tagsnpm versionalso commits the bumpedmanifest.json/versions.jsonand creates the tag. Tags are unprefixed (.npmrcsetstag-version-prefix=), e.g.1.0.1rather thanv1.0.1..github/workflows/release.ymlruns the tests and build, generates a signed build provenance attestation (GitHub Artifact Attestations, backed by Sigstore) plus aSHA256SUMSfile, and creates the release withmain.js,manifest.json,styles.cssandSHA256SUMS.
Verifying a signed release
Attestations are keyless and bound to this repository's release workflow. Anyone can verify that a downloaded asset was produced by this repo's CI from the tagged commit:
gh attestation verify main.js --repo <owner>/<repo>
gh attestation verify manifest.json --repo <owner>/<repo>
gh attestation verify styles.css --repo <owner>/<repo>
A successful check means the file's digest matches the attested build and that
the provenance was issued by a workflow in that repository. For an additional
layer of trust you can also sign the release tags with GPG (git tag -s v1.0.0).
Checksums
Each release also ships a SHA256SUMS file (generated with npm run checksums).
Verify the downloaded artifacts against it:
# Linux
sha256sum --check SHA256SUMS
# macOS
shasum -a 256 --check SHA256SUMS
Security
An authorized security self-assessment (source review, dependency audit,
supply-chain review and secret scanning) is documented in
pentest/final-report.md.
License
Contributing
See CONTRIBUTING.md for the development setup and guidelines.
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.