lupx-bookmark

LUPX Bookmark

A visual bookmark Speed Dial that replaces the Chrome New Tab page.

Available in the Chrome Web Store

Instead of the default blank tab, LUPX Bookmark greets you with a clean grid of bookmark cards — each showing a favicon and a title — organized into collapsible, drag-and-drop groups. Everything is stored locally in your browser; no account, no server, no tracking.


Why

The built-in Chrome bookmark bar is linear and hard to scan at a glance. Third-party Speed Dial extensions are either bloated, require sign-in, or inject ads. LUPX Bookmark is intentionally minimal: a single-purpose extension that does exactly one thing and stays out of your way.


Features


Tech Stack

Layer Technology
Language TypeScript 5 (strict mode)
UI framework React 18
Bundler Vite 8 + vite-plugin-web-extension
Styling CSS Modules
Chrome APIs chrome.storage.sync · chrome.storage.local · chrome.storage.onChanged · chrome.history
Manifest Version 3 (MV3)
Package manager npm

No runtime dependencies beyond React. No Redux, no router, no UI library.


Getting Started

Prerequisites

Install dependencies

npm install

Development build (watch mode)

npm run dev

Vite rebuilds into dist/ on every file save.

Production build

npm run build

Type check

npm run typecheck

Loading the Extension in Chrome

  1. Open chrome://extensions
  2. Enable Developer mode (toggle in the top-right corner)
  3. Click Load unpacked
  4. Select the dist/ folder generated by the build
  5. Open a new tab — LUPX Bookmark replaces the default page

To apply code changes during development: after each save the dist/ folder is updated automatically; click the ↺ refresh icon on the extension card in chrome://extensions to reload.


Project Structure

lupx-bookmark/
├── public/
│   └── icons/
│       ├── lupx_logo.png     # Extension icon (16 / 48 / 128 px)
│       └── pin.svg           # Fallback favicon placeholder
├── src/
│   ├── newtab/
│   │   ├── newtab.html       # New Tab page entry point
│   │   ├── newtab.tsx        # React root — layout, drag state, event wiring
│   │   ├── newtab.module.css
│   │   ├── useAccordions.ts  # Accordion groups CRUD + chrome.storage.local
│   │   ├── useSettings.ts    # User settings + chrome.storage.sync
│   │   ├── useBackground.ts  # Background rendering + file upload to storage.local
│   │   └── useWallpapers.ts  # Built-in wallpaper gallery loader
│   ├── options/
│   │   ├── options.html      # Extension options page
│   │   ├── options.tsx
│   │   └── options.module.css
│   ├── components/
│   │   ├── AccordionGroup/   # Collapsible group with drag handles
│   │   ├── BookmarkCard/     # Individual bookmark card (all 8 style variants)
│   │   ├── AddSlotModal/     # Add-bookmark dialog with history suggestions
│   │   ├── SearchBar/        # Search bar with engine picker
│   │   └── SettingsPanel/    # Slide-in settings drawer
│   ├── types/
│   │   └── index.ts          # Shared TypeScript types and constants
│   └── utils/
│       └── favicon.ts        # favicon resolution: chrome://favicon2/ → Google S2 → pin.svg
├── manifest.json
├── vite.config.ts
└── tsconfig.json

Architecture Notes

All logic runs inside the New Tab page. There is no background service worker.


License

MIT — see LICENSE.