Manifest V3 Architecture Analysis and Environment Setup
If you want to build a micro SaaS and acquire users in the shortest time possible, Chrome Extensions (browser extensions) are undoubtedly your best choice.
Why? Because users don't need to install bulky desktop software or leave the web pages they're browsing. Your tool can directly "parasitize" their browser, providing value when they need it most (e.g., Grammarly helps rewrite English, AdBlock blocks ads, or auto-fill tools).
In this lesson, we'll start from scratch, taking you deep into Google's latest Manifest V3 architecture and building your first extension.
1. What is Manifest V3?
When developing Chrome Extensions, the most critical file is manifest.json. This is like the extension's "ID card" and "manual," telling the browser the extension's name, required permissions, and included scripts.
Google has recently fully transitioned to Manifest V3, replacing the older V2. This is a massive architectural overhaul aimed at improving:
- Security: Restricts the execution of external code to prevent malicious extensions from stealing data.
- Performance: Introduces Service Workers, replacing the memory-hogging Background Pages that used to run persistently in the background.
- Privacy: Stricter permission controls, such as using
declarativeNetRequestinstead ofwebRequestto block network requests.
[!WARNING] Deprecation Warning: Google has started forcibly removing all Manifest V2 extensions. If you come across older tutorials still using
"manifest_version": 2, skip them—they can no longer be published! This course fully adopts the latest V3 standards.
2. Core Components of an Extension
A powerful Chrome Extension typically consists of the following four core components:
- Manifest (manifest.json): Configuration file defining permissions and architecture.
- Background Script (Service Worker): The silent butler running in the background. Handles events, manages cross-page states, and even communicates with backend APIs.
- Content Scripts: The "spies" injected into target web pages. They can directly read and modify the DOM (e.g., highlighting specific words on a page in red).
- Popup / Options Page: User interfaces. The small window that pops up when clicking the top-right icon or a dedicated settings page.
These four components are isolated from each other and must communicate via Chrome's Message Passing API.
3. Hands-On: Building Your First Extension
Let’s start by creating the simplest Hello World project. Create a new folder my-first-extension on your computer and add the following files:
manifest.json
This is the only indispensable file. Paste the following code:
{
"manifest_version": 3,
"name": "Vibe Tutor's First Extension",
"version": "1.0.0",
"description": "This is my first Chrome Extension built with Vibe Tutor!",
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "icons/icon16.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
},
"permissions": [
"storage",
"activeTab"
]
}
Breakdown:
"manifest_version": 3: Declares we're using the latest standard."action": Defines what happens when users click the browser's top-right icon (here, we specifypopup.htmlto pop up)."permissions": Declares the Chrome API permissions we need. Here, we requeststorage(for saving settings) andactiveTab(to access the current tab's info).
popup.html
This is the small UI window that appears when clicking the icon—essentially a simple webpage.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
width: 300px;
padding: 16px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
h1 {
font-size: 18px;
color: #3b82f6;
}
button {
background-color: #3b82f6;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
width: 100%;
margin-top: 10px;
}
button:hover {
background-color: #2563eb;
}
</style>
</head>
<body>
<h1>Hello, Vibe Tutor!</h1>
<p>This is the prototype of your first micro SaaS.</p>
<button id="clickMeBtn">Click Me to Test</button>
<!-- Include the logic script -->
<script src="popup.js"></script>
</body>
</html>
popup.js
Adds interactivity to our button.
document.addEventListener('DOMContentLoaded', () => {
const btn = document.getElementById('clickMeBtn');
btn.addEventListener('click', () => {
alert('Awesome! You successfully triggered the button event!');
btn.innerText = "Clicked ✓";
btn.style.backgroundColor = "#10b981"; // Turns green
});
});
Prepare Icon Images
Create an icons folder in your project and add three images of different sizes (icon16.png, icon48.png, icon128.png).
Tip: If you're only testing locally, you can skip the icons—Chrome will automatically assign a default letter icon.
4. How to Install and Test Your Extension?
After creating these three files, how do we install it in the browser?
- Open Chrome and navigate to
chrome://extensions/. - Enable Developer mode in the top-right corner.
- Click Load unpacked in the top-left.
- Select your
my-first-extensionfolder.
Now, you'll see your extension in the list!
Click the puzzle icon 🧩 next to the address bar and "Pin" your extension to the toolbar. Click its icon, and you'll see the polished popup.html appear, with the button working as expected.
[!TIP] Development and Debugging Tips
Every time you modify HTML or JS files, you must return tochrome://extensions/and click the refresh button (⟳) at the bottom-right of your extension card for the latest code to take effect! This is the step beginners most often forget.
5. Next Challenges
Congratulations! You've completed the first step.
But in a real SaaS product, we need more than just a popup—we need the extension to "understand" the user's current webpage and even automate tasks in the background.
In the next chapter, we'll explore the biggest change in Manifest V3—Background Service Workers—and see what superpowers this invisible butler can bring us!
Extension Files
my-extension/
├── manifest.json # Extension configuration (required)
├── background.js # Service worker (MV3) or background page (MV2)
├── content.js # Injected into web pages
├── popup.html # Browser action popup
├── popup.js # Popup logic
├── options.html # Options page
├── options.js # Options logic
├── styles.css # Shared styles
├── icons/
│ ├── icon16.png
│ ├── icon48.png
│ └── icon128.png
└── _locales/
├── en/
│ └── messages.json # English strings
└── zh_TW/
└── messages.json # Traditional Chinese strings
Manifest V3 vs V2
| Feature | Manifest V2 | Manifest V3 |
|---------|------------|------------|
| Background | Persistent page | Event-driven service worker |
| API access | chrome.webRequest (blocking) | chrome.declarativeNetRequest |
| Remote code | Allowed | Not allowed (security) |
| Execution | Background page | Service worker (terminates) |
| Action API | chrome.browserAction | chrome.action (unified) |
| Host permissions | Requested in manifest | Requested at runtime (optional) |
| Security | Lower | Higher |
Chrome Extension APIs
| API | Purpose |
|-----|---------|
| chrome.action | Browser toolbar button, badge, popup |
| chrome.runtime | Extension lifecycle, messaging, manifest |
| chrome.storage | Local and sync storage (persistent) |
| chrome.tabs | Create, query, update browser tabs |
| chrome.windows | Create, manage browser windows |
| chrome.alarms | Scheduled tasks (replaces setTimeout) |
| chrome.notifications | Desktop notifications |
| chrome.contextMenus | Right-click menu items |
| chrome.commands | Keyboard shortcuts |
| chrome.i18n | Internationalization |
| chrome.scripting | Inject scripts programmatically |
| chrome.declarativeNetRequest | Block/modify network requests |
Messaging Architecture
Content Script ←→ Background Service Worker ←→ Popup / Options
↕ ↕
Web Page Extension Storage (chrome.storage)
Messaging Methods
| Method | Direction | Use Case |
|--------|-----------|----------|
| chrome.runtime.sendMessage() | Any → Background | One-time request |
| chrome.runtime.onMessage | Background receives | Handle incoming messages |
| chrome.tabs.sendMessage() | Background → Content | Send message to specific tab |
| chrome.runtime.connect() | Any ↔ Background | Long-lived connection (port) |
| port.postMessage() | Both directions | Streaming messages |
| port.onDisconnect | Cleanup | Handle disconnection |
Internationalization (i18n)
// _locales/en/messages.json
{
"extensionName": {
"message": "Camping Spot Finder",
"description": "Extension name"
},
"extensionDescription": {
"message": "Find the best camping spots near you",
"description": "Extension description"
},
"saveButton": {
"message": "Save to My Spots",
"description": "Button text for saving a campsite"
},
"noSpotsFound": {
"message": "No camping spots found in this area",
"description": "Empty state message"
}
}
// In extension code
chrome.i18n.getMessage('saveButton'); // → "Save to My Spots"
Permissions
{
"permissions": [
"storage",
"alarms",
"notifications"
],
"host_permissions": [
"*://api.campingspots.com/*"
],
"optional_permissions": [
"geolocation"
]
}
| Permission | Access |
|------------|--------|
| storage | chrome.storage API |
| alarms | chrome.alarms for scheduling |
| notifications | Desktop notifications |
| geolocation | User's location (optional, requested at runtime) |
| host_permissions | Which websites the extension can access |
Summary
Chrome extensions package HTML, JavaScript, and CSS into a browser-integrated application. Manifest V3 is the current standard with service workers replacing background pages. Master the architecture: manifest, service worker, content scripts, popup, options, and storage.
Key takeaways:
- Manifest V3: service worker (ephemeral) instead of background page (persistent)
- Core files: manifest.json, background.js, content.js, popup.html, options.html
- Messaging: runtime.sendMessage / onMessage for cross-context communication
- Storage: chrome.storage.sync (syncs across devices) and .local (local only)
- i18n: _locales/*/messages.json for internationalization
- Permissions: request minimal permissions, use optional permissions when possible
- Host permissions: specify which URLs the extension can access
- Action API: unified browser action for toolbar button, badge, popup
What's Next: Background Service Workers
The next chapter dives deep into background service workers — lifecycle, event-driven programming, alarms API, and state persistence.