Publishing costs a one-time $5 registration fee and usually takes under an hour of dashboard work. The part people underestimate is review: Google checks your code, your permissions, and your privacy disclosures against policy, and a first submission with sloppy answers gets rejected with a cryptic notification ID. Here is the full sequence.
1. Package your extension
- Your
manifest.jsonmust use Manifest V3 — the Chrome Web Store no longer accepts new Manifest V2 extensions. - Zip the extension so
manifest.jsonsits at the root of the zip, not inside a folder. This is a common upload error. - Remove anything that isn't needed: leftover test files, source maps, unused libraries. Reviewers read what you ship.
# from inside your extension directory: zip -r ../my-extension.zip . -x "*.git*" -x "node_modules/*"
2. Register a developer account — the only cost
- Go to the Chrome Web Store Developer Dashboard (chrome.google.com/webstore/devconsole) with the Google account you want to own the extension.
- Pay the $5 one-time registration fee. There is no per-extension or per-update charge after that.
- Enable 2-Step Verification on the account; the dashboard requires it before you can publish.
- Pick the account carefully. Transferring an extension to a different owner later is possible but painful — use a durable account, not a work address you might lose.
3. Upload and fill the store listing
- New item → upload zip. The dashboard parses your manifest and flags structural problems immediately.
- Listing tab: name, description, category, a 128×128 icon, and at least one screenshot (1280×800 or 640×400). Write the description for a human — keyword-stuffed listings are a policy violation on their own.
- Single purpose: you must state one narrow purpose, and everything the extension does has to serve it. Multiple features are fine only when they all relate to that one narrow purpose; an unrelated grab-bag risks rejection.
4. The privacy tab — the easiest place to slip up
- Justify every permission you request, one by one, in plain language. "Needed for the extension to work" is not a justification — say which feature uses the permission and why. If you can't write a convincing sentence for a permission, you probably don't need it — request the narrowest thing that works (see Purple Potassium: excessive permissions).
- Data usage disclosures: declare what user data you collect and certify you follow the data policies. These answers become the "privacy practices" shown on your public listing.
- Privacy policy URL: required if you handle user data. It must be a working, public page — open the link yourself before submitting. Free generator: privacy policy generator.
5. Choose visibility, then submit
| Visibility | Who can install | Typical use |
|---|---|---|
| Public | Anyone; searchable in the store | Normal launch |
| Unlisted | Anyone with the direct link; not searchable | Beta, client-only tools |
| Private | Trusted testers/Google Groups you specify, or your Workspace domain (admin-enabled) | Internal company tools |
All three go through review. Submit, and the item shows "pending review" in the dashboard.
6. Review: what to expect
- Most submissions come back within a few days. Broad host permissions (
<all_urls>, wide content-script matches) and powerful APIs push you into slower, deeper review — sometimes weeks. Details: how long review takes. - If you're rejected, the email cites a notification ID (Blue Argon, Purple Potassium…). Each maps to a specific policy; fix the actual violation and resubmit — resubmitting unchanged code just spends another review cycle on the same outcome. Decode yours with the free rejection decoder or the full ID reference.
- Before you submit at all, run the pre-submission checklist — it covers the checks above in order.
Already rejected? Paste the rejection email into the free decoder, or use the free triage form to get our reading of what to change — not a ruling from Google, and nobody can guarantee approval.
See also: writing permission justifications · privacy policy requirements · appealing a rejection · Why Chrome Web Store rejects extensions