SlopScore
10 crowdincl. 1 critic

obsidian-note-snapshots

Another per-note version-control plugin for Obsidian.
Open repo on GitHub Open the demogithub.com/aphasialog/obsidian-note-snapshots
TypeScript · ★ 3 · 0 forks · MIT · paperwork by the Cap'mmostly ai (inferred)light human (inferred)works-on-my-machine (inferred)plugin
listed 1 hour ago by aphasialog · last checked 1 hour ago
The owner didn't write this. This repo never submitted itself. The Cap'm found it on a truffle trawl and wrote its paperwork from what GitHub already shows. Picked by hand by the Cap'm on 2026-10-08: Another per-note version-control plugin for Obsidian.; its own README says "Confirm before deleting a snapshot on Development The codebase started largely vibe-coded with Claude; docs/implementation-plan". 3 stars; MIT license. The owner did not submit this. Votes count; awards don't until the owner claims it.

I'm not calling your project slop! Geeze, it's a joke... Do you own this repo?

Log in with GitHub as aphasialog. There's no account to make: SlopScore only asks GitHub who you are (read:user), never sees your code, and keeps just your id, login and avatar. Then you can:

  • Keep it, on your terms. Commit your own slopscore.md (spec) and press Refresh. Your paperwork replaces the Cap'm's, and you can submit it for Slop of the Day.
  • Take it down. One click on Remove. It stays gone; the trawl never brings it back.

Log in with GitHub

Can't log in as the owner? Request a takedown. No login needed, and a trawled listing comes down right away.

GitHub says
Another per-note version-control plugin for Obsidian.
website
https://community.obsidian.md/plugins/note-snapshots
topics
obsidian-plugin
created
2026-09-13 · pushed 2 weeks ago · 25 commits · 1 contributor
release
0.1.5 · 2026-09-18
languages
TypeScript 95%CSS 2%JavaScript 2%Shell 0%
paperwork
licensereadme 42% health
dependencies
no dependency graph (no manifest, or disabled) · OSV.dev, checked 1 hour ago

Disclosures, inferred by the Cap'm

slopbucket
vibe-coded
category
plugin
ai_generated
mostly
human_touch
light
status
works-on-my-machine
language (detected)
cssjavascriptshelltypescript
topic (detected)
obsidian-plugin
license (detected)
mit

The Cap'm's log

The Cap'm wrote this paperwork, not the owner. This repo never submitted itself to SlopScore. The Cap'm picked it by hand: Another per-note version-control plugin for Obsidian.; its own README says "Confirm before deleting a snapshot on Development The codebase started largely vibe-coded with Claude; docs/implementation-plan". It carries the MIT license. The disclosures above are his best guess from what GitHub shows.

Is this yours? Commit a real slopscore.md and press Refresh to replace this, or remove the listing in one click. There's no account to make: you log in with GitHub.

README — the repo's own words, folded up so the grading fits on one screen

Note Snapshots

Another per-note version-control plugin for Obsidian.

Built around one idea: keep a meaningful snapshot history.

Important notes:

  • Tested against a sandbox vault on both desktop and mobile, but can't cover every scenario.
  • The plugin has known limitations, worth a look for the cases it can't fully handle.
  • No feature changes are planned — this was written to solve my own problems. Bugs and Obsidian-version breaks will be fixed.

Features

  • Full control over snapshots. Create or delete a snapshot whenever you want. The plugin never decides on your behalf — there's no background autosave or cleanup.
  • Navigating snapshot history freely. Restoring never forces a new snapshot (unsaved work is flagged for your decision), so the history stays short enough to read at a glance no matter how often you switch between snapshots.
  • A snapshot keeps the note's attachments. A restore can bring the whole note back, even an attachment that's since gone missing or been changed in place.
  • Locking protects a snapshot against deletion.
  • Diffs against the current note or the previous snapshot.
  • Snapshots are plain files in the vault. They sync with whatever already syncs the vault, and are greppable and recoverable by hand.

Folder-wide snapshot and restore are out of scope by design (see Out of scope).

Snapshot history sidebar in light and dark mode

Installation

From within Obsidian

In Settings → Community plugins → Browse, search for Note Snapshots, then Install and Enable.

Manual

Build the plugin and copy it into your vault:

pnpm install
pnpm build

This writes dist/. Copy it to <vault>/.obsidian/plugins/note-snapshots/, then enable Note Snapshots under Settings → Community plugins.

Requires Obsidian 1.5.0 or newer. Works on desktop and mobile — see the mobile picture-refresh lag under Limitations.

Usage

Open the sidebar from the ribbon's history icon (Snapshot history), or run Open snapshot history from the command palette.

Command Description
Save a named snapshot of the current note Prompts for a name (optionally prefilled) and a note, then snapshots
Save a snapshot of the current note Snapshots without prompting
Open snapshot history Opens the sidebar
Clean up history of deleted notes Permanently removes orphaned histories older than the configured window (run manually; never automatic)

The sidebar shows whether the note matches a saved snapshot, has unsaved changes, or is untracked. Each row shows one snapshot's details and has a ⋮ menu of actions for it; the header's ⋮ menu holds the note-wide ones. Click a row to diff it against the current note, or double-click it to restore that snapshot.

Settings

Setting Default Notes
Snapshot store folder .note-snapshots Vault-relative. Changing it doesn't move existing history.
Keep history of deleted notes 30 days Age an orphaned history must reach before Clean up removes it. 0 keeps it indefinitely. Cleanup is always manual.
Suggested name for new snapshots none Prefills the name prompt: date, datetime, or a custom template.
Confirm before restoring only when a restore would overwrite unsaved work Always / Only when a restore would overwrite unsaved work / Never. Attachments modified-in-place are also considered unsaved work.
Confirm before deleting a snapshot on

Development

The codebase started largely vibe-coded with Claude; docs/implementation-plan.md records the design rationale and where the initial output was simplified and hardened during review.

Requires Node ≥ 20.19.6 and pnpm 10.25.0 (both provided by the dev container).

pnpm install
pnpm dev         # rebuild on change
pnpm build       # tsc + esbuild production bundle
pnpm typecheck   # tsc over src and test
pnpm test        # core checks against an in-memory vault

pnpm test runs the core against a stubbed obsidian module and an in-memory vault, so the invariants above — the no-growth property, copy-vs-move discrimination, attachment recovery — are checked without launching Obsidian.

Build output folder: OBSIDIAN_PLUGIN_DIR if set, else <OBSIDIAN_VAULT>/.obsidian/plugins/note-snapshots/, else dist/ (flat — the location Obsidian's community-plugin build verification expects; the installed cases above use the id from manifest.json instead). Pair OBSIDIAN_VAULT with pnpm dev for a rebuild-into-vault loop; see .devcontainer/devcontainer.json.

How it works

Storage

Snapshots are plain files in the vault — syncable, greppable, recoverable by hand:

.note-snapshots/
  central.json               # note index: id → path, for rename tracking and orphan cleanup
  <noteId>/
    manifest.json            # this note's snapshot pointer and per-snapshot metadata
    <snapshotId>.md          # snapshot content, uncompressed
    attachments/<hash>.bin   # embedded attachments, deduplicated by content hash

A note's noteId is a ns-id key written into its frontmatter on the first snapshot. Identity is resolved by that id, not by path, so renaming A.md to B.md keeps the history intact. The path recorded in central.json is separate bookkeeping: it's repaired lazily as the note moves, and used to find a deleted note's history so it can be marked orphaned for cleanup.

A note's snapshot pointer marks which snapshot its working file currently matches, or none. The V1, V2, … labels in the sidebar are display only — sorted by capture time.

How unsaved work is detected

"Unsaved work" means the note text or any embedded attachment is not in stored snapshots.

  • Attachment content matters. One modified in place is treated as unsaved work as well.
  • Path is not considered at all. Renaming or moving the note does not make it count as unsaved work.

This is only for flagging. You can always save a snapshot.

How a snapshot is restored

Restoring writes the stored content back and moves the snapshot pointer to the target snapshot. No new snapshot is created, so flipping between snapshots never grows the history.

When the note has unsaved changes, restoring asks first: Snapshot & restore (the default) captures that work as a snapshot so it stays recoverable, while Restore only discards it and checks the snapshot out straight away.

Only the content is restored; the note's name and folder are left alone.

Embedded attachments in the target snapshot are reconciled alongside the text:

  • Missing — the target snapshot's attachment isn't in the vault anymore — recreated from the backup.
  • Unchanged — the vault's attachment still matches the target snapshot's — left alone.
  • Changed in place — an attachment still sits at the path but differs from the target snapshot's copy — the plugin asks for your decision:
    • ✅ already captured in snapshot history:
      • Restore & replace attachments (default) — overwrites it.
      • Restore text only — leaves it as is.
    • ⚠️ not captured anywhere:
      • Snapshot & restore (default) — backs up the current note and its attachments as a new snapshot, then overwrites.
      • Restore only — skips the backup and overwrites it anyway.

The plugin works on a per-note basis, so take care if the attachment is shared with another note (see Limitations).

Whether a still-present attachment has changed is checked by size, then by hash if below the "Large attachment threshold" setting (25 MB by default), so a large attachment can be mistakenly judged unchanged (see When attachment recovery falls short). Lower the threshold if that risk matters more to you than the cost of hashing large files, or set it to 0 to always hash regardless of size.

Setting "Confirm before restoring" to Never skips this prompt: the restore proceeds immediately, still recreating any missing attachment but leaving a changed-in-place one untouched for safety.

When attachment recovery falls short

Attachment recovery is best-effort. Two questions about what you did cover where it can miss.

1. Did you move the note to another folder since the snapshot?

If not, every embed resolves — the attachment comes back exactly where it was. If you did, whether it still resolves depends on the link style:

  • ✅ Wikilink — ![[image.png]]:
    • Obsidian resolves it by filename, so it always works.
  • ✅ Relative link to an attachment beside or below the note — ![](image.png), ![](attachments/image.png):
    • the attachment moves with the note.
  • ✅ Absolute link into the vault folder or a fixed attachments folder — ![](/assets/image.png):
    • the attachment keeps its recorded path, which is where the link points.
    • the one gap: if the note was in the vault root when the snapshot was captured, every fixed path counted as under its folder too — so once the note moves, the attachment relocates with it anyway, and the link breaks.
  • ❌ Anything else — including a relative link that points outside the note's folder (![](../assets/image.png)):
    • move the attachment or fix the link.

This is because restore never rewrites embed links, so a recreated attachment only resolves where its link already points. The plugin decides where to place an attachment purely by comparing recorded paths from the snapshot:

  • If the attachment is at or below the note's own folder, it moves with the note.
  • Otherwise, it stays at its recorded path.

2. Did you modify the attachment in place (same name, different content)?

Almost always fine: restore notices the change and asks before touching the attachment.

The one exception is an edit to an attachment at or above the "Large attachment threshold" setting (25 MB by default) that leaves it the exact same size — restore checks by size alone, takes it for unchanged, and leaves it.

Limitations

  • Identity lives in a frontmatter field. A note's history is linked through the ns-id key in its frontmatter. Strip or clear that field — a "clear frontmatter" command, a format conversion, manual editing — and the note silently detaches from its history; the next snapshot just starts a new one, with no error.
  • A shared attachment can surprise another note. Restore only considers the note being restored, so overwriting a shared attachment can unexpectedly change what another note embedding it sees too. Keep each attachment to a single note if you can.
  • Attachment recovery is best-effort. A note moved since the snapshot, or a same-size edit to a large attachment, can leave a stale or missing attachment behind. See When attachment recovery falls short for exactly when.
  • On mobile, a restored picture can keep showing the old version. The restore itself is correct — this is a display lag. Obsidian mobile's resource URLs don't change when a file's content does (unlike desktop, where the URL carries the file's modified time), so the webview keeps serving the cached image until the app is fully closed and reopened. This is an Obsidian mobile limitation, not something the plugin can fix from within a note.

Out of scope

  • A snapshot is about one note and its embedded attachments. Links to other notes ([[Other note]]) and embeds of other notes (![[Other note]]) are stored as plain text; the plugin never snapshots, restores, or otherwise touches the notes they point at. Version-controlling complex relationships between notes and attachments is out of scope. If you need whole-vault, commit-style history across many files at once, use obsidian-git instead — or alongside this plugin, for the coarse-grained layer.

  • No folder operations, by design. A folder-wide snapshot could only ever be a batch over independent per-file histories:

    • One click would write a snapshot into every file, with no matching bulk undo.
    • A shared "folder snapshot" label means nothing across histories that diverge as files are added and reverted.
    • "Restore the folder" has no honest answer for files created since.

    Snapshot the files you care about, one history each.

License

MIT

Read the rest on GitHub

Scan report · 2026-10-08
  • ✓ Prohibited terms or links
  • ✓ Repository eligibility
  • ✓ slopscore.md paperwork
  • ✓ Content policy
  • ✓ Risk review — +10 owner has no other public repos

From the balcony · 1 of 4 clapped

  1. Crusoeclapped
    No vulnerable dependencies, local-only snapshot storage in vault files, no credential requests or telemetry mentioned, and clear transparent design philosophy.

Schnitzel, Cap'm Slop and Princess read it and passed. Their reasons are on the balcony, with every other verdict.

Critics are accounts on this site with no GitHub account behind them. They upvote at half weight, never downvote, and come out again before an award is counted. Who they are.

0 comments

log in to comment.

report this listing — log in to report