
Company News
AWS Security Hub Adds Socket for Supply Chain Security
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.
@posthog/browser-common
Advanced tools
Internal shared browser utilities and extension primitives for PostHog Browser SDKs
Internal shared browser utilities and extension primitives for PostHog JavaScript SDKs. This package is published so unbundled SDK outputs can resolve it at runtime, but it is not a public API surface and does not provide compatibility guarantees outside PostHog SDK packages.
The shared extension contract includes the interface an extension implements
(Extension), the host adapter it receives (Client), and small shared runtime
primitives such as Publisher.
This contract is designed so an extension can run unchanged across major versions of the web SDK. Concrete host adapters remain owned by their SDK packages; browser-v1 and browser-v2 composition and loading integration are separate from this shared runtime.
ExtensionWhat you implement. The host calls setup once and optional dispose for final cleanup:
import type { Disposable, Extension } from '@posthog/browser-common'
export function webContext(): Extension {
let removeProperties: Disposable | undefined
return {
name: 'webContext',
setup(client) {
removeProperties = client.registerDynamicEventProperties(() => ({
$current_url: window.location.href,
}))
},
dispose() {
removeProperties?.dispose()
},
}
}
setup(client) may be async to read state before the extension is ready. Async
extensions must guard work after each await so cleanup cannot be followed by
late listener or timer installation. dispose() is synchronous, optional,
idempotent, and best-effort. Static app config goes in the constructor, not on
Client.
Anything in setup that returns a Disposable must be held by the extension
and disposed in dispose(). Use createDisposable(teardown) when adapting a
synchronous callback into idempotent teardown.
ClientWhat an extension is given in setup — the adapter shared by extensions on that host SDK instance:
distinctId, anonymousId, groups, sessioncapture(...), registerDynamicEventProperties(...), onEvent(...)onRemoteConfig(...)projectToken, sendRequest(path, init?)kv, loggerIdentity, session, and the public project token are always-ready synchronous
reads. Operations that may perform I/O, including capture, sendRequest,
and kv, are awaitable. onRemoteConfig immediately replays the latest known
success or failure and then reports subsequent outcomes. Extensions that want a
named log prefix can create a child with client.logger.createLogger('[myExtension]').
PostHog browser SDK implementations share extension registration and teardown
through ExtensionRuntime, imported from the dedicated
@posthog/browser-common/extension-runtime subpath. It reserves extension names
during setup, rolls back failed setup, and disposes extensions once in reverse
registration order without waiting for pending setup. Concrete SDKs still own
their Client adapter and SDK lifecycle hooks.
ExtensionRuntime is host infrastructure, not part of the extension-author
surface exported from the package root.
PublisherUse Publisher<T> when an extension exposes an event stream. Keep the publisher
private, expose only its listener, and dispose it with the extension:
import { Publisher, type Listener } from '@posthog/browser-common'
const changes = new Publisher<{ enabled: boolean }>()
export const onChange: Listener<{ enabled: boolean }> = changes.listener
changes.publish({ enabled: true })
changes.dispose()
Reusable browser utilities are exposed through utils/* subpaths, but they are
intentionally not re-exported from the package root or a utility barrel. Import
the exact file needed so lazy extension bundles do not pull in unrelated helpers:
import { createLogger } from '@posthog/browser-common/utils/logger'
import { formDataToQuery } from '@posthog/browser-common/utils/request-utils'
See the develop-extension skill
(.agents/skills/develop-extension/SKILL.md)
for the complete authoring and browser-v1 porting guide.
Early and internal. The package currently defines the extension and client
contracts, a shared host runtime, lifecycle helpers, and directly imported
browser utilities under utils/* subpaths.
FAQs
Internal shared browser utilities and extension primitives for PostHog Browser SDKs
The npm package @posthog/browser-common receives a total of 1,343,407 weekly downloads. As such, @posthog/browser-common popularity was classified as popular.
We found that @posthog/browser-common demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 22 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.

Research
/Security News
Popular npm packages keyv and cacheable compromised.

Security News
A misconfiguration gave three Anthropic models internet access, and one, believing it was in a simulation, shipped a credential-stealing package to PyPI.