Let's talk
Menu

Product engineering / Browser

Extensions built for the modern browser.

Drag or use arrow keys to orbit

Chrome extensions

Manifest V3 extensions that work with changing websites, constrained permissions, and store review.

What we build

Useful from
day one.

Manifest V3TypeScriptChrome APIsReact

MV3 architecture

Service workers, messaging, storage, and permissions are designed for the current platform.

Defensive page integration

Content scripts tolerate DOM change and isolate extension behavior from the host page.

Store-ready delivery

Packaging, policy review, analytics, and updates are handled through release.

The route to production

Clear steps.
Visible progress.

01

Discover

We map the real workflow, risks, users, and success measure before choosing an implementation.

02

Build

Working software lands in visible increments, with the hardest assumptions tested first.

03

Prove

We validate against production-shaped data, failure paths, performance, and real use.

04

Ship

Deployment, monitoring, documentation, and a clean handover are part of the build.

View all services ↗

Verified client reviews

In their words.

“Very knowledgeable. Deployed my project successfully and was kind and patient throughout.”
Sahil GuptaNew Delhi, India · 5.0 ★
“Rapid and great work, with high technical knowledge. Highly recommend.”
Andy WaughCharlestown, Australia · 5.0 ★

Before you ask

Questions,
answered.

Is Manifest V2 still an option?

No. Chrome has moved through disabling and then turning off V2 extensions for the general user base, the Web Store stopped accepting new V2 submissions in 2022, and the enterprise policy that let managed environments keep running them has expired. If your extension is still on V2, it is not about to break — for most users it has already stopped loading.

Can you just bump manifest_version from 2 to 3?

The edit takes minutes and only makes the real problems compile. V3 replaces the always-on background page with an ephemeral service worker, so state kept in memory has to move to chrome.storage, timers move to the alarms API, and blocking webRequest becomes declarativeNetRequest. Change the number without moving the state and the extension will work in your testing and fail silently for a share of your users.

Why does our extension work for us and break for some users?

Almost always the service worker. It is terminated whenever Chrome decides it is idle, and anything held in a module-level variable goes with it. On your machine the worker is warm because you are actively developing; on a user's machine it is cold. The fix is to treat storage as the source of truth, rebuild state on wake, and test deliberately against a cold worker.

How do you keep content scripts working when the host site changes?

By assuming it will. Selectors are written to tolerate markup churn, the extension's behaviour is isolated from the page's own scripts and styles, and a missing element degrades into a disabled feature instead of a thrown error in someone's console. Sites get redesigned; an extension that treats the DOM as a contract breaks the week they ship.

Our extension was rejected. Can you get it through?

Usually, once the actual cause is identified. The common ones are broad host permissions the extension does not need, a privacy policy that does not cover everything the manifest can touch, remotely hosted code that V3 bans, and a listing whose stated purpose is wider or narrower than the code. Nearly all of them reduce to the same thing: your permissions, your code and your listing have to agree.

How do you reduce the permissions we ask for?

List the specific domains the extension acts on in host_permissions instead of requesting all-sites access. Use activeTab where it only needs the tab the user clicked, so access is granted per use. Move anything an optional feature needs into optional_permissions and request it at the moment it is used. Every permission removed is one fewer thing a reviewer has to justify approving.

Do we need a privacy policy?

If anything leaves the browser — error reports, analytics, auth tokens — yes, along with completed data-use disclosures. The frequent failure is a policy that exists but does not describe everything the permissions allow, because the reviewer compares your manifest against your policy and treats any gap as undisclosed use.

Can a rejection be appealed?

Yes. The rejection email links to an appeal form in the Developer Dashboard, and a person reads what you write. Answer the exact policy cited — quote the manifest line, the listing text or the code path and explain why it complies, naming the domains a permission covers and what the data does. A precise, policy-referenced reply works far better than a general protest, and repeatedly resubmitting while an appeal is open does not help.

What does the build involve beyond the extension itself?

Anything with accounts, a back end, synced data or AI is a product with a browser surface, not just an extension, so the work includes the service behind it, the authentication flow inside a constrained environment, and the update path. Packaging, listing assets, policy review and analytics are part of delivery rather than a separate launch task.

Who keeps it working after launch?

Somebody has to. Chrome ships updates, the sites your extension touches get redesigned, and MV3 policy keeps tightening, so an unmaintained extension tends to fail quietly for a portion of users after the next platform change. We would rather agree the maintenance arrangement up front than be called in to rescue abandoned code, which routinely costs more than building it well did.

From the journal

Further reading.

Start with a paragraph, a Figma, or a Loom.

Build this properly.Reply within one business day · one clear scope · one fixed number