Case file 08 · Extension
INTEREST PULSE
A Chrome side panel that turns scattered interests into a timely feed with sources, confidence and context.
- Svelte 5
- Chrome MV3
- NestJS
- PostgreSQL
- Redis
- TypeScript
The challenge
News about the things a person follows is scattered across outlets, stores, communities and product feeds. A useful extension had to find what changed without becoming another opaque recommendation system or asking for invasive browser access at installation.

The approach
I built Interest Pulse as a TypeScript monorepo with a Svelte 5 Manifest V3 extension, a NestJS API and a connector-based editorial pipeline. Shared contracts and pure ranking rules keep the feed explainable, while optional permissions, local history analysis and device-scoped deletion make privacy part of the architecture.
Key decisions
- Use a side panel instead of replacing the new-tab page, so the feed remains available without taking over a browser habit.
- Keep ranking rules and API contracts in shared packages, while every external source stays behind a replaceable adapter.
- Infer browsing interests on-device, require review before saving and keep sponsored content outside the organic score.
Technical architecture
Full-stack architecture designed and built end to end by me.
- 01 Browser experience Svelte 5 · Chrome MV3 · CRXJS
Side panel, options and service worker built around minimum install-time permissions.
- 02 Product API NestJS · Zod contracts
A device-scoped API serves feeds, interests, signals, privacy and shopping.
- 03 Editorial pipeline BullMQ · Redis · source adapters
Independent connectors ingest, normalize and rank without coupling the product to one provider.
- 04 Data & domain PostgreSQL · pgvector · Drizzle
Events, sources, interests and minimized signals share pure ranking rules and typed contracts.
Modules
What the product is made of, as its own screens divide it.
- 01 Side-panel feed
Current events about followed artists, games and series without leaving the active tab.
- 02 Interest profile
Explicit interests and locally inferred suggestions with visible provenance.
- 03 Source ingestion
Replaceable connectors normalize news and releases into one event model.
- 04 Ranking & explanations
Pure domain rules score recency and affinity, then explain every recommendation.
- 05 Signals & learning
Batched reading, saving and dismissal signals refine the profile.
- 06 Privacy controls
Export, deletion and optional permissions remain explicit and reversible.
- 07 Shopping & sponsorship
Commercial content stays outside the organic ranking and uses confirmed interests only.
Before → after
- Before
Interests scattered across media, stores and communities.
AfterOne timely feed beside every browser tab.
- Before
Recommendations with opaque reasons and provenance.
AfterSources, confidence and “why you see this” on every card.
- Before
Personalization that demands broad access up front.
AfterOptional permissions, local analysis and deletable provenance.
Technologies
- Svelte 5
- Chrome MV3
- NestJS
- PostgreSQL
- Redis
- TypeScript
The wider toolkit
- CRXJS
- Drizzle ORM
- pgvector
- BullMQ
- Zod
- Turbo
- Vitest
- Vite
Brand marks from Simple Icons; concepts without one are drawn in-house.
Project log
Sep 2026 → Sep 2026 · 1 active months
- extension monorepo browser extension · 22 commits Sep 2026 → Sep 2026
In the tree
- 10 API controllers
- 9 migrations
- 24 test files
- 238 tracked files
Read from the local Git history on Oct 6, 2026. Aggregates only.
The outcome
The Phase 1 build runs end to end with real source connectors, a ranked side-panel feed, batched signals, interest controls and a separate shopping surface. Its public repository snapshot contains 22 commits, 10 API controllers, nine migrations and 24 test files, keeping product decisions and privacy boundaries inspectable alongside the implementation.
Public codebase — product decisions and implementation are open for inspection.
