Skip to content

Support auto-imports in Nuxt plugin#1517

Merged
webpro merged 20 commits intomainfrom
feat/nuxt-auto-imports
Mar 7, 2026
Merged

Support auto-imports in Nuxt plugin#1517
webpro merged 20 commits intomainfrom
feat/nuxt-auto-imports

Conversation

@webpro
Copy link
Member

@webpro webpro commented Feb 8, 2026

Add support for auto-imports to the Nuxt plugin, by preprocessing and squeezing import statements back into source files during compilation. This way, Knip can connect exports ↔ imports the regular way.

Caveat: requires nuxt prepare upfront to generate .nuxt definition files for imports & components collection and generate the auto imports map.

Install this version of Knip using the pkg-pr-new provided link in the first comment below.

Implementation details:

  • Update in main allows for compilers to be registered from the plugin. Asynchronously. For the Nuxt plugin, this means we have a chance to
    • Load vue/compiler-sfc to parse .vue files (fallback if loading vue/compiler-sfc fails isn't great but it's what we already had so no regression there I think).
    • Build the auto-imports map (based on e.g. .nuxt/components.d.ts and some AST traversals to collect and connect identifiers and import specifiers across scripts and templates) for the .vue (components) + .ts (composables) compilers in the same context, to be used during module resolution in TS program creation. Quite a bit of complexity, but isolated, to let core do its job normally.
  • Entry patterns are dynamically added based on app dir presence and other nuxt.config.ts options (such as serverDir)
  • Layer Nuxt config files (layers/*/nuxt.config.ts) are resolved resulting in additional entry patterns.
  • See https://feat-nuxt-auto-imports.knip.pages.dev/reference/plugins/nuxt for a static version of default patterns.
  • Caveat: despite oxc-resolver supporting TS config project references, aliased specifiers resolved from root (e.g. css: ["~/main.css"] in root nuxt.config.ts) might cause trouble, but workaround might cover bases somewhat (so far so good.. 🤞).

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 8, 2026

Open in StackBlitz

npm i https://pkg.pr.new/knip@1517
npm i https://pkg.pr.new/@knip/language-server@1517
npm i https://pkg.pr.new/@knip/mcp@1517

commit: 3d4b341

@webpro webpro marked this pull request as ready for review February 8, 2026 08:38
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Feb 8, 2026

Deploying knip with  Cloudflare Pages  Cloudflare Pages

Latest commit: 3d4b341
Status:🚫  Build failed.

View logs

@webpro webpro force-pushed the feat/nuxt-auto-imports branch 3 times, most recently from a06e22b to db777ca Compare February 10, 2026 07:28
@yschroe
Copy link

yschroe commented Feb 10, 2026

Copied from #1265:


Thanks! I tried your PR and for me it worked pretty well and I could already remove a bit of dead code from my project. 👍

A few things I noticed:

  • app.config.ts files are marked as unused (in my project this file is inside a nuxt layer folder)
  • index.ts from an auto-imported module is marked as unused (for me also inside a nuxt-layer)
  • Inside this index.ts I have registered a routeMiddleware via addRouteMiddleware. The middleware file is also marked as unused
  • I have a layers/auth/app/types/page-meta.d.ts file to augment the definePageMeta type -> this file is also marked as unused
  • Nuxt modules that are added only in the modules property in defineNuxtConfig/nuxt.config.ts are marked as unused dependencies (e.g. @nuxt/image)
  • vitest-environment-nuxt is marked as a unlisted dependency if used in vitest.config.ts (via environment: 'nuxt' - see nuxt test-utils. nuxt test-utils are listed in my devDependencies)

Not sure how much I normally would need to use a knip ignore list (if this exists) as I have never used knip outside of this one nuxt project.

@webpro
Copy link
Member Author

webpro commented Feb 10, 2026

Copied from #1265:

Thanks! I tried your PR and for me it worked pretty well and I could already remove a bit of dead code from my project. 👍

A few things I noticed:

* [app.config.ts ](https://nuxt.com/docs/4.x/directory-structure/app/app-config) files are marked as unused (in my project this file is inside a nuxt layer folder)

Will add as entry point.

* `index.ts` from an auto-imported module is marked as unused (for me also inside a nuxt-layer)

Would need a reproduction to see/fix properly.

* Inside this `index.ts` I have registered a routeMiddleware via `addRouteMiddleware`. The middleware file is also marked as unused

If a file is unused, so are its dependencies (since the file isn't even read/analyzed at all).

* I have a `layers/auth/app/types/page-meta.d.ts` file to augment the definePageMeta type -> this file is also marked as unused

* Nuxt modules that are added only in the `modules` property in `defineNuxtConfig`/`nuxt.config.ts` are marked as unused dependencies (e.g. @nuxt/image)

That's unexpected, every item of nuxt.config.ts#modules should be marked as referenced, either as string or first item if array. This is not a "layers" thing, right?

* `vitest-environment-nuxt` is marked as a unlisted dependency if used in `vitest.config.ts` (via environment: 'nuxt' - see [nuxt test-utils](https://github.com/nuxt/test-utils). nuxt test-utils are listed in my devDependencies)

I guess vitest-environment-nuxt is a dependency, but not a peer dependency of test-utils? Should it be?

Not sure how much I normally would need to use a knip ignore list (if this exists) as I have never used knip outside of this one nuxt project.

Thanks for the feedback! Is this repo public?

@yschroe
Copy link

yschroe commented Feb 10, 2026

  • Nuxt modules that are added only in the modules property in defineNuxtConfig/nuxt.config.ts are marked as unused dependencies (e.g. @nuxt/image)

That's unexpected, every item of nuxt.config.ts#modules should be marked as referenced, either as string or first item if array. This is not a "layers" thing, right?

I am using layers extensively in the project and many modules are only added to the nuxt.config.ts in a "core" layer.

* `vitest-environment-nuxt` is marked as a unlisted dependency if used in `vitest.config.ts` (via environment: 'nuxt' - see [nuxt test-utils](https://github.com/nuxt/test-utils). nuxt test-utils are listed in my devDependencies)

I guess vitest-environment-nuxt is a dependency, but not a peer dependency of test-utils? Should it be?

Good question. I have installed the module as described here and configured it similar to as described here. vitest-environment-nuxt is listed as a direct dependency of @nuxt/test-utils in its package.json. I guess using environment: 'nuxt' in vitest.config.ts somehow imports it like a transient dependency.

Thanks for the feedback! Is this repo public?

Unfortunately it is a work project that I cannot share. But I will try to work on a repro for the other points later today/this week.

@webpro
Copy link
Member Author

webpro commented Feb 10, 2026

But I will try to work on a repro for the other points later today/this week.

That'd be great! No rush, and no use for me working in the dark 😅

@yschroe
Copy link

yschroe commented Feb 10, 2026

I have created a little demo project with layers, modules, aliases etc here: https://github.com/yschroe/knip-nuxt-repro

This is the output of running knip from this PR:

Unused files (7)
app/components/AppLogo.vue                                           
layers/core/app/assets/css/main.css                                  
layers/core/app/components/LayerComponent.vue                        
layers/core/app/types/some-augmentation.d.ts                         
layers/core/modules/my-module/index.ts                               
layers/core/modules/my-module/runtime/components/Component.vue       
layers/core/modules/my-module/runtime/middleware/module-middleware.ts

Unused dependencies (3)
@iconify-json/lucide  package.json:15:6
@nuxt/ui              package.json:16:6
tailwindcss           package.json:18:6

Unlisted dependencies (1)
vitest-environment-nuxt  vitest.config.ts

I believe pretty much all of those results are false positives. The @iconify-json/lucide is probably hard to check since this is not used directly anywhere, only as a name string via UIcon.

For some reason in this repro some files are marked as unused while similar ones are okay in my real project. E.g. the module component or css import are correctly detected in my real project.

Hope this helps.

@webpro
Copy link
Member Author

webpro commented Feb 11, 2026

Thanks Yannik, this was super helpful! The main takeaway for me here was that layers should have their nuxt.config.ts fully resolved (from a Knip perspective), which has the nice side-effect of a cleaner plugin implementation. What's left is, imho, minor or edge case and at least for now for you to handle (add entry points or ignore* items manually):

Unused files (1)
layers/core/app/types/some-augmentation.d.ts
Unused dependencies (1)
@iconify-json/lucide  package.json:15:6
Unlisted dependencies (2)
@nuxt/kit                layers/core/modules/my-module/index.ts:7:9
vitest-environment-nuxt  vitest.config.ts       

@yschroe
Copy link

yschroe commented Feb 11, 2026

Thanks Yannik, this was super helpful! The main takeaway for me here was that layers should have their nuxt.config.ts fully resolved (from a Knip perspective), which has the nice side-effect of a cleaner plugin implementation. What's left is, imho, minor or edge case and at least for now for you to handle (add entry points or ignore* items manually):

Unused files (1)
layers/core/app/types/some-augmentation.d.ts
Unused dependencies (1)
@iconify-json/lucide  package.json:15:6
Unlisted dependencies (2)
@nuxt/kit                layers/core/modules/my-module/index.ts:7:9
vitest-environment-nuxt  vitest.config.ts       

Thanks for the updates, the list is a lot shorter now for me as well. 👍
I noticed though that server folders inside layers are not correctly detected anymore. I have updated the repro with an example.

@webpro
Copy link
Member Author

webpro commented Feb 11, 2026

I noticed though that server folders inside layers are not correctly detected anymore.

Resolved for layer dirs separately now.

@OrbisK
Copy link

OrbisK commented Feb 11, 2026

I have created a minimal reproduction of some false positives that I have in some of my projects.

https://github.com/OrbisK/knip-nuxt-reprod

  1. pnpm i
  2. pnpm knip
Details

Unused files (3)
app/myAlias/test.ts                                          
layers/test-layer/app/components/test-layer-app-dir.vue      
modules/local-test/runtime/app/components/local-test-comp.vue
Unresolved imports (1)
#myAlias/test  app/app.vue:2:30

@webpro
Copy link
Member Author

webpro commented Feb 11, 2026

lars@Neo ~/p/knip/exercises/knip-nuxt-reprod main ❯ pnpm install && pnpm nuxt prepare && pnpm knip

[...]

Unused files (1)
app/myAlias/test.ts
Unresolved imports (1)
#myAlias/test  app/app.vue:2:30

Not sure if this should even fly: alias: { '#myAlias': '~/myAlias' }

Knip can pass it on to TypeScript (and normal semantics will work), but you'd still need to add wildcards like { '#myAlias/*': '~/myAlias/*' }

@webpro webpro force-pushed the main branch 6 times, most recently from 23f8020 to b6afc01 Compare February 24, 2026 11:42
@yschroe
Copy link

yschroe commented Mar 5, 2026

For what it's worth, from my point of view this is good to go. I am using the pkg.pr.new version since a few weeks in my project and didn't notice any issues. At the very least it is a big improvement over the currently released version.

Or do you still see blockers on your side?

@webpro
Copy link
Member Author

webpro commented Mar 6, 2026

Yeah I guess we're good. Just trying to gather as much feedback as I can, as fixing issues in a branch is more comfortable to manage. Expect this out today or tomorrow.

@webpro webpro force-pushed the feat/nuxt-auto-imports branch from 2719122 to 3d4b341 Compare March 7, 2026 07:08
@webpro webpro merged commit 4ce27b2 into main Mar 7, 2026
68 of 70 checks passed
@webpro webpro deleted the feat/nuxt-auto-imports branch March 7, 2026 07:34
@webpro
Copy link
Member Author

webpro commented Mar 7, 2026

🚀 This pull request is included in v5.86.0. See Release 5.86.0 for release notes.

Using Knip in a commercial project? Please consider becoming a sponsor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants