Read Only View is an Obsidian community plugin that forces selected Markdown files to stay in Reading mode (preview). It works on both desktop and mobile (isDesktopOnly: false) using simple local rule matching with no extra runtime dependencies.
Privacy: No network requests, rules evaluated locally.
- Install the plugin (manual installation steps below).
- In Obsidian, open Settings → Community plugins and enable Read Only View.
- Open Settings → Read Only View.
- Make sure
Enabledis on, then add an include rule such as:project_a/**
- Open a matching
.mdnote. It should stay in Reading mode (preview).
If it does not apply immediately, run command Re-apply rules now from the Command Palette.
- Not in Community Store yet.
- Download or build plugin files.
- Copy files into your vault:
<Vault>/.obsidian/plugins/read-only-view/- required files:
main.js,manifest.json - optional:
styles.css
- Restart Obsidian (or reload plugins), then enable Read Only View in Settings → Community plugins.
In Settings → Read Only View, configure:
EnabledUse glob patternsCase sensitiveDebug loggingInclude rulesExclude rules
While editing rules, the plugin autosaves with debounce (~400 ms) and shows status text: Saving..., Saved., Save failed.
If you need explicit confirmation, wait for Saved. before closing settings.
Rule volume safeguards:
- soft warning when include or exclude has more than
50effective rules - strong warning when include or exclude has more than
150effective rules - hard caps:
- include max:
200 - exclude max:
300 - total max:
400
- include max:
- when hard caps are exceeded, save still succeeds, but extra lines are ignored and marked in diagnostics (
Ignored due to rule limit.) - rules counter in settings shows effective used rules:
Include: X · Exclude: Y · Total: Zwith(+N ignored)when applicable
Common scenarios:
- Protect one project folder, but exclude archive subfolder:
Include:
project_a/**
**/README.md
Exclude:
project_a/archive/**
- Protect all README notes across the vault:
Include:
**/README.md
Exclude:
- Protect one specific note:
Include:
notes/policies/security.md
Exclude:
- Prefix mode folder rule (
Use glob patternsoff):
Include:
projects/
Exclude:
projects/drafts/
Use Path tester to validate behavior before relying on a rule set. It shows:
- matched include rules
- matched exclude rules
- final
READ-ONLY ON/OFF
Use the Command Palette:
Enable read-only modeDisable read-only modeToggle plugin enabledRe-apply rules now
Enable read-only mode is available only when the plugin is disabled.
Disable read-only mode is available only when the plugin is enabled.
- Core enforcement:
- Force matched
.mdfiles into Reading mode (preview). - Prevent switching matched files to Source mode or Live Preview.
- Force matched
- Matching:
- Include and exclude rule lists (
excludehas priority when both match). - Rule limit policy:
- include list is capped first (
200) - exclude list is capped second (
300) - if combined total still exceeds
400, tail of exclude is trimmed first (include keeps priority)
- include list is capped first (
- Two modes:
- Glob mode (
*,**,?) - Literal prefix mode (compatibility mode)
- Glob mode (
- Path normalization for reliable matching:
- trims spaces
- converts
\\to/ - removes leading
./ - collapses duplicate
/
- Include and exclude rule lists (
- Settings UX:
- Rule diagnostics:
✅valid rule⚠️suspicious/non-effective rule- warnings shown inline under each rule (no hover required)
- diagnostics area uses local scroll with capped height on small screens
- Rules editor save behavior:
- saves on typing with debounce (~400 ms)
- flushes pending save on
blur/change - shows text status (
Saving...,Saved.,Save failed.)
- Built-in path tester:
- matched include rules
- matched exclude rules
- final
READ-ONLY ON/OFF - long values wrap safely on narrow/mobile layouts
- Rule diagnostics:
- Commands:
Enable read-only modeDisable read-only modeToggle plugin enabledRe-apply rules nowEnable read-only modeis available only when the plugin is disabled;Disable read-only modeis available only when enabled
- Debug:
- Debug logging via
console.debug(optional) - file paths are redacted by default
- enable
Debug: verbose pathsto include full file paths
- Debug logging via
- This plugin does not change OS-level file permissions and is not an OS-level read-only lock.
- It only affects Obsidian view mode behavior for Markdown (
.md) files. - It does not protect non-Markdown files.
- It is not a security boundary against external tools or other editors.
- Rule enforcement is app-level behavior inside Obsidian (re-applied on relevant workspace/UI events).
- File is not forced to Reading mode (preview):
- Check that plugin
Enabledis on. - Confirm the file extension is
.md(non-Markdown files are ignored). - Verify at least one include rule matches the file path.
- Verify no exclude rule matches the same file path (exclude wins).
- Check that plugin
- Rule looks correct but still does not match:
- Use the built-in Path tester with the exact
file.path. - Check
Case sensitivesetting. - In prefix mode (
Use glob patternsoff),*and?are treated literally.
- Use the built-in Path tester with the exact
- Rule matches too broadly in prefix mode:
- If you intended a folder, keep a trailing
/in the rule. - Remember: prefix mode uses
startsWith.
- If you intended a folder, keep a trailing
- Changes in rules do not appear immediately:
- Run command Re-apply rules now.
- Switch tabs or reopen the note to trigger workspace events.
- You see
Too many rules. Extra lines are ignored.:- Reduce rule count, merge similar paths, and prefer
**in glob mode for broader coverage. - Check diagnostics entries marked
Ignored due to rule limit.to see which lines are not used.
- Reduce rule count, merge similar paths, and prefer
Advanced troubleshooting
- Check normalized path form (
\vs/, leading./, duplicate/) in diagnostics. - Empty diagnostics lines are shown as
(empty line)and are not converted to/. - Warning details are rendered inline (touch-friendly), not only in hover tooltips.
- Enable
Debug loggingand inspect DevTools console output ([read-only-view]prefix). - Keep
Debug: verbose pathsdisabled unless full-path diagnostics are required. - Fallback failures include error type/message in debug logs (
ensure-preview-fallback).
Manual cross-platform/version compatibility checks are tracked in:
docs/compatibility-matrix.md
Requirements:
- Node.js 18+
- npm
Dependency policy:
obsidianis pinned to an exact version inpackage.json(1.10.3) to keep local and CI builds reproducible.- Update policy:
- bump intentionally via
npm install obsidian@<version> - run full validation (
just lint && just test && just build) - smoke-check plugin loading in Obsidian desktop and mobile
- bump intentionally via
Install dependencies:
npm installBuild:
npm run buildTest:
npm testTest suite note:
- includes matcher stress/perf checks for long path and wildcard workloads with conservative runtime budgets to catch obvious regressions without CI flakiness
- includes
main.tsorchestration tests for enforcement flow, observer wiring, command visibility rules, and debug-path redaction behavior
Lint:
npm run lintWatch mode:
npm run devOptional just shortcuts:
just install
just build
just test
just lint
just check
just cleanAt minimum before finishing changes, run:
just lintjust testjust build
- Create a branch for your change.
- Run checks locally (
just checkrecommended; minimum is lint + test + build). - Open a pull request with a clear behavior summary and test notes.
- If behavior changes, update both
README.mdanddocs/PROJECT_STATE.md.
See LICENSE.
See repository Releases.
How enforcement works
- On workspace events (
file-open,active-leaf-change,layout-change), the plugin coalesces bursts into one re-apply pass (150 ms window) before scanning open Markdown leaves.- If the burst contains only
active-leaf-changeand/orfile-open, the plugin applies enforcement only to the changed leaf to reduce unnecessary full-vault UI work.
- If the burst contains only
- For each Markdown file, it evaluates
shouldForceReadOnly(file.path, settings). - If the file should be protected, the plugin forces the leaf view mode to
preview. - If a user or UI action tries to switch back to edit mode, the plugin re-applies preview mode.
- A mutation observer watches popover containers (
.hover-popover,.popover) and re-applies protection only when an editor node appears there.
Matching details and semantics
Matching rules:
- Only
.mdfiles are affected. - If
enabled = false, no enforcement is applied. - Include must match first.
- Exclude then overrides include.
Glob semantics (useGlobPatterns = true):
*matches within one path segment ([^/]*)**matches across segments (.*)?matches one non-/character ([^/])- compiled glob regexes are cached with a fixed FIFO cap (
512entries) to prevent unbounded memory growth with many unique rules
Literal prefix mode (useGlobPatterns = false):
- Uses
normalizedFilePath.startsWith(normalizedPattern) - If rule has no
*/?, does not end with/, and does not end with.md, the plugin appends/automatically (folder intent).



