Every Chrome extension I've built starts the same way. I need to store some user preferences. I need the popup to talk to the background script. I need to check if the user granted a permission before I call an API that'll throw if they didn't.
And every time, I'd write the same wrapper around chrome.storage, the same message-passing boilerplate, the same permission checks. Slightly different each time. Slightly broken in new ways each time.
After 18 extensions and roughly the tenth time copy-pasting a storage helper between repos, I finally extracted it all into three packages and a documentation site. Sharing it here because I wish this existed when I started.
The packages
All three are TypeScript, ship ESM + CJS, and have actual tests (not "tests").
@theluckystrike/webext-storage
Typed storage with schema validation. You define your shape once, and every get and set call is type-safe from that point forward.
``import { defineSchema, createStorage } from '@theluckystrike/webext-storage'
const schema = defineSchema({
theme: 'dark',
count: 0,
notifications: true
})
const storage = createStorage({ schema, area: 'local' })
// theme is typed as string, count as number, etc.
const theme = await storage.get('theme')
// this would be a type error:
// await storage.get('nonexistent')`
No more chrome.storage.local.get(['theme'], (result) => { ... }) with zero type information and a callback that silently gives you undefined when you typo a key name.`
27 tests. CI on Node 18 and 20.
@theluckystrike/webext-messaging
Promise-based typed message passing between extension contexts. If you've ever debugged a chrome.runtime.sendMessage call where the response just... never comes back, you know why this exists.
The documentation
This is the part that took the most work honestly. I wrote a complete Chrome extension development guide 232 articles covering permissions, API reference, MV3 migration, architecture patterns, publishing, the works.
Everything targets Manifest V3 and Chrome 120+. No leftover MV2 patterns. No chrome.browserAction in code examples.
No chrome.extension.getBackgroundPage() nostalgia.
The whole thing lives at theluckystrike.github.io/chrome-extension-guide.
The honest part
The first draft was rough. I ran a systematic audit and found 353 factual errors β wrong API signatures, incorrect permission requirements, even a few completely made-up API methods
(chrome.favicons.get() is not a thing, past me).
After fixing all of those, I ran a second independent review that checked every code example against the actual developer.chrome.com docs.
It came back 9.5/10. The remaining issue is one inaccurate permission warning description in the tabs article.
I'm mentioning this because if you're writing technical documentation, audit it. First drafts lie to you with confidence.Using them together
Here's what a typical extension setup looks like with all three.
Links
Guide: theluckystrike.github.io/chrome-extension-guide
Storage:
github.com/theluckystrike/webext-storage
Messaging:
github.com/theluckystrike/webext-messaging
Permissions:
github.com/theluckystrike/webext-permissions
If you build Chrome extensions and any of this saves you time, a star on the repos would help other devs find it. And if you spot something wrong in the guide, issues are open I clearly can't catch everything on my own.
Top comments (0)