parcel-bundler/parcel · error · ThrowableDiagnostic
Local plugins are not supported in Parcel config packages. P
Error message
Local plugins are not supported in Parcel config packages. Please publish "${pluginName}" as a separate npm package. What it means
A Parcel *config package* (a published `.parcelrc`-bearing npm package) may reference plugins, but every plugin it references must itself be a separately-published npm package. This is enforced so plugins remain individually mixable across configs. Referencing a plugin by a relative path (starting with `.`) inside the config package is rejected with this diagnostic, including a code frame of the offending `.parcelrc`.
Source
Thrown at packages/core/core/src/loadParcelPlugin.js:47
): Promise<{|
plugin: T,
version: Semver,
resolveFrom: ProjectPath,
range: ?SemverRange,
|} | null> {
let resolveFrom = configPath;
let range;
let isOptional = false;
if (
resolveFrom.includes(NODE_MODULES) ||
(process.env.PARCEL_BUILD_ENV !== 'production' &&
/packages[/\\]configs/.test(resolveFrom))
) {
// Config packages can reference plugins, but cannot contain other plugins within them.
// This forces every published plugin to be published separately so they can be mixed and matched if needed.
if (pluginName.startsWith('.')) {
let configContents = await options.inputFS.readFile(configPath, 'utf8');
throw new ThrowableDiagnostic({
diagnostic: {
message: md`Local plugins are not supported in Parcel config packages. Please publish "${pluginName}" as a separate npm package.`,
origin: '@parcel/core',
codeFrames: keyPath
? [
{
filePath: configPath,
language: 'json5',
code: configContents,
codeHighlights: generateJSONCodeHighlights(configContents, [
{
key: keyPath,
type: 'value',
},
]),
},
]
: undefined,View on GitHub (pinned to 59484858a1)
Solutions
- Publish the local plugin as its own npm package and reference it by name.
- If the plugin is project-specific, keep it in the consuming project's `.parcelrc` (local configs may use relative paths), not in a published config package.
- Move the relative plugin out of the config package into the app that uses it.
Example fix
// before (config package .parcelrc)
{ "transforms": { "*.css": ["./local-transformer.js"] } }
// after
{ "transforms": { "*.css": ["@your-scope/parcel-transformer-css"] } } Defensive patterns
Strategy: validation
Validate before calling
// In a config package, reject relative plugin references at author time.
function isRelativePlugin(ref: string): boolean {
return ref.startsWith('.');
}
if (isRelativePlugin(entry)) throw new Error('publish the plugin as a package'); Type guard
function isPublishedPluginName(ref: string): boolean {
return !ref.startsWith('.');
} Prevention
- Never ship plugins inside a config package; publish each separately.
- Keep relative plugins in the consuming project's local .parcelrc.
When it happens
Trigger: Inside a config package, a pipeline entry resolves to a relative file (e.g. `./my-plugin.js`) rather than an npm package name.
Common situations: Authoring a shared Parcel config and bundling helper plugins as local files inside it.
Related errors
- Could not determine version of ${pluginName} in ${path.relat
- Only one spread parameter can be included in a config pipeli
- Cannot find Parcel plugin "${pluginName}"
- Config result is not hashable because it contains non-serial
- Could not find a .parcelrc
AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13).
Data as JSON: /api/errors/da18bb55afa98ee6.
Report an issue: GitHub.