Skip to content
doIIarplusPublic

About

A powerful, customizable Chrome new tab page extension

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Nova Tab

A powerful, customizable Chrome new tab page extension with a pluggable widget system, third-party API integrations, SQL query workbench, and a data transformation pipeline.

Chrome MV3 React 19 TypeScript Tailwind CSS

Features

Widget Dashboard

  • Drag-and-drop grid layout with configurable columns, row height, and compaction
  • 25 widget types spanning static displays, data visualizations, and interactive tools
  • Per-widget settings panel with 5 tabs: data sources, transform pipeline, display options, styling, and info
  • Per-widget content scaling via style settings
  • Copy/paste and duplicate widgets across pages
  • Multi-page dashboard with tab navigation
  • Page-level security with PIN lock, TOTP (2FA), and recovery codes

Widget Types

Type Category Description
Clock Static Large time display with date, 12/24h format
Greeting Static Time-aware greeting with optional name
Quick Links Static Shortcut grid to frequently visited sites
Search Static Quick web search bar
Timer Interactive Countdown timer
Stopwatch Interactive Elapsed time stopwatch
Claude Chat Interactive Conversational AI with model selection (Haiku/Sonnet/Opus), web search, persistent chat history
Notes Interactive Rich text editor (Tiptap) with slash commands, task lists, date smart chips, formatting toolbar
Card Benefits Interactive Editable credit card perks and benefits tracker
Number Card Data Single KPI value with color thresholds and sparkline trends
Table Data Sortable, filterable data table with column visibility and resize
List Data Compact title/subtitle list view
Bar Chart Chart Grouped or stacked bar chart, multi-series, dual Y axis
Line Chart Chart Multi-series line/area chart with stacking and dual Y axis
Pie Chart Chart Donut chart with legend and data labels
Heatmap Chart Color-intensity grid for two-dimensional data
Calendar View Data Week view with event indicators
Timeline Data Grouped chronological event list
Markdown Data Rendered markdown content from data
Credit Cards Financial Visual credit card display with balance and available credit
Accounts Financial Bank account summary with net worth, credit utilization, and asset tracking (categories: Cash, Investments, Assets, Credit, Loans)
Weather Specialized Current conditions + 6-day forecast via Open-Meteo with WMO weather codes
Stock Ticker Specialized Price sparklines with trend indicators, supports any data source or Alpha Vantage self-fetch
Air Quality Specialized AQI gauge display via AirNow
Oura Ring Specialized Health metrics with auto-detection of sleep, activity, readiness, and heart rate data

Data Connectors

Each connector is a self-contained plugin that fetches, normalizes, and caches data from an external service.

Connector Auth What it provides
Gmail Google OAuth2 Unread emails, message metadata
Google Calendar Google OAuth2 Upcoming events across calendars
Google Tasks Google OAuth2 Task lists and items
Claude AI API Key AI-generated responses, chat with web search
Notion API Key Database entries with dynamic schema
Plaid Proxy + Token Bank account balances and transactions
Plaid Cost Proxy + Token API cost tracking
SimpleFIN Bridge URL Bank accounts and transactions
Alpha Vantage API Key Stock price history and quotes
Open-Meteo None Weather forecasts and current conditions
AirNow API Key Air quality index by location
Oura API Key Sleep, activity, readiness, and heart rate data
Frankfurter None Currency exchange rates
Seats.aero API Key Flight and travel data
Custom REST API API Key / None Any JSON endpoint with field mapping

Query Workbench

A Honeycomb-inspired query workbench for exploring and transforming data:

  • Visual query builder -- WHERE filters, GROUP BY, VISUALIZE (aggregations), ORDER BY, LIMIT, HAVING
  • SQL editor -- write raw SQL with syntax highlighting and schema sidebar
  • Bi-directional sync -- visual query and SQL stay in sync as you edit either side
  • SQL engine -- parses SQL via node-sql-parser, supports SELECT, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT, UNION ALL, column aliases, string/number literals
  • Save as widget -- turn query results into a dashboard widget
  • Save as derived dataset -- create virtual datasets from queries for use by other widgets
  • Query history -- browse and replay past queries
  • Export -- download results as CSV or JSON

Manual & Derived Datasets

  • Manual datasets -- create custom data tables directly in the browser with typed columns
  • Derived datasets -- define virtual datasets via pipeline transforms or SQL queries over any combination of connectors, manual datasets, and other derived datasets
  • Derived datasets resolve lazily with cycle detection

Transform Pipeline

A JSON-serializable transform pipeline sits between data and display:

  • filter -- field conditions with and/or logic, date macros ({{now}}, {{now+7d}})
  • sort -- multi-field ascending/descending
  • group_by -- group rows and aggregate per group
  • aggregate -- sum, avg, min, max, count, count_distinct, first, last, median, p50, p95, p99
  • computed_field -- safe JavaScript expressions evaluated per-row
  • select_fields / rename_field -- column projection and renaming
  • limit -- offset + count pagination
  • time_series_bucket -- bucket by hour/day/week/month/quarter/year with gap-filling and timezone support
  • merge -- union or join (inner/left/right/full) multiple data sources
  • custom_expression -- row-level or table-level JS with a sandboxed evaluator
  • window_function -- row_number, rank, running_total, moving_avg, lag, lead, percent_of_total with partition-by and order-by
  • having -- post-aggregation filtering

Theming

  • 9 built-in color themes (Midnight, Slate, Emerald, Rose, Amber, Nord, Dracula, Solarized, Monokai)
  • Dark / Light / System mode
  • Custom accent color, font family, background image with opacity control
  • Global text scale + per-widget content scale
  • OKLCh color space for perceptually uniform palettes

Architecture

External APIs
     |
     v
 Connectors (service worker, chrome.alarms)
     |
     v
 chrome.storage.local (cached NormalizedDataSet)
     |
     v
 useWidgetData hook (TanStack Query + pipeline)
     |
     v
 Display Components (React)

 Manual Datasets ──┐
                    ├──> Query Workbench / Derived Datasets
 Connector Data ───┘

Data flows one direction. The service worker fetches on a schedule and writes to storage. The new tab page reads reactively. Connectors and widgets never reference each other -- all data passes through the NormalizedDataSet / DataTable interfaces.

Manual and derived datasets feed into the same pipeline, allowing widgets to consume data from any source uniformly.

Tech Stack

Layer Technology
Framework React 19, TypeScript 5
Bundler Vite 6, @crxjs/vite-plugin
Styling Tailwind CSS v4 (OKLCh tokens)
Grid react-grid-layout v2
Charts Recharts
Rich Text Tiptap v3 (ProseMirror)
SQL node-sql-parser
State Zustand (global, persisted to chrome.storage)
Data Fetching TanStack Query
Forms react-hook-form, Zod
Animation Framer Motion
Icons lucide-react
Package Manager Bun

Getting Started

Prerequisites

  • Bun >= 1.0
  • Node.js >= 20
  • Google Chrome or Chromium-based browser

Install

bun install

Development

bun run dev

Then load the extension in Chrome:

  1. Navigate to chrome://extensions
  2. Enable Developer mode
  3. Click Load unpacked
  4. Select the dist/ directory

The dev server supports HMR -- changes to React components will hot-reload in the new tab page.

Production Build

bun run build

Outputs a ready-to-load extension in dist/.

Type Check

npx tsc --noEmit

Project Structure

src/
  manifest.ts                   # Chrome MV3 manifest (typed)
  index.css                     # Tailwind entry + custom theme tokens
  newtab/                       # New tab page
    App.tsx                     # Shell: grid + floating toolbar + page tabs
  background/
    service-worker.ts           # Alarm-based fetch scheduling
  core/
    types/                      # TypeScript interfaces (common, connector, widget, transform, grid)
    pipeline/                   # Transform engine + SQL engine + sandbox + date macros
    registry/                   # Connector and display type registries
    storage/                    # Zustand persistence adapter for chrome.storage
    auth/                       # OAuth2 flows, API key store, token cache
    themes/                     # 9 OKLCh color theme presets
    messaging/                  # Typed NTP <-> service worker message passing
    docs/                       # Widget documentation registry
  connectors/
    gmail/                      # Gmail API
    google-calendar/            # Calendar API
    google-tasks/               # Tasks API
    claude/                     # Anthropic Messages API + chat
    notion/                     # Notion database query
    plaid/                      # Plaid via proxy (accounts + cost tracking)
    simplefin/                  # SimpleFIN bridge
    alpha-vantage/              # Stock price data
    open-meteo/                 # Weather forecasts
    airnow/                     # Air quality index
    oura/                       # Oura Ring health data
    frankfurter/                # Currency exchange rates
    seats-aero/                 # Flight data
    custom-api/                 # Generic REST endpoint
  widgets/
    base/
      WidgetShell.tsx           # Frame, drag handle, controls, content scaling
      useWidgetData.ts          # TanStack Query hook for connector data
    displays/                   # Data-driven renderers (charts, tables, cards, weather, stocks)
    interactive/                # Stateful widgets (Chat, Notes, CardBenefits, Timer, Stopwatch)
      notes-editor/             # Tiptap rich editor with slash commands and date chips
    settings-panel/             # 5-tab config modal + visual query builder
  grid/
    GridContainer.tsx           # react-grid-layout wrapper
    GridConfigPanel.tsx         # Grid configuration controls
  stores/                       # Zustand stores (widget, connector, theme, layout, page, manual/derived datasets)
  components/
    query-workbench/            # SQL/visual query builder, results panel, export, history
    WidgetPicker.tsx            # Widget type browser
    ConnectorManager.tsx        # Data source configuration
    ManualDatasetEditor.tsx     # Manual dataset CRUD + derived dataset management
    PageTabs.tsx                # Multi-page tab bar
    GlobalSettings.tsx          # App-wide settings
    WidgetDocsModal.tsx         # Widget documentation viewer

Configuring Connectors

Google Services (Gmail, Calendar, Tasks)

Requires a Google Cloud project with the appropriate APIs enabled and an OAuth2 client ID configured for Chrome extensions. Set the client ID in src/manifest.ts under the oauth2 key.

Claude AI

  1. Get an API key from console.anthropic.com
  2. Add a Claude Chat widget
  3. Enter your API key when prompted (or update it via the key icon in the chat toolbar)
  4. Select your preferred model (Haiku 4.5, Sonnet 4.6, or Opus 4.6)

Notion

  1. Create an internal integration
  2. Share your database with the integration
  3. Add a Notion connector with the integration token and database ID

Plaid

Plaid requires a server-side proxy to hold your client_id and secret. Configure the proxy URL in the Plaid connector settings.

SimpleFIN

  1. Get a setup token from SimpleFIN
  2. Add a SimpleFIN connector and enter the token
  3. The extension will exchange it for an access URL automatically

Custom REST API

Connect to any JSON endpoint. Configure URL, method, headers, response path (dot notation), and field mappings.

Extending

Adding a New Connector

  1. Create src/connectors/your-service/your-connector.ts
  2. Extend BaseConnector and implement manifest and fetch()
  3. Register in src/connectors/index.ts
  4. The connector will automatically appear in the Data Sources panel

Adding a New Widget

  1. Create a component in src/widgets/displays/ or src/widgets/interactive/
  2. Add to staticWidgets or dataWidgets map in src/widgets/base/WidgetShell.tsx
  3. Add a template entry in src/components/WidgetPicker.tsx

License

MIT License - see LICENSE for details.

About

A powerful, customizable Chrome new tab page extension

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages