# Extension points — vitejs/vite

> Canonical page: https://codevetter.com/unpack/vite/extension-points

# Extension points — vitejs/vite

Scanned commit 1544bb1b7ac92f775e9d0dea97954c99cc6cbd43 (2026-09-22). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Vite's primary extension mechanism is the plugin object — a superset of Rolldown/Rollup's, adding `config`, `configEnvironment`, `configureServer`, `configurePreviewServer`, `transformIndexHtml`, `hotUpdate`, `buildApp`, and the environment-scoping fields `applyToEnvironment`/`sharedDuringBuild`. The ordered array returned by `resolvePlugins` is the canonical insertion-point table: user `pre`, `normal` and `post` plugins are spliced at three fixed positions between internal plugins. Beyond plugins, the extension surface includes the environment factory (`dev.createEnvironment`/`build.createEnvironment`), the hot-channel/transport abstraction, the CLI shortcut table, and the `create-vite` template directory convention.
- `resolvePlugins(config, prePlugins, normalPlugins, postPlugins)` is the ordering contract: user `pre` plugins land after the alias plugins, `normal` plugins after asset/CSS/worker handling but before `definePlugin`, and `post` plugins after the glob/dynamic-import plugins — with `clientInjectionsPlugin`, `cssAnalysisPlugin` and `importAnalysisPlugin` always last. — [packages/vite/src/node/plugins/index.ts#L42-150](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/plugins/index.ts#L42-L150)
- `getSortedPluginsByHook(hookName, plugins)` implements the per-hook `order: 'pre' | 'post'` sorting with three running indices, and `createPluginHookUtils` memoises the result per hook name into `getSortedPlugins`/`getSortedPluginHooks` on the resolved config. — [packages/vite/src/node/plugins/index.ts#L152-215](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/plugins/index.ts#L152-L215)
- `applyToEnvironment(environment)` lets a plugin opt in/out per environment or return a *replacement* plugin — as the built-in alias plugin does, swapping itself for Rolldown's native `nativeAliasPlugin` when `environment.config.isBundled` and no custom resolver is present. — [packages/vite/src/node/plugins/index.ts#L60-83](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/plugins/index.ts#L60-L83) [packages/vite/src/node/plugin.ts#L227-235](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/plugin.ts#L227-L235) [packages/vite/src/node/plugin.ts#L416-435](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/plugin.ts#L416-L435)
- `perEnvironmentPlugin(name, applyToEnvironment)` is the public helper for building environment-scoped plugins, exported from the package root alongside `perEnvironmentState`. — [packages/vite/src/node/plugin.ts#L447-456](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/plugin.ts#L447-L456) [packages/vite/src/node/index.ts#L35-36](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/index.ts#L35-L36)
- `buildApp` is the multi-environment build orchestration hook: `builder.buildApp()` walks `config.getSortedPlugins('buildApp')` and interleaves `configBuilder.buildApp(builder)` just before the first `order: 'post'` hook, letting frameworks control environment build order and interdependencies. — [packages/vite/src/node/build.ts#L1859-1893](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/build.ts#L1859-L1893) [packages/vite/src/node/plugin.ts#L346](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/plugin.ts#L346)
- `hotUpdate` is the environment-aware replacement for `handleHotUpdate`: `getSortedHotUpdatePlugins(environment)` selects the plugins and each hook receives a `HotUpdateOptions` with `{type, file, timestamp, read, server, modules}` and may return a filtered module list. — [packages/vite/src/node/server/hmr.ts#L372-410](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/server/hmr.ts#L372-L410) [packages/vite/src/node/server/hmr.ts#L475-525](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/server/hmr.ts#L475-L525) [packages/vite/src/node/plugin.ts#L117](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/plugin.ts#L117)
- Environments are created through configurable factories — `environmentOptions.dev.createEnvironment(name, config, { ws })` at server start and `config.build.createEnvironment(name, config)` in `createBuilder.setupEnvironment` — with `defaultCreateDevEnvironment`/`defaultCreateClientDevEnvironment` as the built-in defaults. — [packages/vite/src/node/server/index.ts#L600-617](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/server/index.ts#L600-L617) [packages/vite/src/node/build.ts#L1918-1922](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/build.ts#L1918-L1922) [packages/vite/src/node/config.ts#L261-280](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/config.ts#L261-L280)
- The HMR transport is pluggable on both ends: server-side via `normalizeHotChannel` and `createServerHotChannel()` (exported publicly), client/runtime-side via `normalizeModuleRunnerTransport` and `createWebSocketModuleRunnerTransport` in `src/shared/moduleRunnerTransport.ts`. — [packages/vite/src/node/server/hmr.ts#L212-260](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/server/hmr.ts#L212-L260) [packages/vite/src/node/server/hmr.ts#L1166](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/server/hmr.ts#L1166) [packages/vite/src/shared/moduleRunnerTransport.ts](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/shared/moduleRunnerTransport.ts) [packages/vite/src/node/index.ts#L73](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/index.ts#L73)
- `bindCLIShortcuts({ print, customShortcuts })` accepts an array of `CLIShortcut<Server>` objects (`{ key, description, action }`) merged with the built-in table — the mechanism the CLI itself uses to add the `p` profiler toggle. — [packages/vite/src/node/shortcuts.ts#L26-196](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/shortcuts.ts#L26-L196) [packages/vite/src/node/cli.ts#L272-303](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/cli.ts#L272-L303)
- Plugin hook filtering is an extension point with its own registry: `getCachedFilterForPlugin(plugin, hookName)` builds and WeakMap-caches `createIdFilter` / `createFilterForTransform` matchers from a hook's `filter: { id, code, moduleType }` object. — [packages/vite/src/node/plugins/index.ts#L217-270](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/plugins/index.ts#L217-L270) [packages/vite/src/node/plugins/pluginFilter.ts](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/plugins/pluginFilter.ts)
- `createIdResolver(config, options)` is exported as the supported way for plugins to reuse Vite's resolver, and `config.createResolver(options)` wraps it with per-environment `PartialEnvironment` instances for client and ssr. — [packages/vite/src/node/index.ts#L42](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/index.ts#L42) [packages/vite/src/node/config.ts#L2185-2202](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/config.ts#L2185-L2202) [packages/vite/src/node/idResolver.ts](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/idResolver.ts)
- `create-vite` extends purely by directory convention — each entry in the `FRAMEWORKS` variants table maps to a sibling `template-<name>` directory (`template-react-ts`, `template-svelte`, `template-qwik-ts`, …), so adding a template means adding a directory plus a table entry. — [packages/create-vite/src/index.ts#L80-200](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/create-vite/src/index.ts#L80-L200) [packages/create-vite/](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/create-vite/)
- The dev-server middleware chain is extensible only through `configureServer` (pre and post phases) and `configurePreviewServer`; there is no separate middleware registry, so ordering is controlled by which phase a plugin uses. — [packages/vite/src/node/server/index.ts#L1000-1082](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/server/index.ts#L1000-L1082) [packages/vite/src/node/plugin.ts#L101-200](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/plugin.ts#L101-L200)
- DevTools integration is a first-class optional extension: `loadDevToolsIntegrationPlugins(config, command, devtoolsOptions)` injects plugins during `resolveConfig`, and `resolveDevToolsConfig` / `isDevToolsOptionEnabled` gate it behind the optional `@vitejs/devtools` peer dependency. — [packages/vite/src/node/config.ts#L792-830](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/config.ts#L792-L830) [packages/vite/src/node/config.ts#L1571-1584](https://github.com/vitejs/vite/blob/1544bb1b7ac92f775e9d0dea97954c99cc6cbd43/packages/vite/src/node/config.ts#L1571-L1584)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
