feat(react): add slim entrypoint for tree-shakeable usage without posthog-js runtime dependency#3284
Open
dustinbyrne wants to merge 6 commits intomainfrom
Open
feat(react): add slim entrypoint for tree-shakeable usage without posthog-js runtime dependency#3284dustinbyrne wants to merge 6 commits intomainfrom
dustinbyrne wants to merge 6 commits intomainfrom
Conversation
…thog-js runtime dependency
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
📝 No Changeset FoundThis PR doesn't include a changeset. A changeset (and the release label) is required to release a new version. How to add a changesetRun this command and follow the prompts: pnpm changesetRemember: Never use |
Contributor
Contributor
|
Size Change: +1.8 kB (+0.03%) Total Size: 6.65 MB
ℹ️ View Unchanged
|
Contributor
Important Files Changed
Prompt To Fix All With AIThis is a comment left during a code review.
Path: packages/react/src/slim.ts
Line: 3-5
Comment:
**Slim bundle's "no posthog-js runtime" guarantee is fragile via the context barrel**
`export * from './hooks'` and `export * from './components'` both route through hooks/components that internally `import { PostHog, PostHogContext } from '../context'`. The `context/index.ts` barrel does `export * from './PostHogProvider'`, pulling the full `PostHogProvider.tsx` into the slim bundle's module graph.
Right now this is safe because `PostHogProvider.tsx`'s only `posthog-js` reference is `import type { PostHogConfig }` (type-only). But if that file ever gains a runtime `posthog-js` import (e.g., someone reverts the `import type` change), tree-shaking will be the only thing standing between the slim bundle and a `posthog-js` runtime dependency — silently and without any build error.
Consider adding a simple CI assertion (e.g., grepping the compiled `dist/esm/slim/index.js` for `require('posthog-js')` / `from 'posthog-js'`) to make this guarantee explicit and detectable in CI. Alternatively, restructure `context/index.ts` so the slim bundle's imports don't traverse through the full `PostHogProvider` barrel path.
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: packages/react/src/context/PostHogContext.ts
Line: 12-17
Comment:
**Context default casts `undefined` to `PostHog`, masking a runtime crash in the slim bundle**
When the slim entrypoint is used and no `PostHogProvider` is mounted, `getDefaultPostHogInstance()` returns `undefined` (no `setDefaultPostHogInstance` is ever called). The `as PostHog` cast suppresses TypeScript's type error, so any consumer calling `usePostHog()` outside a provider will receive `undefined` at runtime but believe they hold a valid `PostHog` instance. The first method call (`client.capture(...)`, `client.captureException(...)`, etc.) will throw `TypeError: Cannot read properties of undefined`.
A safer default would surface the problem at the point where context is consumed rather than when a method is eventually called:
```ts
get client() {
const instance = getDefaultPostHogInstance()
if (!instance) {
throw new Error(
'[PostHog.js] No PostHog client found. Wrap your component tree in <PostHogProvider client={...}>.'
)
}
return instance
},
```
Or at minimum, drop the `as PostHog` cast and let the type be `PostHog | undefined`, forcing callers to guard against it.
How can I resolve this? If you propose a fix, please make it concise.Reviews (2): Last reviewed commit: "chore(react): prettier" | Re-trigger Greptile |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
@posthog/reacthard-imports theposthog-jssingleton at the module level, which forces bundlers to include the full ~180KBposthog-jsbundle even when users want to use the slim ~94KB bundle. There is no way to use the React SDK with a tree-shaken PostHog setup.Solution
Add a
@posthog/react/slimentrypoint that exports the same hooks and components but does not importposthog-jsat runtime. The slim bundle has its own dedicatedPostHogProviderthat only accepts a pre-initializedclientprop — noapiKey, no default instance, no casts.Key changes
src/context/posthog-default.ts— get/set for the default PostHog instancesrc/context/PostHogProviderSlim.tsx— minimal provider that only acceptsclient, used by the slim bundlesrc/slim.ts— slim entrypoint that cherry-picks exports and swaps in the slim providersrc/index.ts— importsposthog-jsand registers it as the default instancegetDefaultPostHogInstance()instead of directposthogJsimport; lazy getter on context default to handle module evaluation orderimport typewhere only types were neededslim/package.jsonUsage
Backwards compatibility
@posthog/reactentrypoint is unchanged in behaviorapiKeyprop continues to work as beforeclient—apiKeyis not available (TypeScript enforces this)