CozyTag is a bookmark manager that runs entirely in your own browser. No backend, no login, no data collection — bookmarks, folders, icons, and preferences all stay in your browser's IndexedDB. The build output is a single HTML file you can double-click to open and use offline.
Most bookmark tools fall into two camps: browser built-ins tied to cloud accounts (Chrome/Edge), or third-party services that require you to trust a server (Raindrop/Pinboard). CozyTag sits in between — you keep the organizing power, and your data stays local:
- Your data, your machine — Import once and everything lands in IndexedDB. Close the tab, data stays. Clear browser storage, it's gone. No server ever sees it.
- Take it anywhere —
npm run buildproduces one HTML file with all JS/CSS inlined. Put it on a USB drive, email it, host it on an intranet server. Works offline. - Smooth with thousands — Virtual grid rendering with absolute positioning and DOM node pooling keeps ~40 cards in the DOM even with 1700+ bookmarks. Zero layout jank.
- Import and export, lossless — Reads Chrome/Edge/Firefox bookmark files, de-duplicates and merges folders on import. Export back to standard Netscape HTML, re-import with no loss.
| Feature | What it does |
|---|---|
| Offline-first | IndexedDB storage, zero network requests, works in private mode |
| Single file | Build output is one HTML file, no external dependencies |
| Virtual scroll | Node pooling keeps thousands of bookmarks scrolling smoothly |
| Views | Grid / list / compact, with scroll position preserved |
| Smart folders | Recent / starred / uncategorized / duplicates, one click away |
| Import wizard | Parse, preview, de-duplicate, merge, then import in bulk |
| Lossless export | Standard Netscape HTML, re-importable |
| Command palette | Ctrl / ⌘ + K for keyboard-first navigation |
| Edit mode | Card actions stay visible; click selects instead of opening |
| Custom background | Image / GIF / video ≤10MB, adjustable opacity and position |
| Themes | 8-color palette, derived colors generated live with color-mix |
| Dark mode | Layered surfaces and four-step grays for clear hierarchy |
| Keyboard | Palette / search / undo / import / export / arrow navigation |
| Undo | Delete, move, and bulk actions can all be rolled back |
npm install # install dependencies
npm run dev # local dev server
npm run check # type check
npm run build # build → dist/CozyTag.html (single file)After building, double-click dist/CozyTag.html to use it offline in any modern browser. On first open, click Import in the top-right and drop in the .html bookmark file your browser exports.
End-to-end tests (build first):
node scripts/e2e.mjs # headless
node scripts/e2e.mjs --headed # with browser UI- Framework — Astro 7 (build only, zero runtime hydration)
- Language — TypeScript 5.9
- Styles — SCSS + CSS custom properties (design tokens)
- Storage — IndexedDB (folders / bookmarks / icons / meta)
- Tests — Playwright (44-assertion e2e suite)
- Bundling —
scripts/bundle-single-file.mjsinlines the Astro output into one HTML file
CozyTag/
├── src/
│ ├── lib/
│ │ ├── app.ts # entry: wire up views, shortcuts, background layer
│ │ ├── db.ts # IndexedDB layer (four stores + batch transactions)
│ │ ├── state.ts # in-memory index + event bus + undo stack
│ │ ├── netscape.ts # Netscape bookmark parser
│ │ ├── virtual.ts # virtual grid: absolute positioning + node pool
│ │ └── ui/ # topbar / sidebar / list / import / export / palette
│ ├── pages/index.astro # single page + skeleton
│ └── styles/ # design tokens + layered styles
├── scripts/
│ ├── bundle-single-file.mjs
│ └── e2e.mjs
└── package.json
Three principles: a neutral base with switchable accent color, a dark mode with real hierarchy, and animations that never touch layout.
- Color — Clean neutral gray in light mode, slightly muted (not pure black) in dark mode so surfaces can float. Default accent is teal (
#0d9488), with 7 more to switch between; all derived colors come fromcolor-mix. - Motion — Only
transformandopacity, never layout. The topbar hides with an absolute-positionedtranslateYon the compositor; the sidebar transitions viagrid-template-columns; the virtual grid usestranslate3d. Respectsprefers-reduced-motion. - Interaction — Card action buttons stay hidden by default to avoid mis-clicks; in edit mode they stay visible and a click selects. Hover feedback uses a border and glow.
Internal project. For development or issues, contact the maintainer.