Bookmrk is a lightweight, open-source bookmark manager built with React, TypeScript, Vite and Tailwind CSS. It is designed as a modern local-first bookmark manager with quick-save keyboard shortcuts, multi-board organization, a canvas-style 4-column board layout, Chrome import fallback, flexible backgrounds and a bunch of themes.
This README is intended to be a comprehensive reference for users and contributors: installation, usage, architecture, data model, storage & migration, development and contribution guidelines, troubleshooting, and FAQs.
Bookmrk helps you capture and organize web pages into Boards and Pages. It focuses on fast keyboard-driven capture (Quick Save), portable storage, and a clean UI with modal-based input and toasts instead of intrusive browser prompts.
Key design goals:
Quick Saves board (auto-created if missing).Prerequisites:
Repo → Releases → Download latest boomrk-extension-v1.0.0.zip
After extraction, the folder should contain:
manifest.json
index.html
assets/
icons/
background.js
content_toast.js
favicon.svg
icons.svg
chrome://extensions
Enable Developer Mode (top-right corner).
Click Load unpacked.
Select the extracted boomrk-extension folder.
Bookmrk is now installed 🎉
+ controls.Ctrl/Cmd + Shift + Y
(⋯) to rename, delete, organize, or summon bookmarks.

Notes:
Note: Browser-level keyboard handling may vary across platforms and OS; when running as an extension, Chrome-specific platform behavior applies.
Access settings via the settings icon in the toolbar. Settings are auto-saved as you adjust them.
Behavior Settings:
Appearance Settings:
Support:
Persistence is provided by src/storage/local.ts. Bookmrk uses the browser extension APIs (when available) and falls back to localStorage otherwise.
Imported Bookmarks board and sets a chromeBookmarksImported flag to prevent repeated imports._settingsMetadata section documenting current settings (behavior and appearance) with human-readable labels and descriptions. You can manually include background data if desired for full fidelity.If you have an older Bookmrk export (or another import source), map the fields to the current BookmrkData shape. Pay attention to chromeBookmarksImported (boolean) and background (object |
null). |
Core TypeScript types are defined in src/shared/types.ts. The important shapes:
Bookmark - { id, url, title, notes?, createdAt }Board - { id, name, order, columnIndex?, bookmarks: Bookmark[] }Page - { id, name, boards: Board[] }Settings - { openLinksInNewTab?: boolean, showBookmarkDescriptions?: boolean, compactMode?: boolean, themeMode?: ‘discord’ |
‘simple’ | ‘neobrutalist’ | ‘neumorphism’, fontFamily?: ‘plus-jakarta-sans’ | ‘satoshi’ | ‘google-sans’ | ‘electrolize’ | ‘dm-mono’ | ‘jetbrains-mono’ | ‘comic-sans’ | ‘space-grotesk’ } |
BookmrkData - { pages: Page[], settings: Settings, meta: { createdAt }, chromeBookmarksImported?: boolean, background?: Background |
null } |
Background types:
prefers-color-scheme by default. Modal surfaces use #000000 in dark mode and #FFFFFF in light mode to ensure contrast and consistent visuals.Bookmrk provides three built-in visual themes (selectable from the Palette menu in the toolbar or via the Appearance settings):
These theme choices are persisted in the stored settings as themeMode with allowed values discord, simple, or neobrutalist (see src/shared/types.ts).
Top-level structure (important files/directories):
src/App.tsx — Application root, global modal mounting and theme fallback.src/store/useStore.ts — Zustand store: pages, boards, bookmarks, background, settings, modals, and toasts. Provides actions for settings management (updateSettings, openSettingsModal, closeSettingsModal).src/storage/local.ts — Persistence adapter (chrome.storage.local when available, otherwise localStorage). Handles export/import operations with settings metadata in exports.src/shared/types.ts — Central TypeScript types including Settings and getModalBackgroundStyle utility.src/components/ — UI components and modal implementations:
Settings/SettingsModal.tsx — settings manager with tabs for General (behavior/appearance/font picker), Account, and Support sections. Auto-saves changes with toggle switches.Background/BackgroundModal.tsx — background manager (URL/upload).Shared/InputModal.tsx — reusable input modal.Bookmark/QuickSaveModal.tsx — Quick Save keyboard handler and UX.Board/BoardColumn.tsx — board UI and BoardSettingsModal.Page/PageView.tsx — canvas-style 4-column board lanes, DnD context, and add-board placement.src/store/ — global state & helpers.DnD is implemented with @dnd-kit/core and @dnd-kit/sortable. Portals use createPortal from react-dom to ensure modals render at the document root and center properly.
Prerequisites: Node.js 18+ and npm.
npm install
npm run dev
npm run build
npm run preview
npm run dev — start Vite dev servernpm run build — production buildnpm run preview — preview production build locallyvitest for unit tests, eslint for linting, and prettier for formatting.We welcome contributions. High-level workflow:
When the persisted data shape changes between releases, a small migration script can help convert older exports to the current BookmrkData shape. Add and run this script locally to transform an exported JSON file.
Example script: scripts/migrate_v1_to_v2.ts — usage:
# install ts-node if you don't have it
npm install -D ts-node typescript
# run migration
npx ts-node scripts/migrate_v1_to_v2.ts old-export.json migrated.json
This example script performs conservative transforms:
chromeBookmarksImported exists (defaults to false)background to explicit { type, value } | nullcreatedAt timestamps exist on top-level metaSee scripts/migrate_v1_to_v2.ts for the implementation.
I’ve added a Pull Request template at .github/PULL_REQUEST_TEMPLATE.md with a contributor checklist to make reviews faster. The checklist includes items for tests, docs, migrations, and changelog notes.
When opening a PR, please include:
docs/screenshots/).README.md or docs when features or developer flows change.Q: Quick Save isn’t working in my browser.
A: Ensure the page has focus and the app/extension is active. Browser-level keybindings can conflict; try the toolbar Quick Save button as a fallback.
Q: I imported Chrome bookmarks and the button is disabled.
A: That’s by design, Bookmrk sets chromeBookmarksImported to avoid duplicate imports. If you need to re-import, you have two safe options:
Imported Bookmarks board from the UI; Bookmrk will automatically clear the import lock and re-enable the Import Chrome button.chromeBookmarksImported flag manually in storage (not recommended unless you know what you’re doing).
Q: My exported JSON is missing my background image.
A: Bookmrk intentionally omits background data from exported JSON to keep exports small. If you need the background included, open the storage code in src/storage/local.ts and adjust the export function.
Q: Summon opened too many tabs.
A: Summon opens all bookmarks in a board. Use with caution with large boards.
Q: Where did the open-link icon go on bookmark cards?
A: The bookmark card itself now opens the URL when clicked, so the separate open-link button was removed.
This project is open source under MIT License.
For questions, issues, or contributions, open an issue or pull request in the repository.