Skip to main content

rematter

Frontmatter management CLI for Obsidian vaults. Validate metadata against a schema, auto-fix missing fields, sync markdown to external destinations like Astro content collections, rename fields, and prepend dates to filenames -- all async with parallel threads for great performance on large vaults. Every command comes with dry-run support to preview the operations, your notes are precious, and we value that! We're Obsidian weirdos too.

The tool is still very early, there is much more to come.

Install

The easiest way to install if you're a Python user is via uv, but there's also a compiled binary (via PyInstaller) available on Homebrew for macOS and Linux:

# uv (recommended)
uv tool install rematter

# Homebrew
brew install g15r/tap/rematter

Quick start

# Validate frontmatter against a schema
rematter validate ~/vault/notes

# Auto-fix missing fields with defaults
rematter validate ~/vault/notes --fix

# Sync to an Astro content collection
rematter sync ~/vault/notes --dest ~/site/src/content/notes

# Preview any command without writing
rematter sync ~/vault/notes -n

Commands

validate -- Check frontmatter against a schema

rematter validate <directory> [--schema PATH] [--fix] [--recursive] [--dry-run]

Validates every markdown file against the .rematter.yaml schema in the target directory. Report-only by default -- exits 1 on failures. Unrecognized fields always error.

--fix sets defaults for missing properties and reorders keys to match schema order. Combine with --dry-run (-n) to preview what would change.

sync -- Sync vault markdown to an external destination

rematter sync [source] [--dest PATH] [--link-path-prefix PREFIX] [--recursive] [--dry-run]

Syncs publishable markdown files to an external directory. The pipeline per file:

  1. Skip files where publish is not true
  2. Slugify the filename for the destination
  3. Skip if dest has the same modified value (no changes)
  4. Extract type from capitalized Obsidian tags (#Book -> type: book)
  5. Validate against schema
  6. Resolve creator wikilinks to {name, slug} objects
  7. Resolve body wikilinks to markdown links (broken links -> plain text)
  8. Resolve media references and rewrite hero image paths
  9. Stamp synced timestamp, set title from source filename
  10. Strip sync: false fields from destination output
  11. Write dest file, copy referenced media, stamp synced back on source

Requires a .rematter.yaml config with at least dest (or pass --dest). CLI flags override config values.

transform -- Rename a frontmatter field

rematter transform <directory> --field OLD --to NEW [--recursive] [--dry-run]

Renames a field across all markdown files. Key order is preserved. Files where the target name already exists are skipped with an error.

date-extract -- Prepend dates to filenames

rematter date-extract <directory> [--field DATE_FIELD] [--recursive] [--dry-run]

Reads a date field (default: Date), prepends YYYY-MM-DD - to the filename, and removes the field from frontmatter. Already-prefixed files are skipped. Useful for systems like Notion that export a date field, when you want to pull that out into the filename for Obsidian's filesystem-centric approach.

Configuration

Each directory can be given a .rematter.yaml that combines sync config and frontmatter schema:

# Sync config
link_path_prefix: /notes
dest: ~/site/src/content/notes/
ignore:
  - draft-*
  - private/*
media:
  source: _media
  dest: src/assets
  link_prefix: /assets

# Frontmatter schema
properties:
  status:
    type: string
    required: false
    enum: [not_started, in_progress, on_hold, done, cancelled]
    default: not_started
  creators:
    type: list
    required: false
  own:
    type: bool
    required: false
    default: false
    sync: false          # validated but stripped from dest
  hero:
    type: string
    required: false
    requires: [heroAlt]  # co-dependency: both or neither
  heroAlt:
    type: string
    required: false
    requires: [hero]
  created:
    type: timestamp
    required: true
    default: "%Y-%m-%d %H:%M"   # strftime format, stamps current time on --fix
    sync: false
  modified:
    type: timestamp
    required: true
    default: "%Y-%m-%d %H:%M"
  publish:
    type: bool
    required: true
    default: false
    sync: false

Property spec fields

Field Purpose
type timestamp, bool, string, list, int, float
required Key must exist (null values are valid)
default Value set by --fix when missing. strftime string for timestamps, literal for others, null for explicit null
enum Allowed values (string fields)
requires Companion fields that must also have values (co-dependency)
sync true (default) or false -- field is validated but stripped from dest during sync

Sync config fields

Field Purpose
dest Destination directory (overridable via --dest)
link_path_prefix URL prefix for resolved wikilinks (overridable via --link-path-prefix)
ignore Glob patterns for files to skip
media.source Source media directory name (relative to vault dir)
media.dest Destination media directory (relative to dest root)
media.link_prefix URL prefix for media links in dest output

Development

uv sync --dev          # install deps
uv run pytest -v       # run tests
uv run rematter --help # run locally

Metadata

Release files for rematter 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rematter 0.1.0
File Size Uploaded
rematter-0.1.0.tar.gz 73.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for rematter 0.1.0
File Interpreter ABI Platform
rematter-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 92.3 kB

Release files / rematter-0.1.0.tar.gz

Download URL rematter-0.1.0.tar.gz
Size 73.1 kB
Tags Source
SHA-256 checksum
How to use checksums
7afb29b45f219b00f0cdc7292dfcbd5fd8649fc7de47ee47c2c965d30a70548d
BLAKE2b-256 checksum
How to use checksums
9c93e47fe441c54b17ab5c8b4800590820734b9675434613c2440a495636bf17
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / rematter-0.1.0-py3-none-any.whl

Download URL rematter-0.1.0-py3-none-any.whl
Size 19.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ab16fe8e56b334e84050ccc3942dfc0ead4c85ee62009abf368ba91e8157bd2d
BLAKE2b-256 checksum
How to use checksums
90113f79a59076026791bf3bb99d129f9f2270e4adda818a3e18c4f11534bb09
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page