How CRXJS Vite Plugin Performs Manifest Version Validation During Build
The CRXJS Vite plugin validates the manifest version synchronously in the config hook by checking that manifest.manifest_version equals 3, immediately throwing an error if any other version is detected.
The CRXJS Vite plugin enforces strict Manifest V3 compliance for Chrome extensions by validating the manifest version before any build steps execute. This validation occurs in the config hook of the plugin, ensuring developers receive immediate feedback if they attempt to use deprecated Manifest V2 formats. Understanding this validation mechanism helps prevent build failures and ensures compatibility with modern Chrome extension standards.
Where Manifest Version Validation Occurs
The validation logic resides in packages/vite-plugin/src/node/plugin-manifest.ts inside the crx:manifest-init plugin. According to the CRXJS source code, the plugin registers a config hook—the earliest Vite lifecycle hook available to plugins—to perform this check.
When Vite initializes, the plugin calls getOptions(config) to retrieve the user-provided manifest object or manifest factory function. This acquisition happens synchronously during Vite's configuration resolution phase, ensuring the build halts before any file processing begins if validation fails.
The Validation Implementation
The validation follows a strict three-step process:
-
Manifest acquisition – The plugin retrieves the manifest via
getOptions(config), which handles both static objects and dynamic functions. -
Version comparison – It reads
manifest.manifest_versionand compares it against the supported integer3. -
Error throwing – If the version is not exactly
3, the plugin throws an error with the message:CRXJS does not support Manifest vX, please use Manifest v3
This check runs synchronously, meaning Vite never proceeds to the build phase with an unsupported manifest. The source code includes a comment // TODO: build this out into full validation plugin, indicating that while comprehensive schema validation may arrive in future versions, the version gate serves as the critical safeguard today.
Code Examples
Valid Manifest V3 Configuration
This configuration passes validation and allows the build to proceed:
// vite.config.ts
import { defineConfig } from 'vite';
import { crx } from '@crxjs/vite-plugin';
export default defineConfig({
plugins: [
crx({
manifest: {
manifest_version: 3, // ✅ Required version
name: 'My Extension',
version: '1.0.0',
action: {
default_popup: 'index.html',
},
},
}),
],
});
Invalid Manifest V2 Error Handling
Attempting to use Manifest V2 triggers an immediate build failure:
// vite.config.ts
import { defineConfig } from 'vite';
import { crx } from '@crxjs/vite-plugin';
export default defineConfig({
plugins: [
crx({
manifest: {
manifest_version: 2, // ❌ Unsupported version
name: 'Old Extension',
version: '0.1.0',
browser_action: {
default_popup: 'index.html',
},
},
}),
],
});
$ vite build
Error: CRXJS does not support Manifest v2, please use Manifest v3
at config (packages/vite-plugin/src/node/plugin-manifest.ts:...)
Dynamic Manifest Functions
The validation also works when providing a function that generates the manifest at runtime:
// vite.config.ts
import { defineConfig } from 'vite';
import { crx } from '@crxjs/vite-plugin';
export default defineConfig({
plugins: [
crx({
manifest: (env) => ({
manifest_version: env.mode === 'production' ? 3 : 3, // Must return 3
name: 'Dynamic Manifest',
version: '1.0.0',
}),
}),
],
});
Even with dynamic generation, the config hook executes the function and validates the returned object's manifest_version before Vite continues.
Why Early Validation Matters
Performing manifest version validation in the config hook provides three critical benefits:
- Safety – Prevents accidental bundling of MV2 extensions, which are deprecated and unsupported by the CRXJS toolchain.
- Early feedback – Developers see the error immediately when running
viteorvite build, rather than discovering issues during browser loading or distribution packaging. - Future-proofing – The synchronous check establishes a foundation for the TODO-commented "full validation plugin" that may add schema validation for permissions, host permissions, and other Manifest V3 requirements.
Summary
- CRXJS validates manifest version in the
confighook located inpackages/vite-plugin/src/node/plugin-manifest.tsbefore Vite processes any source files. - Only
manifest_version: 3is supported; any other integer value triggers an immediate fatal error. - The validation uses
getOptions(config)to retrieve the manifest, then checksmanifest.manifest_versionagainst the hardcoded value3. - Error messages explicitly state: "CRXJS does not support Manifest vX, please use Manifest v3".
- Dynamic manifest functions are executed and validated during the config resolution phase, ensuring runtime-generated manifests still comply with V3 requirements.
Frequently Asked Questions
What happens if I use Manifest V2 with CRXJS?
The build fails immediately during Vite's configuration resolution phase. The plugin throws an error stating "CRXJS does not support Manifest v2, please use Manifest v3" and exits without processing any source files.
Can I use a function to generate the manifest dynamically?
Yes, CRXJS supports passing a function to the manifest option in the plugin configuration. The function receives the Vite environment object and must return a manifest object with manifest_version: 3. The validation occurs after the function executes but before the build begins.
Where is the manifest version validation code located?
The validation logic is implemented in the config hook inside packages/vite-plugin/src/node/plugin-manifest.ts. This file imports the manifest via getOptions from packages/vite-plugin/src/node/plugin-optionsProvider.ts and performs the version check against the ManifestV3 type definition found in packages/vite-plugin/src/node/manifest.ts.
Is Manifest V3 validation the only check performed?
Currently, only the manifest_version integer is strictly validated. However, the source code contains a TODO comment indicating plans to expand the plugin-manifest.ts logic into a comprehensive validation plugin that may verify permissions, host permissions, and other Manifest V3 schema requirements in future releases.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →