Skip to content

Repository files navigation

简体中文

CozyTag

Astro 7 TypeScript 5.9 IndexedDB Single-file HTML

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.

Why

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 anywherenpm run build produces 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.

Workflow

Features

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

Getting started

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

Tech stack

  • 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)
  • Bundlingscripts/bundle-single-file.mjs inlines the Astro output into one HTML file

Project structure

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

Design notes

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 from color-mix.
  • Motion — Only transform and opacity, never layout. The topbar hides with an absolute-positioned translateY on the compositor; the sidebar transitions via grid-template-columns; the virtual grid uses translate3d. Respects prefers-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.

License

Internal project. For development or issues, contact the maintainer.

About

Tab Navigation

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages