I was struggling with this for many hours recently. I have a sort of unique setup, but maybe the solution I arrived at will light a bulb for you. I have a Flask "pseudo"-monorepo with several apps contained in their own root-level directories. I have NPM workspaces configured in this app, and so have two levels of package.json files: one at the root and one in each app. npm install placed the @rollup/plugin-inject package in the root-level package.json, so the package-lock.json never reflected the fact that my apps actually needed it. I tried everything under the sun before I figured this out, and eventually I just placed "devDependencies": { "@rollup/plugin-inject": "^5.0.5" } in my apps' package.json, removed window.$ = window.jquery = jquery from the entry point I was feeding Vite, and violà! — Jquery had been successfully injected.