How to Publish a Chrome Extension to the Chrome Web Store
You've built a Chrome extension — now what? The publishing process can be surprisingly confusing the first time around. This guide walks through the entire flow, from registering as a developer to passing review.
1. Register a Developer Account
Go to the Chrome Web Store Developer Dashboard and sign up as a developer.
- Sign in with your Google account
- Pay the one-time $5 registration fee (non-refundable)
- Fill in your developer profile: name, email, website, etc.
You can choose between an individual account or a group (organization) account. For personal projects, an individual account is perfectly fine.
Note for users outside the US: If your country isn't listed or the payment doesn't go through, try selecting United States as your country and entering 10001 (New York) as the ZIP code.
2. Build and Package as a ZIP
Package your extension into a ZIP file. The exact steps depend on your build tool, but in most cases you just compress the output folder after building.
# Using WXT
npm run zip
# Manual compression
cd dist && zip -r ../extension.zip .
Required files to include in the ZIP:
manifest.json- Icon files
- Build output: HTML, JS, CSS, etc.
Important: Exclude unnecessary files like node_modules, source maps, and .git.
3. Prepare Store Listing Assets
Having these ready before you upload will save you time.
Required
| Item | Spec |
|---|---|
| Extension icon | 128×128 PNG |
| Screenshots | At least 1, 1280×800 or 640×400 PNG/JPG |
| Description | Up to 132 characters (summary); detailed description separate |
| Category | Choose from Developer Tools, Productivity, etc. |
| Language | Select your primary language |
Optional
- Promotional tile image (440×280) — used if your extension gets featured
- Homepage URL
- Support URL
- Privacy policy URL (may become required depending on permissions)
4. Upload via the Dashboard
- Click "New Item" in the Developer Dashboard
- Upload your ZIP file
- After uploading, fill in the tabs:
- Store listing: description, screenshots, category
- Privacy practices: explain why each permission is needed
- Distribution: visibility and region settings
Visibility Options
- Public: Anyone can search and install it
- Unlisted: Only people with the direct link can install it (not shown in search)
- Private: Only specified users can install it (useful for testing)
If it's your first time, consider publishing as Unlisted first to verify everything looks right, then switching to Public.
5. Justify Your Permissions
For every permission declared in manifest.json, you need to explain why it's needed. A vague or incomplete justification is a common reason for rejection.
Example:
| Permission | Justification |
|---|---|
storage | Required to save user settings (API keys, theme preferences) locally |
activeTab | Required to extract information from the current tab's URL |
host_permissions | Required to make calls to external APIs |
Key principle: Only declare permissions you actually use. Unused permissions will get your submission rejected.
6. Submit for Review
Once everything is filled in, click "Submit for Review".
Review Timeline
- Typically 1–3 business days
- First-time submissions may take longer
- Sensitive permissions (e.g.,
tabs,webRequest) may trigger additional review
Common Rejection Reasons
- Unnecessary permissions — permissions in the manifest that aren't actually used
- Unclear description — it's not obvious what the extension does
- Missing privacy policy — required when handling user data
- Single-purpose violation — one extension containing unrelated features
If rejected, you'll receive a reason. Fix the issue and resubmit.
7. Publishing Updates
Updating an already-published extension is straightforward.
- Bump the
versioninmanifest.json - Build a new ZIP file
- In the Dashboard, go to the "Package" tab → "Upload New Package"
- Submit for review again
Updates go through review too, but usually faster than initial submissions. Existing users will receive the update automatically after it passes.
Tips
- Always increment the version in
manifest.json— you cannot upload a package with the same version number. - Use real screenshots of the extension in action. Mock-ups or text-only images may be rejected.
- If you're using privacy-related permissions, set up a privacy policy page in advance. A GitHub Pages or Notion page is sufficient.
- You can automate publishing via the Chrome Web Store API for CI/CD deployments. The
chrome-webstore-uploadnpm package makes this easy.
Wrap-Up
It looks complicated at first, but once you've done it, the update cycle is simply: build ZIP → upload → submit for review. The most important thing is to request only the permissions you need and clearly explain why you need each one. Get that right, and your submission will almost always sail through review.