Extension UI that survives the host app
Our react-content-script-injector mounts complete React components inside apps you do not control. It watches injection points, remounts UI after SPA changes, and ships with end-to-end tests running in a real browser.
The host app will change
Your injector should not disappear with it
Modern apps replace DOM fragments, navigate without a page reload, and run multiple UI variants at once. A basic content script mounts once and hopes its target stays in place. We design for continuous change.
Host changes the DOM
A route, re-render, or experiment removes the mount point.
Injector detects it
The observer recognizes a missing or changed injection point.
React UI returns
The component remounts with its React context and styles intact.
E2E guards regressions
CI replays the browser scenario before deployment.
A private runtime for the hardest part of an extension
The library stays private and is included in the extensions we deliver. You get a proven foundation without maintaining another internal framework.
Resilient mount points
We watch target elements and remount components after SPA navigation or a host re-render.
Shadow DOM
Extension styles stay out of the host page, and third-party CSS stays out of your UI.
React Portals
Modals, dropdowns, and panels keep providers, state, theme, and the complete React context.
Cleanup without duplicates
Controlled unmounting and reinjection prevent stale handlers and duplicate UI.
Flexible positioning
We place inline actions, sidebars, panels, and floating UI exactly where users work.
Visible failures
Injector failures can report page and extension context instead of waiting for a user complaint.
Real-browser testing
We test more than the component. We test the injection moment.
A unit test cannot prove that an extension found the right anchor on a real page. Our E2E scenarios load the production extension build in Chromium and verify the complete injector lifecycle.
- 01Build the production extension
- 02Load it into Chromium
- 03Replay the host-page change
- 04Assert UI, cleanup, and reinjection
Initial injection
The right component appears next to the right host element.
SPA navigation
The UI leaves, cleans up, and returns when navigation reaches a supported route.
Host re-render
The injector recovers after the host replaces its DOM fragment.
No duplicate mounts
Repeated DOM mutations never create multiple copies of the same UI.
Host variants
Known languages, layouts, and selector variants lead to the same result.
Controlled failure
A missing anchor produces a useful diagnostic signal instead of a silent failure.
From a DOM anchor to a maintainable deployment
We do not hand over a package and walk away. We design injectors, test how they behave through host changes, and maintain the integration as the host app evolves.
Map the host app
We identify stable anchors, routes, UI variants, and likely failure points.
Build the injector
We mount React UI with style isolation, context, and a controlled lifecycle.
Automate E2E coverage
We turn critical variants and regressions into browser scenarios running in CI.
Deploy and maintain
We deliver the build, update pipeline, and support when the host app changes.
Frequently asked questions
Is react-content-script-injector a public package?+
No. It is our private injector runtime, used in browser extensions we build and maintain for clients.
Can you add it to an existing extension?+
Yes. We first audit existing content scripts, mount points, and tests, then migrate injectors incrementally without rebuilding the entire extension.
Do the E2E tests use the real extension?+
Yes. The test loads the production extension build in Chromium and checks injector behavior from the user's perspective.
What happens when the host app changes its DOM?+
The runtime looks for a supported injection point and remounts the UI. If the change falls outside known variants, browser tests and error reporting help locate the regression quickly.
Building an extension on a page you do not control?
We will design injectors that handle SPA changes and protect their critical paths with E2E tests.
Who's behind this

Tomasz Dłuski
Founder & CEO
Senior Software Engineer with 10+ years of experience. Previously part of a company that scaled from 5 to 50+ engineers. Now building Optymized - a company that combines enterprise project delivery experience with own SaaS products. Maintainer of CRXJS (3.9k GitHub stars), one of the most popular tools for building browser extensions.
Let's discuss your project
Whether you need a custom browser extension, a dedicated dev team, or technical consulting - let's find the best approach together.