DEV Community

Cover image for How I Built a Modern Chrome Extension with React, Plasmo, and rrweb
Ch Usama
Ch Usama

Posted on

How I Built a Modern Chrome Extension with React, Plasmo, and rrweb

Browser session recording is a game-changer for QA, product teams, and user research. I recently built a Chrome extension that lets users record their “Golden Path” flows, manage projects, and upload recordings to the cloud—all with a modern React UI. In this post, I’ll walk you through the architecture, key challenges, and lessons learned, so you can build your own powerful browser extension.

🚀 Why Build a Session Recorder Extension?

Manual bug reports and user feedback often miss crucial context. By capturing browser sessions, you can replay exactly what happened—making debugging, QA, and product feedback much more effective. My goal was to create an extension that’s easy to use, secure, and developer-friendly.

🏗️ Project Structure

/src
   /components
     /popup
     /recorder
     /auth
   /contents
   popup.tsx
/lib
   /hooks
   /providers
   /services
   /types
/constants
   api.ts
Enter fullscreen mode Exit fullscreen mode

Scaffolding with Plasmo

Plasmo makes it painless to set up a Chrome extension with React and TypeScript. It handles manifest generation, content script injection, and hot reloading.

pnpm create plasmo
pnpm install
pnpm dev
Enter fullscreen mode Exit fullscreen mode

Technical Deep-Dive

Architecture & Stack

  • Frontend: React 18, TypeScript, Tailwind CSS, Plasmo (for Chrome extension scaffolding)
  • State & Data: React Context, @tanstack/react-query for async state, zod for schema validation
  • Recording: rrweb for capturing DOM events, rrweb-player for playback
  • Auth: Auth0 via Chrome’s identity API, with token management and error handling
  • API: Custom API client with error schemas, project and upload services, and integration with a backend (Atlas)
  • UX: Modular popup UI with project dropdown, recording controls, and a draggable in-page recorder bar

Key Features

  • Screen Recording: Uses rrweb to capture and serialize user interactions, storing events in Chrome’s local storage.
  • Authentication: Auth0 flow is triggered via Chrome’s identity API, with robust error handling and token management.
  • Project Management: Fetches and manages projects from the backend, allowing users to select a context for their recordings.
  • UI/UX: Clean, responsive popup and in-page controls, with feedback for loading, errors, and upload status.

Notable Implementation Details

  • Plasmo Integration: Leverages Plasmo for MV3 manifest, content script injection, and streamlined extension development.
  • Type Safety: Heavy use of TypeScript and zod for runtime and compile-time safety.
  • Error Handling: Custom error classes and retry logic for API and auth failures.
  • Separation of Concerns: Hooks and providers abstract logic for recording, uploading, and project management.

Developer Experience

  • Linting & Formatting: ESLint, Prettier, and Husky for pre-push checks.
  • Scripts: pnpm dev, pnpm build, and pnpm lint for a smooth workflow.
  • Plasmo: Hot reloads and easy manifest management.

💡 Lessons Learned

  • OAuth in Extensions: Chrome’s identity API is powerful but has quirks—test thoroughly!
  • State Management: React Context + react-query is a great combo for async data.
  • Error Handling: Invest in good error messages and retries, especially for auth and uploads.
  • User Experience: A clean, simple UI makes a big difference for adoption.

📝 Conclusion

Building a modern Chrome extension is easier than ever with the right tools. Plasmo, React, and rrweb let you focus on features, not boilerplate. If you’re thinking about building your own extension, I hope this guide helps you get started!

Top comments (0)