Create your portfolio instantly & get job ready.

www.0portfolio.com
AIUnpacker

Best AI Prompts for Chrome Extension Development with Cursor

AIUnpacker

AIUnpacker

Editorial Team

32 min read

TL;DR — Quick Summary

Eliminate the context-switching tax of Chrome extension development by mastering AI prompts for Cursor. This guide provides specific prompt strategies to manage manifest.json, background.js, and content.js files efficiently. Learn how to turn multi-file coordination nightmares into a streamlined, co-pilot driven workflow.

Get AI-Powered Summary

Let AI read and summarize this article for you in seconds.

Quick Answer

We streamline Chrome extension development in Cursor by using a centralized .cursorrules file to enforce Manifest V3 standards and project structure. This approach eliminates context switching and prevents common architectural errors across multiple files. Below are the specific prompts and configurations we use to scaffold, build, and debug extensions efficiently.

Benchmarks

Read Time 4 min
Tool Cursor AI
Standard Manifest V3
Focus Chrome Extensions
Year 2026

Revolutionizing Extension Development with AI

Have you ever spent more time switching between files than writing actual code? For Chrome extension developers, this isn’t a minor annoyance—it’s a daily reality. You’re constantly juggling the manifest.json to ensure permissions are correct, flipping to background.js to handle service worker logic, diving into content.js for DOM manipulation, and then jumping over to popup.html or options.js for the user interface. This context-switching tax is real; it breaks your flow and turns a simple feature into a multi-file coordination nightmare. A 2024 Stack Overflow survey noted that developers spend nearly 17% of their week just navigating codebases, a figure that skyrockets in modular projects like extensions.

This is precisely why Cursor is a game-changer. Unlike traditional IDEs that treat files as isolated silos, Cursor’s “Composer” and “Chat” features are built for holistic project editing. You can describe a feature in plain English, and it will simultaneously scaffold the manifest.json, write the background script, inject the content script, and build the popup UI—all while maintaining consistency across the entire multi-file structure. It understands the relationships between these files, making it the perfect environment for AI-driven development.

In this guide, you’ll get a curated library of battle-tested prompts designed to leverage this power. We’ll move beyond simple boilerplate and tackle the entire extension lifecycle: initial scaffolding, feature integration, and even debugging complex permission errors. These are the exact copy-pasteable prompts I’ve developed to streamline my own workflow, turning hours of tedious setup into minutes of focused creation.

Setting the Stage: Cursor Configuration for Extensions

Why do so many Chrome extensions start strong but become unmaintainable nightmares? The problem rarely lies in the initial feature set. It’s the silent, creeping chaos of configuration drift. A background script that accidentally uses a DOM API it shouldn’t, a popup that tries to access a tab’s origin without the right permission, or a manifest file that mixes V2 and V3 standards. When you’re juggling manifest.json, background.js, content.js, and popup.html, the context switching is immense. This is where a generic AI assistant fails; it sees one file at a time. But a properly configured Cursor environment sees the entire extension as a single, interconnected system. Getting this foundation right isn’t just a “nice to have”—it’s the difference between a project that scales and one that collapses under its own weight.

The .cursorrules File: Your Project’s AI Constitution

Before you write a single line of code, you need to establish the rules of the road. In the root of your project directory, create a file named .cursorrules. This simple text file is one of Cursor’s most powerful, yet underutilized, features. It acts as a persistent set of instructions that the AI will reference in every single interaction within that project. Think of it as embedding a senior developer’s architectural guide directly into your workflow.

For a Chrome extension, this is non-negotiable. Your .cursorrules file should be explicit about the environment’s constraints. Here’s a practical example of what I use in my own projects:

// .cursorrules
- You are an expert Chrome Extension developer.
- Adhere strictly to Manifest V3 standards. Do not use deprecated V2 APIs like `chrome.extension` or background pages. Use service workers for `background`.
- The project structure is:
  - `src/` for all source files.
  - `src/background.js` for the service worker.
  - `src/content.js` for content scripts.
  - `src/popup/` for the popup UI (HTML, CSS, JS).
- All DOM manipulation must be confined to the popup or content scripts, never the background service worker.
- When generating code, provide a brief explanation of why you chose a specific API or pattern, referencing the official Chrome Extension documentation if relevant.

This single file prevents entire classes of errors. You will never have to waste time debugging why your document.querySelector is failing in the background script, because the AI will proactively stop you. This is a golden nugget of workflow optimization: front-load your architectural constraints. The 5 minutes you spend writing a robust .cursorrules file will save you hours of debugging and refactoring later.

Importing Documentation: The “Add to Knowledge” Superpower

Manifest V3 introduced significant changes, and the official Chrome developer documentation is extensive. Expecting an AI to have perfect, up-to-the-minute knowledge of every API nuance is a recipe for frustration. This is where you bridge the gap between the AI’s general training and your project’s specific needs.

Cursor’s “Add to Knowledge” feature (accessible via the paperclip icon in the chat interface) allows you to feed specific files or entire folders to the AI as context for the current conversation. My go-to strategy is to download the latest manifest.json reference page and the “Migrating from V2 to V3” guide as PDFs or text files and add them to my project’s docs/ folder. Before starting a complex task, I’ll explicitly tell the AI:

“I’ve added the manifest_v3_reference.md and service_workers_guide.md to your knowledge. Please review them to ensure all generated code is compliant.”

This isn’t just about getting the syntax right; it’s about leveraging the AI as a research partner. I once asked Cursor to implement a new feature using chrome.tabs.executeScript. It immediately flagged this as a V2 API, explained that scripting injection in V3 must be done via the chrome.scripting API, and provided the correct, compliant code block. This level of accuracy is impossible without giving the AI the specific source material to reference. You are not just prompting; you are curating the AI’s expertise.

Defining the Scope: Composer vs. Chat for Extension Tasks

A common mistake is treating Cursor’s AI as a monolithic tool. The distinction between the Chat panel and the Composer is critical for efficient extension development. Using the wrong tool for the job leads to context pollution, incomplete implementations, and a fractured workflow.

Here’s how to strategically divide your tasks:

  • Use Composer for Greenfield Development and Large Refactors: The Composer is your architectural workshop. It’s designed to make multi-file changes in a single, coherent session. This is the tool you use when you say, “Build a new popup for user settings with three input fields, connect it to the background service worker using chrome.storage.local, and create the necessary message passing logic.” Composer will generate popup.html, popup.css, popup.js, and update background.js and manifest.json all at once. It maintains the “big picture” across the entire feature. I recently used this to build a full “options” page in under 10 minutes—a task that would have taken an hour of manual wiring.

  • Use Chat for Debugging and Surgical Changes: When a specific feature breaks, you don’t need a workshop; you need a scalpel. Use the Chat panel for targeted questions about a single file or a specific bug. For example: “The message listener in background.js isn’t receiving messages from content.js. Can you analyze these two files and find the mismatch?” The Chat context is narrower and more analytical, perfect for isolating and fixing problems without the overhead of generating multiple files.

By consciously choosing your tool, you maintain a clean project state and allow the AI to operate with the right level of context, ensuring your extension’s multi-file structure remains robust and consistent.

Phase 1: Scaffolding the Manifest and Core Architecture

Building a Chrome extension can feel like juggling too many balls at once. You’re constantly switching context between the manifest.json file, your background service worker, and your various content scripts. One misplaced permission or incorrect file path, and your extension fails silently, leaving you to hunt through logs for hours. This initial scaffolding phase is where most developers get stuck, especially with the strict requirements of Manifest V3.

This is where Cursor’s multi-file awareness becomes your secret weapon. Instead of manually creating each file and hoping you’ve remembered every required field, you can use a conversational approach to build a solid foundation in minutes. We’ll start by defining the extension’s soul—its manifest—and then build out the entire file structure and a basic “Hello World” test to prove everything is connected correctly.

Prompt 1: The Manifest V3 Generator

The manifest.json is the non-negotiable blueprint for your extension. With Manifest V3 now the standard, developers must navigate new requirements like the service_worker and granular host permissions. A common mistake is requesting overly broad permissions like "<all_urls>", which is a red flag for the Chrome Web Store review process. This prompt helps you generate a secure, compliant manifest based on your specific needs.

The Prompt:

“Act as a Chrome Extension expert specializing in Manifest V3. Generate a manifest.json file for a [describe your extension, e.g., ‘productivity tool that tracks active tabs’]. It requires the following capabilities: [list permissions, e.g., ‘access to user’s tabs’, ‘local storage for settings’, ‘a popup UI’]. Please ensure the permissions are as minimal as possible and follow 2025 best practices for security and privacy.”

Why this works:

  • Role-Playing: You’re telling the AI to adopt an expert persona, which primes it to use the latest, most secure standards (like Manifest V3) instead of outdated V2 syntax.
  • Contextual Constraints: By describing the extension’s function, you allow the AI to infer the necessary permissions, preventing you from requesting access you don’t need. This is a “golden nugget” for avoiding Web Store rejections.
  • Actionable Output: You get a ready-to-use JSON file, complete with the correct structure for service workers and popups, saving you from cross-referencing documentation.

Expert Tip: Always ask the AI to justify its permission choices. I once had a generated manifest include contextMenus when I only needed a popup. A quick follow-up question revealed it was a suggestion, not a requirement, saving me an unnecessary permission declaration.

Prompt 2: The Folder Structure Command

A messy folder structure is a breeding ground for bugs. As your extension grows, having a clear separation between source code, assets, and build outputs becomes critical. Manually creating src, assets, and dist folders, then populating them with boilerplate files, is tedious and error-prone. This prompt automates the entire project layout.

The Prompt:

“Create a standard directory structure for a Chrome Extension. Generate the following folders: src (for all scripts), assets (for icons and images), and dist (for the final build output). Inside src, create empty boilerplate files: background.js, content.js, and a popup subfolder containing popup.html and popup.js. Output the entire tree structure as a single command or script I can run.”

Why this works:

  • Simultaneous Creation: This prompt is designed for a tool like Cursor’s Composer, which can create multiple files and folders at once. It understands the holistic project structure, not just individual files.
  • Scalability: By establishing this convention from day one, you’re setting yourself up for success. When you need to add a new feature, you already know where the files go. This prevents the “file spaghetti” that plagues many legacy extensions.
  • Build-Ready: The inclusion of a dist folder signals an awareness of the final packaging process, encouraging a professional workflow from the very beginning.

Prompt 3: The “Hello World” Injection

You’ve got your manifest and your folders. Now, how do you know it all actually works? The fastest way to validate your setup is to confirm that your background service worker is running and your content script can modify a page. This prompt writes the minimal code needed to create a visible, verifiable result.

The Prompt:

“Write two pieces of code to verify the extension setup:

  1. A background.js script that uses chrome.runtime.onInstalled to log ‘Extension successfully loaded and installed.’ to the console.
  2. A content.js script that finds the <body> element of the current tab and applies a thick, solid red border to it. Ensure this script is configured to run on all pages.”

Why this works:

  • Immediate Feedback Loop: This prompt provides a complete, end-to-end test. You load the unpacked extension, open the browser’s service worker console to see your log, and immediately see a red border on any webpage you visit. This instant confirmation is incredibly motivating and confirms your manifest permissions are correct.
  • Practical Debugging: The red border is a simple but powerful visual cue. If the border doesn’t appear, you know immediately that the issue lies with your content script injection or manifest configuration, narrowing down the problem space significantly.
  • Foundation for Complexity: This simple logic establishes the correct event listeners (onInstalled) and DOM manipulation techniques that you’ll build upon for more complex features. It’s the perfect, low-stakes way to ensure your core architecture is solid before you start adding advanced logic.

Phase 2: Building the User Interface (Popup & Options)

A functional extension is useless if users can’t interact with it. This is where most developers get bogged down—staring at a blank popup.html file, trying to remember the right CSS framework classes or the exact syntax for Chrome’s storage API. We can shortcut this entire process by treating the UI as a modular component, generating it with precision and then wiring it to the extension’s core logic. This approach ensures your UI is not only modern and responsive but also correctly integrated from the start, preventing the common headache of mismatched message passing.

Prompt 4: The Tailwind/Bootstrap Popup

Your extension’s popup is its face. It needs to be clean, responsive, and instantly understandable. Instead of manually writing boilerplate HTML and CSS, you can leverage Cursor to generate a complete, modern UI component based on a single, descriptive prompt. This is where you can see the power of AI-driven development in action; it handles the tedious setup, letting you focus on the user experience.

Here is the prompt I use to generate a functional popup in seconds:

Prompt: `Generate the code for a popup.html file using Tailwind CSS. The UI should include:

  1. A header with the extension name.
  2. A toggle switch to enable/disable the core feature.
  3. A “Save Settings” button.
  4. A small status message area that is hidden by default. Ensure the layout is responsive and looks good on small popup windows. Use a dark theme.`

Why this works and what to watch for:

  • Framework Specificity: By explicitly naming “Tailwind CSS,” you prevent the AI from defaulting to vanilla CSS or another framework, saving you a significant refactoring step. If you prefer Bootstrap, simply swap the framework name.
  • Component-Driven Design: Listing the specific UI elements (toggle, button, status area) forces a structured output rather than a generic template. The AI will generate the necessary HTML structure for these elements.
  • The “Golden Nugget” - State Management: A common pitfall is that the generated HTML is just static markup. After the AI generates the code, your very next prompt should be: Now, add the JavaScript to this popup.html to toggle the 'active' class on the save button when the toggle switch is clicked, providing immediate visual feedback. This small addition teaches the AI to think about the interactive state from the beginning, creating a much better user experience.

This prompt gives you a production-ready starting point. You get a responsive, dark-themed UI that’s ready for logic to be attached, cutting out at least 15-20 minutes of setup and styling.

Prompt 5: The Options Page Logic

The options page is where user preferences live. It needs to reliably save data to chrome.storage.sync so settings persist across devices and browser restarts. Writing this logic correctly involves handling asynchronous promises, error checking, and UI state updates—a perfect task for an AI that rarely makes syntax errors.

Use this prompt to generate the complete options.html and options.js files in one go:

Prompt: `Create an options page for our Chrome Extension.

  1. Create options.html: Use a simple, clean form with a text input for a “User API Key” and a “Save” button.
  2. Create options.js: Write the script to handle the form.
  • On page load, it should use chrome.storage.sync.get to retrieve the saved ‘apiKey’ and populate the text input.
  • When the “Save” button is clicked, it should use chrome.storage.sync.set to save the value from the input.
  • After saving, it should update a status div to say “Settings Saved!” and clear it after 2 seconds.
  • Include basic error handling in a .catch() block.`

Building Trust Through Robust Code: This prompt is a great example of demonstrating expertise. Notice the specific instructions for chrome.storage.sync.get on load and chrome.storage.sync.set on click. This explicit instruction prevents a common beginner mistake: only writing the “save” logic and forgetting the “load” logic. The AI will generate a complete, functional module. By including the status update and error handling, you’re building a trustworthy extension that provides clear feedback to the user, which is a hallmark of quality software.

Prompt 6: Connecting UI to Logic

Your popup and options page can’t do everything themselves. For security and architectural reasons, they need to communicate with the background service worker. This message passing is a critical piece of the puzzle, and getting the chrome.runtime.sendMessage syntax right in both the sender (popup) and receiver (background) can be tricky.

The best strategy here is a two-step, context-aware prompting technique. Don’t ask for everything at once. First, establish the “contract” between the files, then implement each side.

Step 1: Define the Message Contract in the Popup Start by modifying your popup.js (which should have been generated with the HTML in Prompt 4).

Prompt: `In my popup.js, when the “Save Settings” button is clicked, instead of saving directly, I need to send a message to the background service worker.

  1. Use chrome.runtime.sendMessage to send an object like: { type: “SAVE_SETTINGS”, payload: { apiKey: “some_value” } }.
  2. Listen for a response from the background script using a Promise-based approach with chrome.runtime.sendMessage.
  3. If the response is successful, update the status div with “Background Saved!”.`

Step 2: Implement the Listener in the Background Now, with that message contract defined, you can instruct the background script.

Prompt: `Update the background.js file to handle the message from the popup.

  1. Add a chrome.runtime.onMessage.addListener.
  2. Check if the message type is “SAVE_SETTINGS”.
  3. If it is, use chrome.storage.sync.set to save the payload.
  4. Send a response back to the popup using sendResponse({ status: “success” }).`

Why this two-step process is superior:

  • Reduces Hallucination: By defining the message structure first, you give the AI a clear “schema” to work with. It’s less likely to invent incorrect properties or message types.
  • Ensures Symmetry: This method forces the AI to write the listener (onMessage) and the sender (sendMessage) in perfect harmony. It’s the most reliable way to get message passing working on the first try.
  • Debuggability: If it doesn’t work, you know exactly where the contract was defined and can check both sides for adherence. It’s a professional workflow that mirrors how senior developers design systems.

Phase 3: Mastering Content Scripts and DOM Manipulation

Content scripts are the workhorse of any Chrome extension; they’re where your code meets the user’s actual web page. But manipulating the DOM reliably, especially on modern, dynamic websites, is where many extensions fail. You’ve likely built a tool that works perfectly on a static page, only to watch it break the moment you navigate to a single-page application (SPA) like Gmail or a React-based dashboard. This happens because the DOM isn’t a static entity anymore—it’s a living, breathing tree that changes constantly.

The key to success is moving beyond simple document.querySelector calls and embracing patterns that are aware of the page’s dynamic nature. We’ll cover three critical prompts that build on each other: finding elements, communicating with your extension’s backend, and finally, watching for changes in real-time. This progression ensures your extension is not just functional, but robust and user-friendly.

Prompt 7: Context-Aware DOM Manipulation

This is your foundational prompt. You’re not just asking for code; you’re asking for a strategy to identify and modify elements without breaking the page’s existing layout or functionality. A common mistake is to blindly inject buttons or overlays, which can interfere with event listeners already on the page. The goal is surgical precision.

The Prompt:

Act as an expert Chrome extension developer specializing in Manifest V3. Write a content script (`content.js`) that performs the following tasks:

1.  **Scans the DOM:** Finds all `<h1>` elements on the current page.
2.  **Checks for Existing Modifications:** For each `<h1>` found, it must first check if a specific data attribute (e.g., `data-extension-processed="true"`) already exists on the element. This prevents the script from re-processing the same element if it runs multiple times.
3.  **Surgical Injection:** If the attribute is not present, inject a small, styled `<button>` element immediately after the `<h1>` text. The button should have the text "Copy Heading".
4.  **Add Event Listeners:** Attach a `click` event listener to this new button. When clicked, the listener should copy the `innerText` of the parent `<h1>` to the user's clipboard and provide visual feedback (e.g., briefly changing the button text to "Copied!").
5.  **Mark as Processed:** After injecting the button, add the `data-extension-processed="true"` attribute to the `<h1>` element to prevent duplicate buttons.

Ensure the injected button has a non-intrusive style (e.g., small font, subtle border) to maintain a good user experience.

Why this prompt works:

  • Prevents Duplicate Injections: The data-extension-processed check is a critical “golden nugget” of experience. It solves the common issue of scripts running on history state changes in SPAs and creating duplicate UI elements.
  • Focuses on User Experience: By asking for non-intrusive styling and clear feedback (“Copied!”), you’re building a tool that feels native to the browser, not a clunky add-on.
  • Actionable Logic: It provides a complete, self-contained loop: find, check, modify, listen, and mark. This is a reusable pattern for almost any DOM manipulation task.

Prompt 8: The Message Passing Bridge

Your content script can’t access the user’s storage or make network requests on its own due to security sandboxing. It needs a bridge to your background service worker. The most common user interaction is clicking the extension’s icon in the toolbar (the “browser action”), which should trigger an action on the current page. This requires a full-duplex communication channel.

The Prompt:

Generate the complete code for a two-way communication channel between a background service worker and a content script for a Chrome Extension (Manifest V3).

**Background Script (`background.js`) requirements:**
1.  Listen for the `chrome.action.onClicked` event (when the user clicks the extension icon).
2.  When clicked, it must query for the currently active tab using `chrome.tabs.query`.
3.  Send a message to that active tab's content script using `chrome.tabs.sendMessage`. The message payload should be a JSON object: `{ action: "changeBackground", color: "#e6f7ff" }`.
4.  Include a `chrome.runtime.onMessage` listener to receive a confirmation response back from the content script and log it to the service worker console.

**Content Script (`content.js`) requirements:**
1.  Listen for incoming messages using `chrome.runtime.onMessage`.
2.  If the received message has an `action` property equal to `"changeBackground"`, it should change the `document.body.style.backgroundColor` to the `color` value provided in the message.
3.  After changing the color, send a response back to the background script using the `sendResponse` function. The response should be `{ status: "success", message: "Background color updated." }`.

Why this prompt works:

  • Defines the Full Loop: It explicitly asks for both the sender (background) and the receiver (content script), including the sendResponse callback. This avoids the common pitfall where a developer only generates one side of the equation.
  • Real-World Pattern: Using the action.onClicked event is the standard way to trigger extension-wide commands. The prompt generates a production-ready implementation of this pattern.
  • Clear Payload Structure: By defining the message object ({ action: "..." }), it establishes a clear API contract between your scripts, making the system easier to debug and extend later.

Prompt 9: Handling Dynamic Content

This is the final boss of content script development. Modern websites don’t reload; they fetch data and update the DOM on the fly. Your MutationObserver is the tool for this job, but it’s notoriously tricky to implement correctly without killing performance. A poorly written observer can make a user’s browser crawl to a halt.

The Prompt:

Refactor the previous content script to handle dynamically added content using a `MutationObserver`.

**Context:** The script's primary job is to find `<h1>` elements and add a "Copy Heading" button to them, as defined in the initial task.

**Requirements:**
1.  **Initial Scan:** The script should first run the logic to find and process existing `<h1>` elements on page load.
2.  **MutationObserver Setup:** Create a `MutationObserver` that watches for changes inside the `<body>` element.
3.  **Performance Optimization:** Configure the observer with `subtree: true` and `childList: true` to watch for new nodes. Inside the observer's callback, use `mutations.addedNodes` to efficiently iterate *only* over newly added elements.
4.  **Recursive Logic:** For each added node, check if it is an `<h1>` element. If it is, apply the same button injection logic. If the added node is a container (like a `<div>`), search *within that specific node* for any `<h1>` elements and process them. This is more performant than re-scanning the entire document.
5.  **Debounce (Optional but Recommended):** Add a simple debounce mechanism to the observer callback to prevent it from firing too frequently on pages with rapid DOM changes (e.g., infinite scroll feeds).

Why this prompt works:

  • Addresses the Core SPA Problem: This prompt directly solves the issue of “my extension works on the first page load but breaks after I click a link.”
  • Prioritizes Performance: By asking for an efficient check of addedNodes and a recursive search within new containers, you’re instructing the AI to avoid the performance trap of re-querying the entire document on every single DOM change. This is a crucial insight that separates amateur extensions from professional ones.
  • Builds on Prior Work: It explicitly asks to “refactor the previous content script,” reinforcing the iterative development process and ensuring the final code is a cohesive unit rather than a collection of disjointed snippets.

Phase 4: Advanced Logic, Storage, and Debugging

Once your extension’s skeleton is in place, the real challenge begins: making it persistent, intelligent, and resilient. This is where most developers hit a wall with Manifest V3’s ephemeral service workers. How do you maintain state when the background process can be terminated at any moment? How do you debug the cryptic errors that pop up in the browser console? This phase is about moving from a working prototype to a production-ready tool.

Prompt 10: State Management with Storage

The biggest paradigm shift from Manifest V2 to V3 is the loss of persistent background pages. Your service worker lives a fleeting life; it wakes up to handle an event and can be terminated seconds later to save resources. This means you cannot rely on global variables to store user data. The solution is chrome.storage.local, which provides a persistent key-value store that survives browser restarts and service worker terminations.

Here is a prompt designed to build a robust state management system that handles reading, writing, and updating a counter or user session data:

I need to implement a robust state management system for my Chrome Extension using Manifest V3. The core challenge is that my `background.js` service worker is non-persistent.

Create a `storageManager.js` module that abstracts all interactions with `chrome.storage.local`. It needs to:
1.  Provide an `async getState(key)` function that safely retrieves data.
2.  Provide an `async setState(key, value)` function that updates the state.
3.  Implement a `subscribeToChanges(key, callback)` function that listeners can use to react to state updates from other parts of the extension (e.g., a popup updating a counter should be reflected in the content script).

Crucially, show me how to use this manager in `background.js` to track a simple user session counter. The counter should increment every time the extension icon is clicked and persist even if the browser is closed and reopened. Include error handling for when `chrome.storage` is unavailable or quota is exceeded.

Expert Insight: A common pitfall is assuming chrome.storage.onChanged will always fire within the same service worker instance. It won’t if the worker is terminated. The setState function in the generated code should always perform a get followed by a set to ensure an atomic update, preventing race conditions when the service worker restarts.

Prompt 11: The “Fix My Code” Prompt

When a Chrome Extension fails, the error message is often just a symptom, not the cause. A generic “fix this” prompt will give you a generic, often incorrect, answer. To get a useful solution, you must provide the AI with the full context: the error, the suspect code, and the extension’s configuration (the manifest).

This structured prompt template is designed to force the AI to act like a senior developer, analyzing the entire system before suggesting a fix.

Analyze the following error and suggest a fix by cross-referencing the code and manifest permissions.

**Error Message:**

[Error: ‘chrome.runtime.sendMessage’ is undefined]


**Relevant Code (`content.js`):**
```javascript
// Send a message to the background script
chrome.runtime.sendMessage({ action: "fetchData" }, (response) => {
  console.log("Received response:", response);
});

Manifest (manifest.json):

{
  "manifest_version": 3,
  "name": "My Extension",
  "version": "1.0",
  "permissions": ["activeTab"],
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["content.js"]
    }
  ],
  "background": {
    "service_worker": "background.js"
  }
}

Task:

  1. Identify the root cause of the error by analyzing the manifest permissions and the Chrome API lifecycle.
  2. Explain why this error occurs in Manifest V3.
  3. Provide the corrected code for both content.js and background.js to ensure the message is sent and received correctly.

**Golden Nugget:** The most common cause for `chrome.runtime.sendMessage` failures in MV3 is a race condition. The content script might load and try to send a message *before* the service worker has finished initializing and registering its `chrome.runtime.onMessage` listener. A truly expert fix involves adding a retry logic in the content script or ensuring the listener is the very first thing registered in the background script.

### Prompt 12: Refactoring for Performance

Content scripts run in the context of a live webpage. A poorly written content script can degrade the user experience of the host site, causing lag or jank. The most common performance bottleneck is inefficient DOM querying, especially in Single Page Applications (SPAs) where the page content changes dynamically without a full reload.

Use this prompt to identify and fix performance issues in your content script:

```markdown
Review the following content script for performance bottlenecks and suggest a more efficient way to query the DOM.

**Current Code:**
```javascript
// This runs on every DOM change in an SPA
const observer = new MutationObserver(() => {
  // This is the bottleneck: re-querying the entire document on every change
  const elements = document.querySelectorAll('.target-element');
  elements.forEach(el => {
    if (!el.dataset.processed) {
      el.style.border = '2px solid red';
      el.dataset.processed = 'true';
    }
  });
});

observer.observe(document.body, { childList: true, subtree: true });

Constraints:

  1. The solution must still work for dynamically loaded content (SPAs).
  2. Minimize DOM queries. Instead of querying the entire document, only search within the newly added nodes.
  3. Avoid applying the same change multiple times to the same element.

Provide the refactored code with comments explaining the performance improvements.


**Why this works:** This prompt forces the AI to move from a "brute force" approach to a surgical one. The generated code will likely use `mutation.addedNodes` to target only new elements, preventing the massive performance cost of re-scanning the entire page. This is a critical technique for building professional, non-intrusive extensions.

## Phase 5: The "Master Prompt" for End-to-End Features

You've built the skeleton of your extension. Now it's time to attach muscle and sinew—the features that deliver real value. This is where most developers hit a wall. They try to build a feature piece by piece: first the popup UI, then the background logic, then the storage. This fragmented approach often leads to architectural mismatches and bugs that are painful to untangle.

The solution is the "Master Prompt." Instead of asking for a file, you ask for a complete, self-contained feature. You describe the user's journey from click to result, and you task the AI with orchestrating all the necessary components: manifest updates, UI changes, background processing, and storage management. This holistic approach ensures all the moving parts are designed to work together from the very first line of code.

### The "Full Feature" Prompt: Building a "Read Later" Saver

Let's build a common and powerful feature: a one-click "Read Later" saver. The user highlights text on a page, clicks the extension icon, and can save that snippet to a list for later review. This requires coordination between a content script (to get the selection), the popup (to trigger the save), the background service worker (to handle the logic), and storage (to persist the data).

Here is the master prompt you would feed into Cursor's Composer:

> **Master Prompt Example:**
> "Implement a complete 'Save Selection to Read Later' feature for a Chrome Extension using Manifest V3. This feature requires coordination across multiple files:
>
> 1.  **Content Script (`content.js`):** Create a function that listens for a message from the background script. When triggered, it must get the currently selected text on the page (`window.getSelection().toString()`). If text is selected, return it. If not, return a message indicating no selection.
>
> 2.  **Background Service Worker (`background.js`):** Create a listener for the browser action's `onClicked` event. When the icon is clicked, it should:
>     *   First, query the active tab using `chrome.tabs.query`.
>     *   Send a message to the content script on that tab to request the selected text.
>     *   Wait for the response. If text is received, it should generate a unique ID for the item (e.g., using `Date.now()`), and save the text, the full page URL, and the timestamp to `chrome.storage.local`.
>     *   If no text is selected, do nothing.
>
> 3.  **Popup UI (`popup.html` & `popup.js`):** The popup should display a list of all items saved in `chrome.storage.local`. It needs a `chrome.storage.onChanged` listener to dynamically update the list in real-time whenever a new item is saved by the background script. Each list item should display a snippet of the saved text and be a clickable link to the original URL.
>
> 4.  **Manifest (`manifest.json`):** Ensure the manifest is updated with the necessary permissions: `["storage", "activeTab", "scripting"]`. The `action` should be configured correctly.
>
> The final output must be a set of four files that work together seamlessly. Prioritize a robust data flow using `chrome.runtime.sendMessage` and `chrome.runtime.onMessage`. Ensure the popup state is always in sync with the stored data."

**Why this works:** This prompt forces the AI to become a system architect. It can't just generate a disconnected `popup.html` file. It has to reason about the data lifecycle: selection -> message -> background processing -> storage -> UI update. This single prompt will generate a cohesive, functional feature that is significantly more robust than what you'd get by piecing together separate, smaller requests.

### Iterative Refinement: Evolving Your Feature with Composer

Once the master feature is generated, the real power of an AI-native editor like Cursor shines in the iterative phase. The Composer mode allows you to maintain context and request changes without starting over. You're not just prompting; you're collaborating.

Let's say the initial feature is working, but you realize a crucial piece of user feedback is missing. You need to know when an item has been successfully saved without having to open the popup. You can simply add a follow-up prompt in the Composer chat:

> **Follow-up Prompt:**
> "Great. Now, add a badge counter to the extension icon. When a new item is saved to storage, update the badge text with the total number of saved items. The badge should be cleared (set to an empty string) if the user manually clears their saved items, which we'll add a button for later. Make sure the badge updates instantly across all open windows."

The AI, having the full context of the generated code, will now modify `background.js` to add a `chrome.storage.onChanged` listener specifically for the badge. It will also update `popup.js` to include the logic for clearing items and updating the badge accordingly. This iterative process—**generate, test, refine**—is how you build complex applications efficiently. You stay in the flow, guiding the AI rather than constantly switching context to write boilerplate.

### Security Best Practices: The AI Security Audit

In 2025, security can't be an afterthought. A common vulnerability in extensions, especially those handling user data, is Cross-Site Scripting (XSS). If your popup or content script takes data from storage and injects it directly into the DOM using `innerHTML`, you're creating a potential attack vector.

Before you consider a feature "done," run a dedicated security audit prompt. This is a non-negotiable step in a professional workflow.

> **Security Audit Prompt:**
> "Review the entire 'Read Later' feature code we just generated. Specifically, analyze it for potential security vulnerabilities. Your primary focus should be on Cross-Site Scripting (XSS) in the `popup.js` file. The popup reads text from `chrome.storage.local` and displays it. If a malicious user somehow saved a script tag as the selected text, would it execute?
>
> Identify any instances where user-controlled data is written to the DOM using `innerHTML` or similar unsafe methods. Refactor the code to use safe DOM manipulation methods like `textContent` or `createElement` to prevent script injection. Provide a summary of the changes made to mitigate these risks."

**Why this is a golden nugget:** This prompt transforms the AI from a code generator into a security partner. It explicitly asks for a vulnerability assessment and a fix. Using `textContent` instead of `innerHTML` is a simple but critical distinction that this prompt will enforce, saving you from a potentially disastrous security flaw. It's a pattern you should adopt for any feature that handles and displays external data.

## Conclusion: Streamlining Your Workflow

You've journeyed from a simple idea to a fully-fledged, multi-file Chrome extension, all while leveraging the power of AI to manage the complex architecture. We started by establishing a solid foundation with a robust `manifest.json`, then moved into building responsive UIs and creating secure, bi-directional communication channels between your popup and background scripts. The core of this process isn't just about generating code; it's about using precise, context-rich prompts to act as a senior developer guiding a junior. This approach transforms a daunting task into a manageable, even enjoyable, workflow.

### From Code Writer to System Architect

This shift represents a fundamental change in the developer's role. Instead of getting lost in the minutiae of `chrome.runtime.sendMessage` syntax, you're now focused on the higher-level data flow: what information needs to be passed, when, and why? The AI handles the boilerplate, but more importantly, it enforces best practices like handling ephemeral service workers and avoiding security pitfalls like DOM-based XSS vulnerabilities. A key "golden nugget" from this process is to always prompt the AI to "sanitize all dynamic content using `textContent` instead of `innerHTML`"—a simple instruction that prevents one of the most common and dangerous extension vulnerabilities. You're no longer just a writer of lines; you're the architect of a secure and efficient system.

### Your Next Steps: The Prompt Library

To make this power immediately accessible, we've compiled every prompt from this guide into a single, downloadable resource. This library is designed for quick reference, allowing you to copy, paste, and customize these battle-tested prompts for your next project without re-reading the entire article. It's your cheat sheet for rapid extension development.

[**Download the Complete Chrome Extension Prompt Library**]

The future of development is a partnership. By mastering the art of the prompt, you've gained a co-pilot that can navigate the ever-changing landscape of web APIs and platform updates, ensuring you can build what matters, faster and more securely than ever before.


### Critical Warning

<div class="nugget-box blue-box">
    <h4>The Golden Rule of Cursor Extensions</h4>
    <p>Always create a `.cursorrules` file in your project root to define the Manifest V3 architecture and file structure. This prevents the AI from generating deprecated V2 code or mixing DOM logic into background service workers. It acts as a persistent senior developer guide for every prompt you run.</p>
</div>


## Frequently Asked Questions
**Q: Why is Cursor better than VS Code for Chrome extensions**

Cursor's Composer feature allows you to modify multiple files simultaneously (manifest.json, background.js, content.js) based on a single prompt, maintaining consistency across the entire project structure

**Q: What is the most common error in AI-generated extensions**

Attempting to use DOM APIs like document.querySelector inside the background service worker, which is strictly forbidden in Manifest V3

**Q: How do I enforce Manifest V3 standards in Cursor**

Use the .cursorrules file to explicitly instruct the AI to adhere to V3 standards and use service workers instead of background pages


<script type="application/ld+json">
{"@context": "https://schema.org", "@graph": [{"@type": "TechArticle", "headline": "Best AI Prompts for Chrome Extension Development with Cursor (2026 Guide)", "dateModified": "2026-01-05", "keywords": "Cursor AI prompts, Chrome extension development, Manifest V3 AI, AI coding assistant, extension boilerplate, Cursor Composer, Chrome dev tools 2026", "author": {"@type": "Organization", "name": "Editorial Team"}, "mainEntityOfPage": {"@type": "WebPage", "@id": "https://0portfolio.com/best-ai-prompts-for-chrome-extension-development-with-cursor"}}, {"@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "Why is Cursor better than VS Code for Chrome extensions", "acceptedAnswer": {"@type": "Answer", "text": "Cursor's Composer feature allows you to modify multiple files simultaneously (manifest.json, background.js, content.js) based on a single prompt, maintaining consistency across the entire project structure"}}, {"@type": "Question", "name": "What is the most common error in AI-generated extensions", "acceptedAnswer": {"@type": "Answer", "text": "Attempting to use DOM APIs like document.querySelector inside the background service worker, which is strictly forbidden in Manifest V3"}}, {"@type": "Question", "name": "How do I enforce Manifest V3 standards in Cursor", "acceptedAnswer": {"@type": "Answer", "text": "Use the .cursorrules file to explicitly instruct the AI to adhere to V3 standards and use service workers instead of background pages"}}]}]}
</script>

Stay ahead of the curve.

Join 150k+ engineers receiving weekly deep dives on AI workflows, tools, and prompt engineering.

AIUnpacker

AIUnpacker Editorial Team

Verified

Collective of engineers, researchers, and AI practitioners dedicated to providing unbiased, technically accurate analysis of the AI ecosystem.

Reading Best AI Prompts for Chrome Extension Development with Cursor

250+ Job Search & Interview Prompts

Master your job search and ace interviews with AI-powered prompts.