TUTORIAL · BROWSER EXT

Browser extensions are back. Here's how to ship a Manifest V3 + WXT extension that actually sells.

Extensions used to be a niche side project. Now they're a real distribution channel for AI-powered tools. I shipped one last month — here's the path I'd take if I were starting today.

MO
Maya Okafor
Indie hacker · Tutorials & ship-fast guides
TL;DR

Browser extensions are having a moment again. AI-powered tools (writing assistants, summarizers, scrapers, schedulers) are the new must-have. WXT is the framework I'd use today — it's like Vite for extensions, supports MV3, hot-reload, and Chrome + Firefox in one codebase. Here's the recipe.

Why now?

Three things made extensions interesting again:

  1. AI changed what an extension can do. A tab-summarizer used to require a backend, an API, and a queue. Now it's a fetch to OpenRouter or Anthropic and a popup. Distribution is suddenly bigger than implementation.
  2. Manifest V3 finally settled down. The migration was painful but it's done. Service workers replaced background pages and most flake is fixed.
  3. The Chrome Web Store still has insane reach. A small but well-designed extension can hit 10k installs in a month if it lands on Product Hunt or X.

The stack I'd use today

That's it. No Docker, no backend server to baby-sit, no separate auth provider needed.

Step 1 — Scaffold

npx wxt@latest init my-extension
cd my-extension
npm install
npm run dev   # opens Chrome with hot-reload

WXT auto-detects content scripts, service workers, popups, options pages — you just drop files in entrypoints/ and they show up.

Step 2 — A useful extension in 50 lines

Let's build a "summarize this page" tool. Click the icon, get a summary in a popup.

entrypoints/popup/App.tsx:

import { useState } from 'react'

export default function App() {
  const [summary, setSummary] = useState('')
  const [loading, setLoading] = useState(false)

  async function summarize() {
    setLoading(true)
    const [tab] = await chrome.tabs.query({ active: true, currentWindow: true })
    const [{ result }] = await chrome.scripting.executeScript({
      target: { tabId: tab.id! },
      func: () => document.body.innerText,
    })
    const r = await fetch('https://my-api.workers.dev/summarize', {
      method: 'POST',
      body: JSON.stringify({ text: result.slice(0, 8000) }),
    })
    setSummary(await r.text())
    setLoading(false)
  }

  return (
    <div style={{ padding: 16, width: 320 }}>
      <button onClick={summarize} disabled={loading}>
        {loading ? 'Summarizing…' : 'Summarize page'}
      </button>
      <p>{summary}</p>
    </div>
  )
}

The Worker on the other end just calls Anthropic / OpenAI and streams back a summary. ~30 lines.

Step 3 — The parts the docs skip

The docs are good at scaffolding. They are bad at the boring parts. The boring parts are why your extension actually ships:

A rejected store submission costs you a week. Read the review checklist before you write a line of code.

Distribution that actually moves the needle

Three channels, in order of how well they worked for me:

  1. Product Hunt — extensions do well there, especially with a 30-second video
  2. X (Twitter) — short demo gif, replies to posts complaining about the problem you solve
  3. The Web Store featured carousel — write a really good description, it gets crawled

The chrome.com/webstore organic search is also surprisingly real for niche keywords.

Where buildr fits

If you ask buildr "build me a Chrome extension that summarizes the current page," the agent picks WXT, scaffolds the popup, wires up a Worker for the AI calls, and ships both. Same chat, two artifacts (extension + backend), no separate setup.

Bottom line

The extension you're thinking about is shippable in a weekend.

WXT removed 80% of the boilerplate that used to make extensions painful. Manifest V3 is stable. AI gives extensions superpowers they didn't have before. If you've been sitting on an extension idea, this is the year. Tell me what you build.

Ship the extension you've been sitting on.

"Build me a Chrome extension that…" — same chat, WXT scaffold, Workers backend for AI. Free for open source.

Build my app free