missing `pkg.exports` in package.json
It is not possible to use posthog-js package within an ESM project in Node environment, because the package.json is missing the exports property (https://publint.dev/[email protected]) while Node doesn't read the module property and thus it fails to treat it as an ES package.
You get the following error if you try:
import { PostHogProvider } from "posthog-js/react/dist/esm/index.js";
^^^^^^^^^^^^^^^
SyntaxError: Named export 'PostHogProvider' not found. The requested module 'posthog-js/react/dist/esm/index.js' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from 'posthog-js/react/dist/esm/index.js';
const { PostHogProvider } = pkg;
This is within a Remix Vite project, but I guess it's relevant for any ESM project that runs SSR in Node and doesn't prebundle dependencies.
I had to apply the following patch to get it working:
diff --git a/dist/es.js b/dist/es.mjs
similarity index 100%
rename from dist/es.js
rename to dist/es.mjs
diff --git a/dist/es.js.map b/dist/es.mjs.map
similarity index 100%
rename from dist/es.js.map
rename to dist/es.mjs.map
diff --git a/package.json b/package.json
index 4d35188aea0eed88a85d9c9c3a140ea10f578034..c10df882ec27ca97a29c814735f8ea53ad847dc2 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,18 @@
},
"main": "dist/module.js",
"module": "dist/es.js",
+ "exports": {
+ ".": {
+ "types": "./dist/module.d.ts",
+ "import": "./dist/es.mjs",
+ "require": "./dist/module.js"
+ },
+ "./react": {
+ "types": "./react/dist/types/index.d.ts",
+ "import": "./react/dist/esm/index.mjs",
+ "require": "./react/dist/umd/index.js"
+ }
+ },
"types": "dist/module.d.ts",
"files": [
"lib/*",
diff --git a/react/README.md b/react/README.md
deleted file mode 100644
index 6d2737d54f58c39c85eea2afcfb6dd583686aef9..0000000000000000000000000000000000000000
diff --git a/react/dist/esm/index.js b/react/dist/esm/index.mjs
similarity index 100%
rename from react/dist/esm/index.js
rename to react/dist/esm/index.mjs
diff --git a/react/package.json b/react/package.json
index f313bf7c1e42c7d43be66390329013fd342558a0..8932551985ed093f2f2ab25ee48cdb0543b97a71 100644
--- a/react/package.json
+++ b/react/package.json
@@ -21,6 +21,13 @@
},
"main": "dist/umd/index.js",
"module": "dist/esm/index.js",
+ "exports": {
+ ".": {
+ "types": "./dist/types/index.d.ts",
+ "import": "./dist/esm/index.mjs",
+ "require": "./dist/umd/index.js"
+ }
+ },
"types": "dist/types",
"files": [
"dist/*",
Bumping this as it's still an issue
@benjackwhite 🙏
We are currently experiencing this issue as well when we upgraded our Remix project to Vite
I used yarn patch to workaround this issue locally.
In short, I added an exports field to the main package file and renamed the ESM files from js to mjs.
This seems to have done the trick.
posthog-js-npm-1.157.2-d8e62a83b4.patch
I do think that this should be a relatively straightforward fix... it's just a case of aligning your package file with the ESM standards as documented in the Node JS docs.
However, I will not that creating a hybrid package (i.e. ESM and CJS) is a huge PITA, but using .cjs and .mjs and including the appropriate exports data should do it.
I'd offer a PR, but I haven't used Rollup, so I'm probably not the best person to do it.
@dancrumb That isn’t far off from what we’re doing at my job. There’s a little bit of extra work we have to do to make it work on our npm workspaces codebase. The main problem is that our local fix could break in a later version of posthog, and we try to keep everything pretty up to date in our app.
Encountering the same issue with posthog-js/react and Remix + Vite. Since I'm not using the feature flag feature, I found it simpler to just reimplement PostHogProvider and usePostHog. That should be more 'future-proof'.
@ekojsalim Can you post a code snippet to illustrate your solution?
@ekojsalim Can you post a code snippet to illustrate your solution?
Something like this:
import { atom, useAtomValue, useSetAtom } from "jotai";
import posthog from "posthog-js";
import { useEffect } from "react";
const postHogAtom = atom<typeof posthog | undefined>(undefined);
const PostHogProvider = ({
children,
options,
apiKey,
}: { children: React.ReactNode; options: any; apiKey: string }) => {
const setPostHogInstance = useSetAtom(postHogAtom);
useEffect(() => {
const posthogInstance = posthog.init(apiKey, options);
setPostHogInstance(posthogInstance);
}, [apiKey, options, setPostHogInstance]);
return children;
};
const usePostHog = () => useAtomValue(postHogAtom);
export { PostHogProvider, usePostHog };
We use jotai instead of more usual context/provider scheme so it might be a bit different. Baiscally, it's just taking the existing PostHogProvider and usePostHog and reimplementing it in the internal codebase. Importing posthog-js is fine but posthog-js/react breaks.
Having this issue too. Took down our site first time tried to install post hog. Vite is very popular bundler. Would be nice to have support.
How is this issue almost a year old?? They even showed you how to fix it in the second reply
Anyway, here's my solution. It's just ekojsalim's without the jotai dependency:
import posthog from 'posthog-js'
import React, { createContext, useContext, useEffect, useState } from 'react'
type PostHogType = typeof posthog | undefined
const PostHogContext = createContext<PostHogType>(undefined)
interface PostHogProviderProps {
children: React.ReactNode
options?: any
apiKey?: string
}
const PostHogProvider: React.FC<PostHogProviderProps> = ({
children,
options,
apiKey,
}) => {
const [posthogInstance, setPosthogInstance] = useState<PostHogType>(undefined)
useEffect(() => {
if (apiKey) {
const instance = posthog.init(apiKey, options)
setPosthogInstance(instance)
} else {
// If apiKey is undefined, ensure PostHog instance is not set
setPosthogInstance(undefined)
}
}, [apiKey, options])
return (
<PostHogContext.Provider value={posthogInstance}>
{children}
</PostHogContext.Provider>
)
}
const usePostHog = () => useContext(PostHogContext)
export { PostHogProvider, usePostHog }
Can anyone from Posthog confirm if this is on their radar and if there's a plan to fix it? In the year the issue has been open, we've seen https://github.com/PostHog/posthog-js/pull/1168 (autoclosed due to inactivity), https://github.com/PostHog/posthog-js/pull/1284 (autoclosed due to inactivity), and https://github.com/PostHog/posthog-js/pull/1293 (autoclosed due to inactivity). Meanwhile, https://github.com/PostHog/posthog-js/issues/1450 has also been raised, and https://github.com/PostHog/posthog.com/pull/9830 proposes telling users to manually reimplement much of posthog-js/react to work around this issue (!). I realise this is easy to say from the outside, but it increasingly looks like more of a drain on maintainers' time to leave the issue open than to resolve it!
This is a problem for me too. Here's what it looks like in a production-like app: https://github.com/iloveitaly/python-starter-template/blob/e36a3013b2a84d8c7807b38b55550d672bf78d41/web/app/configuration/posthog.tsx#L25-L30
Still happening, were in 2025!
Seriously annoying. Cant deploy without this. Update: commented out the entire posthog-js plumbing until this is fixed.
Wow, a show stopper that's been around for 1 year. We are unable to use Posthog with Astro for this reason. @rafaeelaudibert can you help?
How come this is not resolved after a year
Not sure if it's the right solution for other imports, but managed to fix my issue with imports from posthog-js/react with the following patch using pnpm patch and [email protected]:
diff --git a/package.json b/package.json
index 5cd394f287ba6ff4d707f50c22ab187c08d6dcb4..58a772f22ca12bf6ce0c91d8b6c5fe3d378223a7 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,18 @@
"react/dist/*",
"react/package.json"
],
+ "exports": {
+ ".": {
+ "types": "./dist/module.d.ts",
+ "import": "./dist/module.js",
+ "require": "./dist/main.js"
+ },
+ "./react": {
+ "types": "./react/dist/types/index.d.ts",
+ "import": "./react/dist/esm/index.js",
+ "require": "./react/dist/umd/index.js"
+ }
+ },
"dependencies": {
"core-js": "^3.38.1",
"fflate": "^0.4.8",
diff --git a/react/package.json b/react/package.json
index 5c2d9042056b3055c961cac920602c15fc3512f3..88afa41d6690b9951019235255660a442973ed0e 100644
--- a/react/package.json
+++ b/react/package.json
@@ -36,6 +36,13 @@
"optional": true
}
},
+ "exports": {
+ ".": {
+ "types": "./dist/types/index.d.ts",
+ "import": "./dist/esm/index.js",
+ "require": "./dist/umd/index.js"
+ }
+ },
"devDependencies": {
"@rollup/plugin-commonjs": "^17.0.0",
"@rollup/plugin-inject": "^4.0.2",
EDIT: This is for versions older than originally posted in the issue, the fix from https://github.com/PostHog/posthog-js/issues/908#issue-2006292774 works properly for the latest version ([email protected])
The following addition to vite.config.ts is a good workaround for us:
ssr: {
noExternal: ["posthog-js"],
},
We are using Remix. We had been using posthog-js for a long time, but our first attempt at using posthog-js/react was not successfully running server-side. Interestingly, it was building and starting, but requests to a specific URL failed. The specific URL used the hook:
import { useFeatureFlagVariantKey } from "posthog-js/react";
Error:
client.getFeatureFlag is not a function
The stack trace revealed the following source in posthog-js/react:
const client = usePostHog()
const [featureFlagVariantKey, setFeatureFlagVariantKey] = useState<string | boolean | undefined>(() =>
client.getFeatureFlag(flag)
)
The failure was only server-side, with Remix set to ssr: true, but it was not failing on the client side.
The above edit to vite.config.ts resolved it all. I assume we'll now be able to use other features of posthog-js/react on Remix.
You can use the undocumented @posthog/react and it should work with esm modules. You just have to replace your posthog-js/react imports with @posthog/react. Package is here: https://www.npmjs.com/package/@posthog/react
Let me know if it doesn't work !
@hpouillot how did you discover this / is this the unofficial-official solution? I don't want to use this if it's going to break in a month.
@iloveitaly I added this package as part of a bigger migration and kept posthog-js/react for retro-compatibility but it's the same package under the hood. We need to update the documentation but you can already use it.
I updated the doc to reflect the import changes : https://posthog.com/docs/libraries/react
I'll close this issue as it should be solved but feel free to reopen one if you see any problem
@hpouillot super helpful! Here's how I ended up implementing it in my project:
https://github.com/iloveitaly/python-starter-template/blob/master/web/app/configuration/posthog.tsx