Skip to content

Repository files navigation

 __  __ __      __ _      
|  \/  |\ \    / /(_)  ___   ___  __   __ _   ___  _ __  
| |\/| | \ \  / / | | / _ \ / __| \ \ / // _` | / _ \| '__|
| |  | |  \ \/ /  | || (_) |\__ \  \ V /| (_| ||  __/| |   
|_|  |_|   \__/   |_| \___/ |___/   \_/  \__,_| \___||_|   

MView

Your Obsidian vault, everywhere. No server, no sync service, no monthly fee. Just your markdown, in your browser, on any device.

MView is a local-first PWA that turns your markdown vault into a fully interactive web app — offline, installable, and fast. It reads your Obsidian vault (via folder import or GitHub clone) into IndexedDB, then lets you browse, read, search, and edit from any browser. Your phone. Your tablet. Your friend's laptop. Anywhere.


Why MView?

Obsidian is the best markdown editor on desktop. But on mobile, it's limited — the app is heavy, sync requires their paid service, and the mobile experience doesn't match the desktop power.

MView is the companion: a lightweight, read-first web app that works on any browser. Use Obsidian on your desktop (it's your primary tool), and use MView on your phone to read, search, and make quick edits.

The workflow:

  1. Keep using Obsidian on desktop — it's the source of truth
  2. Clone your vault into MView (or import via drag-drop)
  3. Browse, read, search on your phone offline
  4. Make quick edits — they auto-save to your browser
  5. Push changes back to GitHub when you're back online
  6. Pull from GitHub to get desktop edits into MView

Features

📂 File Tree

Navigate your vault by folder structure in the left sidebar. Folders auto-expand on click, and a collapse-all button resets the view. The tree reads from your IndexedDB database and mirrors your vault's file hierarchy.

📝 Markdown Viewer & Editor

Mode What you get
Read Rendered markdown with GFM tables, code syntax highlighting, inline [[wikilinks]], and embedded images
Edit CodeMirror 6 with One Dark theme, markdown syntax highlighting, and autosave (2-second debounce)

Toggle between modes with the pencil/eye icon. Edits auto-save — no save button needed.

🔗 Wikilinks & Backlinks

  • [[Wikilinks]] are parsed at render time and become clickable links to other notes
  • The Backlinks panel (right sidebar) shows a 3-level tree: notes you link to → current note (glowing) → notes that link back
  • Each level is expandable/collapsible with chevron toggles

🔍 Search

Two search surfaces:

Omnisearch bar (header) — quick search with 150ms debounce, returns top 10 results in a dropdown.

Full Search page (/search) — complete search with advanced filters:

  • tag:#topic — filter by tag
  • path:folder/subfolder/* — filter by path
  • Also shows recent notes (tracked by lastOpenedAt)

Powered by FlexSearch — instant full-text search across titles and content. Index is rebuilt on vault import and cleared on vault clear. Inserts are batched in chunks of 100 for performance.

🏷️ Tags

The Tags page (/tags) shows all discovered #tags from your vault with note counts. Features:

  • Star favorites — toggle tags as favorites (persisted in IndexedDB)
  • All / Favorites filter — switch between full tag list and starred tags only
  • Sorted by count (most-used first)

🌲 Link Tree

The Graph tab (/graph) replaces the typical force-directed graph with a tidy expandable link tree:

  • Select a root folder from the dropdown (auto-detected from your vault)
  • Adjust depth (1–5 levels) with a slider — persisted in localStorage
  • Click any node to expand its links recursively
  • Folder color badges — each folder gets a unique hue based on its path
  • Cycle detection — notes already shown in the tree get "(already shown)" labels and can't be expanded again
  • Reset button to start fresh

⚙️ Settings

The Settings page (/settings) is your control center:

Git Sync

  • Add a GitHub repository URL and Personal Access Token
  • Clone — downloads the full vault into IndexedDB (5 concurrent workers)
  • Pull — incremental sync via commit comparison (only downloads changed files since last sync)
  • Push — uploads only dirty notes (tracked by dirtyAt timestamp) back to GitHub
  • Real-time progress bar with phase text and counts
  • Status indicator per repo (idle / synced / error / spinning for in-progress)

Export

  • Export all — downloads all notes as a .zip preserving folder structure (processed in chunks of 50)
  • Export single — download any note as .md from the Note page

Danger Zone

  • Clear vault — wipes IndexedDB and rebuilds search index. Doesn't affect GitHub.

🌓 Theme Toggle

Switch between dark and light modes with an animated center-circle clip-path reveal. The theme persists in localStorage (mview-theme). Dark mode is default (matches Obsidian, saves OLED battery).

📱 PWA (Progressive Web App)

MView is a fully installable PWA:

  • Service worker — auto-updates via vite-plugin-pwa, pre-caches all app assets (HTML/CSS/JS) via workbox
  • Offline — once the vault is imported and the app has been visited once, everything works without internet: browsing, reading, editing, searching
  • Install prompt — add to home screen on Android/iOS
  • iOS supportapple-mobile-web-app-capable, status bar style, touch icon meta tags

🚀 Performance Optimizations

  • Route-level code splitting — each page loads on demand via React.lazy(); main chunk is 404 KB
  • Search index — FlexSearch inserts batched in chunks of 100 with yield between chunks
  • Export — zip processing batched in chunks of 50 with yield between chunks
  • Search debounce — 150ms debounce on keystroke avoids hammering IndexedDB

Tech Stack

Layer Choice Why
Framework React 18 + Vite 5 Fast dev server, instant HMR, tree-shaking
Routing React Router v6 (HashRouter) Works on static hosting (GitHub Pages)
Markdown render react-markdown + remark-gfm + rehype-highlight Extensible, GFM, syntax highlighting
Editor CodeMirror 6 Best browser code editor, markdown mode
Search FlexSearch 0.8 Blazing fast full-text in the browser
Storage Dexie.js (IndexedDB) Local-first, no server, survives restarts
Styling Tailwind CSS 3 + shadcn/ui + typography Utility-first, accessible components
Icons lucide-react Clean, consistent icon set
PWA vite-plugin-pwa (workbox) Service worker, manifest, offline caching
Sync GitHub REST API (direct) No backend, no CORS issues
Export JSZip Client-side zip generation

Getting Started

1. Open MView

Visit https://kirakage88.github.io/mview/ — or run locally with npm run dev.

2. Put your vault on GitHub

If your vault isn't on GitHub yet, create a repo:

# In your vault folder
git init
git add .
git commit -m "Initial vault"
gh repo create my-vault --private --push --remote origin

Or create a repo manually on github.com, then:

git remote add origin https://github.com/your-user/my-vault.git
git push -u origin main

3. Create a GitHub Personal Access Token

MView needs a token with repo scope to read/write your vault:

  1. github.com → Settings → Developer settings → Personal access tokens → Tokens (classic)
  2. Click Generate new token (classic)
  3. Name: MView
  4. Expiration: pick what suits you (or "No expiration")
  5. Scopes: check repo (full control of private repos) — or just public_repo if your vault repo is public
  6. Click Generate token
  7. Copy the token now — it's shown once

4. Clone into MView

  1. Open MView → Settings (gear icon)
  2. Repository URL: https://github.com/your-user/my-vault
  3. Token: paste your token
  4. Branch: main
  5. Click Add Repository, then Clone
  6. MView downloads all .md files into IndexedDB — you're ready to go

5. Use it

Browse, read, search, edit — everything works offline once cloned.

6. Sync back

  • Push → uploads only edited notes to GitHub
  • Pull → downloads new changes from GitHub since last sync

Both buttons are in Settings → Git Sync. Only changed files are transferred.

Local Development

npm install
npm run dev

Open http://localhost:5173 — import via file picker, drag-drop, or Git clone.

Mobile Access

npm run dev  # vite already hosts on 0.0.0.0:5173

VS Code Ports tab → Port Visibility: Public → tunnel URL → phone.


Routes

Path Page What it does
/ Home Welcome screen + vault import
/note/:path Note Read or edit a specific note
/search Search Full-text search with filters
/graph Graph Expandable link tree view
/tags Tags Tag browser with favorites
/settings Settings Git sync, export, clear vault

Project Structure

mview/
├── .github/workflows/deploy.yml       # GitHub Actions auto-deploy
├── src/
│   ├── lib/
│   │   ├── db.js                       # Dexie schema (notes, favoriteTags, gitRepos)
│   │   ├── parser.js                   # Tag/link extraction, title derivation
│   │   ├── search.js                   # FlexSearch init, query, structured parsing
│   │   ├── vault-import.js             # File/folder/drag-drop import
│   │   ├── git-sync.js                 # GitHub REST API clone/pull/push
│   │   ├── export.js                   # ZIP export, single note download
│   │   ├── remark-mview-links.js       # Remark plugin: [[wikilinks]] → links
│   │   └── utils.js                    # cn() utility (clsx + tailwind-merge)
│   ├── hooks/
│   │   ├── useNotes.js                 # CRUD, recent, tags, favorites, dirty tracking
│   │   └── useLinkTree.js              # Recursive link tree builder
│   ├── components/
│   │   ├── ui/                         # shadcn primitives (Button, Sheet, Tabs, etc.)
│   │   ├── Layout/AppShell.jsx         # Root layout with sidebars + desktop tabs
│   │   ├── Layout/BottomNav.jsx        # Mobile bottom tab bar
│   │   ├── FileTree/FileTree.jsx       # Folder-based navigation tree
│   │   ├── Editor/CodeMirrorEditor.jsx # CodeMirror 6 markdown editor
│   │   ├── Preview/MarkdownRenderer.jsx# react-markdown viewer
│   │   ├── Search/SearchBar.jsx        # Header search with dropdown
│   │   ├── Backlinks/BacklinksPanel.jsx# 3-level backlink tree
│   │   ├── Graph/LinkTree.jsx          # Root link tree component
│   │   ├── Graph/LinkTreeNode.jsx      # Recursive tree node
│   │   ├── Graph/graph-utils.js        # Folder color helpers
│   │   └── ImportVault.jsx             # Vault import UI
│   ├── pages/
│   │   ├── Home.jsx                    # Welcome + import
│   │   ├── Note.jsx                    # Read/edit with toggle
│   │   ├── Search.jsx                  # Full search page
│   │   ├── Graph.jsx                   # Link tree page
│   │   ├── Tags.jsx                    # Tag browser
│   │   └── Settings.jsx                # Git sync, export, clear
│   ├── App.jsx                         # Routes + search init + title migration
│   ├── main.jsx                        # React root (HashRouter)
│   └── index.css                       # Tailwind + theme variables + gradients
├── public/icon.svg                     # PWA icon
├── index.html                          # Entry HTML (iOS meta, theme overlay)
├── vite.config.js                      # Vite + PWA config
├── tailwind.config.js                  # Tailwind with shadcn preset
└── PLAN.md                             # Full build plan

Build Plan

See PLAN.md for the full build plan across 5 phases:

  • Phase 1 (v0.1) — Core: file tree, markdown viewer/editor, wikilinks, backlinks, search, mobile nav
  • Phase 2 (v0.2) — Omnisearch, recent notes, tag browser, favorite tags
  • Phase 3 (v0.3) — Link tree, 3-level backlinks, gradient backgrounds, theme toggle
  • Phase 4 (v0.4) — Git sync, export (zip/md), PWA manifest, settings page, clear vault
  • Phase 4.5 (v0.45) — Smart sync (incremental pull/push), code splitting, search batching, export batching

MView is a companion, not a replacement. Your vault lives in Obsidian on desktop. MView gives you a window into it from anywhere.

About

A Web Markdown Editor and Viewer, similar to Obsidian but in web.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages