__ __ __ __ _
| \/ |\ \ / /(_) ___ ___ __ __ _ ___ _ __
| |\/| | \ \ / / | | / _ \ / __| \ \ / // _` | / _ \| '__|
| | | | \ \/ / | || (_) |\__ \ \ V /| (_| || __/| |
|_| |_| \__/ |_| \___/ |___/ \_/ \__,_| \___||_|
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.
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:
- Keep using Obsidian on desktop — it's the source of truth
- Clone your vault into MView (or import via drag-drop)
- Browse, read, search on your phone offline
- Make quick edits — they auto-save to your browser
- Push changes back to GitHub when you're back online
- Pull from GitHub to get desktop edits into MView
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.
| 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]]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
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 tagpath: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.
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)
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
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
dirtyAttimestamp) 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
.zippreserving folder structure (processed in chunks of 50) - Export single — download any note as
.mdfrom the Note page
Danger Zone
- Clear vault — wipes IndexedDB and rebuilds search index. Doesn't affect GitHub.
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).
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 support —
apple-mobile-web-app-capable, status bar style, touch icon meta tags
- 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
yieldbetween chunks - Export — zip processing batched in chunks of 50 with
yieldbetween chunks - Search debounce — 150ms debounce on keystroke avoids hammering IndexedDB
| 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 |
Visit https://kirakage88.github.io/mview/ — or run locally with npm run dev.
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 originOr create a repo manually on github.com, then:
git remote add origin https://github.com/your-user/my-vault.git
git push -u origin mainMView needs a token with repo scope to read/write your vault:
- github.com → Settings → Developer settings → Personal access tokens → Tokens (classic)
- Click Generate new token (classic)
- Name:
MView - Expiration: pick what suits you (or "No expiration")
- Scopes: check
repo(full control of private repos) — or justpublic_repoif your vault repo is public - Click Generate token
- Copy the token now — it's shown once
- Open MView → Settings (gear icon)
- Repository URL:
https://github.com/your-user/my-vault - Token: paste your token
- Branch:
main - Click Add Repository, then Clone
- MView downloads all
.mdfiles into IndexedDB — you're ready to go
Browse, read, search, edit — everything works offline once cloned.
- 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.
npm install
npm run devOpen http://localhost:5173 — import via file picker, drag-drop, or Git clone.
npm run dev # vite already hosts on 0.0.0.0:5173VS Code Ports tab → Port Visibility: Public → tunnel URL → phone.
| 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 |
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
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.