Miller Columns

unlisted

by Nelson Love

Navigate your notes as Miller columns over parent/children frontmatter, with drag-to-reparent.

Updated 2d agoMIT
View on GitHub

Miller Columns

Browse your notes as Finder-style Miller columns — a horizontally-scrolling stack of panes where each column shows the children of whatever you selected in the column to its left. Click a note with children to drill in and open a new column; click a leaf note to open it. Use Miller Columns as a standalone view, or (on Obsidian 1.10.0+ with the Bases plugin enabled) register it as a custom view type inside your .base files.

The hierarchy isn't a folder structure — it comes from parent / children frontmatter properties on your notes, the same convention used by Breadcrumbs and abstract-folder. Miller Columns reads that frontmatter directly, so it interoperates with either plugin out of the box — no configuration required if you're already using their default field names, and no hard dependency on either one.

Frontmatter convention

A note declares its parent (and/or its children) as wikilinks in frontmatter:

---
parent: "[[Project Alpha]]"
---

Children can be declared the other direction instead (or in addition — both are merged into the same graph):

---
children:
  - "[[Task 1]]"
  - "[[Task 2]]"
---

A note can also have more than one parent — set parent to a list to place it in multiple branches of the tree at once:

---
parent:
  - "[[Project Alpha]]"
  - "[[Q3 Priorities]]"
---

Notes with no parent become roots and appear in the first column. Property names are configurable in settings (defaults: parent / children), and links that don't resolve to an existing note are skipped rather than shown as broken entries.

Drag gestures

  • Drag a note onto a folder (a note that already has children) — moves it, replacing its existing parent(s) with that folder.
  • ⌘/Ctrl-drag a note onto a folder — adds the folder as an additional parent instead of replacing, giving the note multiple parents.
  • Drop on empty space in the root column — clears all parents, making the note a root.

Dropping a note onto one of its own descendants is rejected with a notice; nothing is written. Dropping a note onto itself is simply ignored (no-op, no notice).

Known limitation: only folders (notes that already have at least one child) are valid drop targets. A childless note can't yet be turned into a parent by dragging onto it — to give a note its first child, add the parent/children frontmatter by hand once, and drag-and-drop works on it from then on.

Sorting

Each column can be sorted one of four ways (set in settings):

  • Name — alphabetical, folders (notes with children) before files.
  • Thermal — most recently modified first.
  • Gravity — most descendants first (biggest subtrees rise to the top).
  • Rot — staleness-weighted: notes that are both old and have a large, neglected subtree sort first, so overgrown, untouched branches surface.

Settings

  • Parent properties / Children properties — comma-separated frontmatter property names to read (defaults parent / children).
  • Sort order — one of the four sorts above.
  • Open in new tab — open a clicked note in a new tab instead of the current one.
  • Use my Breadcrumbs fields — a one-click button that inspects your installed Breadcrumbs configuration and copies its "ups"/"downs" field groups into the Parent/Children property settings above, so the two plugins read the exact same frontmatter.

Use as a Bases view

Miller Columns can also register as a custom view type within Obsidian's Bases plugin (requires Obsidian 1.10.0+ and the Bases core plugin to be enabled; on older versions or with Bases disabled, the plugin still works as a standalone view).

To use:

  1. Open any .base file and add/switch a view to "Miller Columns" as the view type.
  2. Configure the view in the Bases view settings UI:
    • Parent property (default: note.parent)
    • Children property (default: note.children)
    • Sort — Name, Thermal, Gravity, or Rot (see above).

Scoped to the Base's query results: Only notes matching the Base's filters appear in the hierarchy. Parent links pointing outside the result set are ignored; those notes appear as roots instead.

Drag-to-reparent: Works only when the .base file is opened standalone in its own tab. When the base is embedded (![[Foo.base]] or a `base` code block), the view is read-only navigation — the same click-to-drill gestures work, but dragging is disabled. Drag a note onto a folder to move it, ⌘/Ctrl-drag to add a parent, or drop in the empty root-column area to make a note a root.

Opening notes: Clicking a leaf note opens it in the active tab. (The standalone Miller Columns view's "open in new tab" setting doesn't apply to the Bases view.)

Installation

Desktop only for v1 — the horizontal column layout and drag-to-reparent gestures rely on desktop drag-and-drop (manifest.json sets isDesktopOnly: true). It will not install or run on Obsidian mobile.

Not yet in the Obsidian community plugin catalog. Until then, install manually or via BRAT.

Manual:

  1. Download main.js, manifest.json, and styles.css from a release.
  2. Create a folder <vault>/.obsidian/plugins/miller-columns/ and place the three files inside it.
  3. Reload Obsidian and enable Miller Columns in Settings → Community plugins.

Via BRAT:

  1. Install and enable the BRAT community plugin.
  2. Run BRAT: Add a beta plugin for updates, and enter this repository (nelsonlove/obsidian-miller-columns).
  3. Enable Miller Columns in Settings → Community plugins.

License & provenance

MIT licensed (see LICENSE). This is an independent, clean-room implementation — it reads the same parent/children frontmatter convention as abstract-folder for interoperability, but no code was copied from it or from any GPL-3.0 project; nothing here is a derivative work.

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.