GitHub - blueyferg/webext-ship-kit: Config-driven build and pre-submission validation for shipping one Manifest V3 browser extension to Chrome, Edge and Firefox. · GitHub
/" data-turbo-transient="true" />
Skip to content
Search or jump to...
Search code, repositories, users, issues, pull requests...
-->
Search
Clear
Search syntax tips
Provide feedback
--><br>We read every piece of feedback, and take your input very seriously.
Include my email address so I can be contacted
Cancel
Submit feedback
Saved searches
Use saved searches to filter your results more quickly
-->
Name
Query
To see all available qualifiers, see our documentation.
Cancel
Create saved search
Sign in
/;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up
Appearance settings
Resetting focus
You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
{{ message }}
blueyferg
webext-ship-kit
Public
Notifications<br>You must be signed in to change notification settings
Fork
Star
main
BranchesTags
Go to file
CodeOpen more actions menu
Folders and files<br>NameNameLast commit message<br>Last commit date<br>Latest commit
History<br>2 Commits<br>2 Commits
bin
bin
examples/minimal
examples/minimal
lib
lib
test
test
.gitignore
.gitignore
LICENSE
LICENSE
README.md
README.md
extship.config.example.json
extship.config.example.json
package.json
package.json
View all files
Repository files navigation
webext-ship-kit
Config-driven build and pre-submission validation for shipping one Manifest V3<br>browser extension source tree to Chrome, Edge and Firefox as three<br>store-ready zips.
Generalized from the tooling behind a real extension that shipped to all<br>three stores. The specific traps it exists to catch — and a field-by-field<br>walkthrough of each store's actual submission form — are written up in<br>GUIDE.md, included in the paid package on Gumroad.<br>This repository has the free build/verify tooling only.
No dependencies. Requires Node 16+ and the zip/unzip command-line tools<br>(preinstalled on macOS and Linux; on Windows, use WSL or Git Bash).
What it does
extship build — reads one manifest + source tree, applies your<br>declared per-store overrides (the Firefox-only gecko block, a shortened<br>name, whatever else you configure), and produces three zips in dist/.
extship verify — checks the build output against the class of things<br>a store validator rejects: package structure, per-store manifest field<br>limits, Firefox's required browser_specific_settings fields, every file<br>the manifest references actually being in the zip, asset dimensions, a<br>network-call grep (for anyone making a "verified zero-network" privacy<br>claim the way the original extension did), and length limits on your<br>listing copy.
extship init — scaffolds a config by walking an existing<br>manifest.json for the files it references, so you're editing a starting<br>point instead of writing one from scratch.
Quickstart
cd your-extension<br>node /path/to/webext-ship-kit/bin/extship.js init<br>node /path/to/webext-ship-kit/bin/extship.js build<br>node /path/to/webext-ship-kit/bin/extship.js verify
Or install it so the extship command is on your PATH — either<br>npm link from this directory, or copy bin/ and lib/ into your own<br>project and add "extship": "node ./tools/webext-ship-kit/bin/extship.js"<br>as an npm script.
A complete working example — a tiny fixture extension plus a config<br>exercising every check — is in examples/minimal. Run<br>npm test from this directory to build and verify it.
Config reference
extship.config.json (see extship.config.example.json<br>for a full copy-pasteable example):
Field<br>Default<br>Meaning
manifestPath<br>"manifest.json"<br>Path to the shared source manifest, relative to the config file.
packageName<br>(required)<br>Used in the output filename: {packageName}-{version}-{target}.zip. Version is read from the manifest's version field.
outDir<br>"dist"<br>Where finished zips land.
buildDir<br>"build"<br>Scratch directory holding the unzipped per-target trees; safe to gitignore.
files<br>["manifest.json"]<br>What ships. Literal paths, or a directory path ending in /** to include everything under it recursively. Anything not listed here stays out of every package, regardless of what's in the source tree.
targets<br>["chrome", "edge", "firefox"]<br>Which stores to build for.
overrides..manifestPatch<br>Deep-merged onto the base manifest for that target only. This is how the Firefox gecko block and a shortened Firefox name get injected without touching the shared manifest — see trap 3 in GUIDE.md.
limits..name / .description<br>Chrome 75/132, Firefox name 45<br>{ min, max } character limits checked against manifest.json fields in the built package. Don't put a store's listing-page copy limits here — those are a separate web form; use listingChecks instead.
assets<br>[]<br>Array of { path, width, height, targets?, required?,...