Build a Tab Grouper Chrome Extension with Plasmo: A Step-by-Step Guide

Introduction

Chrome extensions are lightweight tools that enhance your browsing experience—from managing passwords to organizing tabs. While building one from scratch can involve complex setup, the Plasmo framework simplifies the process, letting you focus on core functionality. In this guide, you'll create a Tab Grouper extension that automatically groups tabs by domain using TypeScript, React, and Plasmo. No prior extension experience needed—just basic React and TypeScript knowledge.

Build a Tab Grouper Chrome Extension with Plasmo: A Step-by-Step Guide
Source: www.freecodecamp.org

What You Need

Step-by-Step Instructions

Step 1: Scaffold the Project

Open your terminal and run:

plasmo init tab-grouper
cd tab-grouper

This creates a new directory with TypeScript, React, and a basic manifest.json already configured. Plasmo reads your package.json and generates the manifest automatically—you never edit it directly. The project includes a popup.tsx file and a background folder where you'll add scripts.

Step 2: Understand the Extension Structure

Chrome extensions consist of:

For the Tab Grouper, you'll use the background script to handle tab creation and grouping, and the popup to trigger the action.

Step 3: Build the Background Script

Inside src/background, create a file index.ts. This script listens for messages from the popup and performs the grouping logic. Add:

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === 'groupTabs') {
    groupTabsByDomain();
  }
});

async function groupTabsByDomain() {
  const tabs = await chrome.tabs.query({ currentWindow: true });
  const domainMap: Record = {};

  for (const tab of tabs) {
    if (!tab.url || !tab.id) continue;
    const url = new URL(tab.url);
    const domain = url.hostname;
    if (!domainMap[domain]) domainMap[domain] = [];
    domainMap[domain].push(tab.id);
  }

  for (const [domain, tabIds] of Object.entries(domainMap)) {
    if (tabIds.length > 1) {
      await chrome.tabs.group({ tabIds });
      await chrome.tabGroups.update((await chrome.tabs.group({ tabIds })).groupId, {
        title: domain,
        color: 'blue'
      });
    }
  }
}

This script queries all tabs in the current window, groups tabs sharing the same domain, and assigns a color. Note: in a real implementation you'd handle errors and color cycling.

Step 4: Create the Popup UI

Open src/popup.tsx and replace the default content with a simple button:

import { sendToBackground } from '@plasmohq/messaging';

export default function Popup() {
  const handleGroup = async () => {
    await sendToBackground({ name: 'groupTabs' });
  };

  return (
    

Tab Grouper

); }

Plasmo's sendToBackground utility sends a message to the background script. Make sure the message name matches the listener in the background script.

Build a Tab Grouper Chrome Extension with Plasmo: A Step-by-Step Guide
Source: www.freecodecamp.org

Step 5: Test the Extension Locally

In your terminal, run:

plasmo dev

This starts a development server that rebuilds on changes. Open Chrome and go to chrome://extensions. Enable Developer mode, click Load unpacked, and select the build/chrome-mv3-dev folder (or whatever path Plasmo outputs). The extension should appear in your toolbar. Open several tabs from different sites, click the extension icon, then click Group Tabs – your tabs will be grouped by domain.

Step 6: Add Polish and Error Handling

To make the extension robust, consider:

For example, to cycle colors, define an array ['red','orange','yellow','green','blue','purple'] and increment an index per domain.

Step 7: Prepare for Publishing

When you're ready to publish:

Tips for Success

With these steps, you've built a fully functional Chrome extension using Plasmo. Now you can extend it with additional features or create entirely new extensions!

Recommended

Discover More

The Slow Revolution: How Programming Evolved and Stack Overflow Changed EverythingScorpions' Secret Weapon: How Nature Forges Biological Metal ArmorAWS 2026 Unveils Amazon Quick Desktop App and Expands Connect with Agentic AI Solutions10 Crucial Facts About GRASP: Making Long-Horizon Planning PracticalMastering JavaScript Startup Speed: How to Use V8's Explicit Compile Hints