This is a Chrome extension built as a pnpm monorepo using Turbo for orchestration. The extension replaces the new tab page with a customizable start interface featuring search, quick links, history suggestions, and MQTT-based event notifications.
chrome-extension/ # Core extension (manifest, background script)
pages/ # Extension UI pages (new-tab, popup, options, etc.)
new-tab/ # Main new tab replacement page
popup/ # Extension popup
options/ # Settings page
side-panel/ # Chrome side panel
packages/ # Shared workspace packages
shared/ # Common utilities, hooks, MQTT provider
storage/ # Chrome storage abstraction layer
ui/ # Reusable UI components (shadcn/ui based)
i18n/ # Internationalization system
hmr/ # Hot module replacement for dev
vite-config/ # Shared Vite configuration
Package Manager: pnpm 9.9.0 (required)
Build Tool: Turbo + Vite
Node Version: >=18.19.1 (see .nvmrc)
pnpm install # Install all dependencies
pnpm dev # Start dev mode with watch (Chrome)
pnpm dev:firefox # Start dev mode for Firefox
pnpm build # Production build (Chrome)
pnpm build:firefox # Production build (Firefox)
pnpm lint # Run ESLint with auto-fix
pnpm type-check # TypeScript type checking across monorepo
pnpm update-version 1.2.3 # Update version in all packages- Turbo orchestrates package builds via
turbo.jsontask definitions readytask runs first for shared packages (@extension/shared,@extension/storage) using esbuild viabuild.mjs- Pages and chrome-extension use Vite with custom plugins
- Browser targets: Chrome (default) and Firefox via
__FIREFOX__env variable - HMR enabled in dev mode - extension auto-reloads on changes
- Use
@typescript-eslint/consistent-type-imports: Import types withimport type { ... } - No React imports needed:
react/react-in-jsx-scopeis disabled - Path aliases defined per package in
tsconfig.json(e.g.,@src,@root)
- Tailwind CSS with custom config via
@extension/tailwindcss-config - Class merging: Use
cn()utility from@extension/ui(combinesclsxandtwMerge) - VS Code setup:
.vscode/settings.jsonconfigures Tailwind IntelliSense forcn,cva,clsx - Prettier config: Single quotes, no semicolons, 120 char width, trailing commas
- shadcn/ui integration: See
packages/ui/README.mdfor adding components
All storage uses custom wrappers from @extension/storage:
import { settingStorage, quickUrlStorage, historySuggestStorage } from '@extension/storage'
import { useStorage } from '@extension/shared'
// In React components
const settings = useStorage(settingStorage)
// Update with deep merge
await settingStorage.update({ wallpaperUrl: 'https://...' })
// In background scripts
const settings = await settingStorage.get()Storage types: BaseStorage abstraction supports StorageEnum.Local, StorageEnum.Sync, StorageEnum.Session
Live updates: Storage changes propagate via liveUpdate: true option
Background script manages MQTT connection for cross-device notifications:
- Provider:
generateClient()from@extension/sharedcreates MQTT connection - Event center:
generateEventCenter()manages topic subscriptions - Example: "Drink water" reminder events sync via MQTT (
drink-water/launch,drink-water/confirm) - Configuration: Settings stored in
settingStorage.mqttSettings(broker URL, secret key) - Background lifecycle: Connection setup in
chrome-extension/src/background/index.ts
- Chrome i18n API wrapper with type safety
- Translation files:
packages/i18n/locales/{locale}/messages.json - Usage:
import { t } from '@extension/i18n'thent('translationKey') - Auto-generation: i18n types are generated automatically during
pnpm devandpnpm build - Types: Ensures all locales have matching keys (compile-time check)
- Pages export a main component (e.g.,
NewTab.tsx) rendered inindex.tsx - Shared components in
@extension/uifor cross-page reuse - Page-specific components in
pages/{page}/src/components/ - HOCs available:
withErrorBoundary,withSuspensefrom@extension/shared
- Copy an existing page structure (e.g.,
pages/popup) - Update
package.jsonwith dependencies - Create
vite.config.mtswith entry point - Add to
chrome-extension/manifest.jsif needed - Ensure
pnpm-workspace.yamlincludes the directory
- Create storage in
packages/storage/lib/impl/usingcreateStorage() - Define TypeScript types
- Export from
packages/storage/lib/impl/index.ts - Use
useStorage()hook in React components
Follow packages/ui/README.md for shadcn/ui components:
- Run
pnpm dlx shadcn@latest add {component} -c ./packages/ui - Export from
packages/ui/lib/components/ui/index.ts - Use
withUI()in consuming page'stailwind.config.ts
Use pnpm update-version <version> to update all package.json files atomically (see UPDATE-PACKAGE-VERSIONS.md).
- E2E tests:
pnpm e2e(builds, zips, then runs tests) - Test location:
tests/e2e/ - Limited test infrastructure currently present
- Chrome: Full support (side panel API)
- Firefox: Compatible build via
__FIREFOX__env (excludes side panel) - Manifest v3 with webextension-polyfill for cross-browser APIs