A privacy-first, open-source, local-only markdown editor built with Svelte 5.
Your notes never leave your device. No accounts. No tracking. No cloud.
$...$ and display $$...$$).Ctrl+P).# Clone the repository
git clone https://github.com/nthung2112/nth-mark.git
cd nth-mark
# Install dependencies
bun install
# Start development server
bun dev
Open http://localhost:5173 in your browser.
# Build the application
bun run build
# Preview the production build
bun preview
| Script | Description |
|---|---|
bun dev |
Start the development server |
bun build |
Build static output for production |
bun preview |
Preview the production build locally |
bun check |
Run svelte-check for type errors |
bun lint |
Run Prettier and ESLint checks |
bun format |
Format all files with Prettier |
| Shortcut | Action |
|---|---|
Ctrl+B |
Bold text |
Ctrl+I |
Italic text |
| Ctrl+` | `Inline code` |
Ctrl+~ |
|
Ctrl+Shift+. |
Numbered list |
Ctrl+. |
Bullet list |
Ctrl+Q |
Block quote |
| Shortcut | Action |
|---|---|
Ctrl+H |
Show keyboard shortcuts panel |
Ctrl+F |
Find and replace |
Ctrl+P |
Print document |
Ctrl+S |
Save now |
Ctrl+/ |
Toggle comment |
Tab |
Indent line |
Shift+Tab |
Outdent line |
| Shortcut | Action |
|---|---|
Ctrl+0 |
Reset zoom |
F11 |
Enter fullscreen |
| Shortcut | Action |
|---|---|
Ctrl+A |
Select all |
Ctrl+D |
Select next occurrence |
Ctrl+Shift+L |
Select all occurrences |
$state, $derived, $effect)nth-mark/
├── src/
│ ├── app.html # HTML shell (dark theme, anti-flash CSS)
│ ├── app.d.ts # Platform type declarations
│ ├── lib/
│ │ ├── index.ts # Library barrel exports
│ │ ├── appState.svelte.ts # Global reactive state (Svelte 5 runes)
│ │ ├── db.ts # Dexie database schema and operations
│ │ ├── markdown.ts # Unified markdown processing pipeline
│ │ └── components/
│ │ ├── Editor.svelte # CodeMirror 6 editor with custom theme
│ │ ├── Preview.svelte # Block-based markdown preview with TOC
│ │ ├── Sidebar.svelte # File explorer sidebar
│ │ ├── FileTree.svelte # Recursive file tree with drag-and-drop
│ │ └── Toolbar.svelte # Formatting toolbar with menus
│ └── routes/
│ ├── +layout.svelte # Root layout (SEO, PWA meta, fonts)
│ ├── +layout.server.ts # SSR disabled, prerender enabled
│ ├── +page.server.ts # Page prerender config
│ ├── +page.svelte # Main page (UI orchestration)
│ └── layout.css # Global CSS reset
├── static/
│ ├── manifest.json # PWA web app manifest
│ ├── favicon.ico
│ └── robots.txt
├── package.json
├── svelte.config.js # SvelteKit config (static adapter)
├── vite.config.ts # Vite config with build-time constants
├── tsconfig.json
├── eslint.config.js
└── .prettierrc
NTH Mark uses IndexedDB via Dexie.js for local-first data storage. All your notes are stored in your browser and never leave your device.
++id, name, parentId, isOpen++id, folderId, title, content, createdAt, updatedAt
folderIdcan benullfor root-level files (files not inside any folder).
The database auto-initialises with a "Notes" folder and a "Welcome" file on first use. Helper functions handle unique name generation, recursive folder deletion, and move operations with cycle detection.
You can export all your data as a JSON file for backup:
To restore:
NTH Mark works fully offline as a Progressive Web App (PWA).
Contributions are welcome! Please feel free to submit a Pull Request.
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)This project is licensed under the MIT License - see the LICENSE file for details.
Made with Svelte 5 | Open Source | Privacy First