How to Publish a Chrome Extension to the Chrome Web Store
A step-by-step guide to publishing your first Chrome extension: registering a developer account, packaging your code, completing the store listing, and passing review.
Shipping a Chrome extension is mostly a paperwork problem. The code is the easy part: the friction is the developer account, the packaging rules, and the review questions about permissions and data. This guide walks the whole path, from a working folder of code to a live listing, so nothing surprises you on submission day.
Before you start
Have these ready before you open the dashboard. Gathering them up front turns a multi-day back-and-forth into a single sitting.
- A Google account you are happy to tie to your developer identity. For anything beyond a personal toy, use a dedicated account or a Google Workspace account, not your main personal inbox.
- A working extension built on Manifest V3. Manifest V2 is no longer accepted for new submissions, so new extensions must target V3.
- A 128x128 PNG icon, plus at least one screenshot (1280x800 or 640x400).
- A one-line summary, a longer description, and a category.
- A privacy policy URL if your extension handles any user data (most do).
- The $5 one-time developer registration fee and a card to pay it.
Step 1: Register a developer account
Go to the Chrome Web Store Developer Dashboard and sign in. The first time, you pay a one-time $5 USD registration fee that covers your account for all the extensions you ever publish. It exists mostly to deter spam.
While you are there, complete your account verification: a contact email (verified) and, if you plan to publish under a brand, set up a group publisher so the listing shows your organization rather than a personal name.
Step 2: Get your manifest right
Your manifest.json is the contract the store reviews against. Two fields matter most for a clean first review: version and permissions.
{
"manifest_version": 3,
"name": "My Extension",
"version": "1.0.0",
"description": "A short, accurate description of what it does.",
"icons": { "16": "icons/16.png", "48": "icons/48.png", "128": "icons/128.png" },
"action": { "default_popup": "popup.html" },
"permissions": ["storage"],
"host_permissions": ["https://*.example.com/*"]
}
The single most common reason a first submission stalls is over-broad permissions. Request only what you use, prefer narrow host_permissions over <all_urls>, and lean on activeTab when you only need access on click. Every permission you list becomes a question you have to justify later, and a scarier install warning for users.
Step 3: Package the extension
The store wants a ZIP file whose root contains manifest.json directly, not a parent folder.
# From inside your extension's build output directory:
zip -r ../my-extension.zip . -x "*.git*" "node_modules/*"
Verify the ZIP by unzipping it somewhere fresh and confirming manifest.json sits at the top level. If you ship a build step (bundler, TypeScript, framework), zip the compiled output, never your source directory.
Step 4: Create the store listing
In the dashboard, choose Add new item and upload your ZIP. You will then fill out the listing across a few tabs.
| Section | What it asks for |
|---|---|
| Store listing | Name, summary, detailed description, category, language, icon, screenshots |
| Privacy | Single purpose, per-permission justifications, data-use disclosures, privacy policy URL |
| Distribution | Visibility (public / unlisted / private), regions, and pricing |
Take the privacy tab seriously. You declare a single purpose for the extension, justify each permission in plain language, and disclose what data you collect and how it is used. Reviewers read these. Vague or contradictory answers are a fast path to rejection.
Step 5: Choose visibility and submit
Pick your visibility before you submit:
- Public lists you in search and category pages.
- Unlisted is reachable by direct link only, which is ideal for a soft launch or beta.
- Private restricts install to specific testers or your Workspace org.
When everything is filled in, click Submit for review. A new extension typically clears review in anywhere from a few hours to a few days; sensitive permissions or a large code surface can push it longer. You cannot speed it up, so submit with buffer before any launch date.
Step 6: After approval, plan your updates
Once you are live, updates are simple: bump the version in manifest.json (it must always increase), re-zip, upload a new package, and submit again. Users get the update automatically over the following hours.
A few habits keep future reviews smooth:
- Never reuse a version number. Chrome rejects a package whose version is not higher than the published one.
- Keep permissions stable. Adding a sensitive permission in an update can trigger a fresh, slower review and re-prompt users.
- Write real release notes. They build trust and help reviewers understand the diff.
A quick pre-submission checklist
- Manifest V3, with an accurate
name,description, and an increasingversion. - Only the permissions you actually use, justified in plain language.
- 128x128 icon and at least one screenshot at the right resolution.
- Privacy policy URL live and reachable, matching your data disclosures.
- ZIP with
manifest.jsonat the root, built from compiled output.
Get your first users on launch day
Passing review is the start, not the finish. A brand-new listing has no reviews, no ranking signal, and no audience. Launching it somewhere with an engaged community gives you those first installs and that first feedback loop.
When your extension is live, submit it to ExtensionLaunch to put it in front of people who are actively looking for new extensions to try, and to earn a fast, linkable page that helps people discover and compare it. Next, read how to optimize your Chrome Web Store listing so those first visitors actually convert into installs.