withastro/astro · warning

More than one JSX renderer is enabled. This will lead to une

Error message

More than one JSX renderer is enabled. This will lead to unexpected behavior unless you set the `include` or `exclude` option. See https://docs.astro.build/en/guides/integrations-guide/react/#combining-multiple-jsx-frameworks for more information.

What it means

The React integration runs the same astro:config:done check as the other JSX renderers: if more than one of @astrojs/react, @astrojs/preact, @astrojs/solid-js is registered and react() was configured without include/exclude, Vite has ambiguous JSX transform rules and this warning is emitted. JSX components may compile with the wrong factory (React.createElement vs h vs Solid) and fail at runtime.

Source

Thrown at packages/integrations/react/src/index.ts:203

				updateConfig({
					vite: getViteConfiguration(
						{ include, exclude, babel, experimentalReactChildren, experimentalDisableStreaming },
						versionConfig,
					),
				});
				if (command === 'dev') {
					const preamble = FAST_REFRESH_PREAMBLE.replace(`__BASE__`, '/');
					injectScript('before-hydration', preamble);
				}
			},
			'astro:config:done': ({ logger, config }) => {
				const knownJsxRenderers = ['@astrojs/react', '@astrojs/preact', '@astrojs/solid-js'];
				const enabledKnownJsxRenderers = config.integrations.filter((renderer) =>
					knownJsxRenderers.includes(renderer.name),
				);

				if (enabledKnownJsxRenderers.length > 1 && !include && !exclude) {
					logger.warn(
						'More than one JSX renderer is enabled. This will lead to unexpected behavior unless you set the `include` or `exclude` option. See https://docs.astro.build/en/guides/integrations-guide/react/#combining-multiple-jsx-frameworks for more information.',
					);
				}
			},
		},
	};
}

/**
 * @deprecated Import `getContainerRenderer` from `@astrojs/react/container-renderer` instead.
 */
export function getContainerRenderer(): AstroRenderer {
	console.warn(
		'[@astrojs/react] Importing `getContainerRenderer` from `@astrojs/react` is deprecated. Import it from `@astrojs/react/container-renderer` instead.',
	);
	return getContainerRendererImpl();
}

View on GitHub (pinned to 52e6c34790)

Solutions

  1. Pass include/exclude globs to each JSX integration so every framework owns a disjoint file set, e.g. react({ include: ['**/react/**'] }) and preact({ include: ['**/preact/**'] }).
  2. Remove renderer integrations you do not actually use.
  3. Restart astro dev / rerun astro build to re-evaluate the config hook and confirm the warning is gone.

Example fix

// before
export default defineConfig({
  integrations: [react(), preact()],
});

// after
export default defineConfig({
  integrations: [
    react({ include: ['**/react/**'] }),
    preact({ include: ['**/preact/**'] }),
  ],
});
Defensive patterns

Strategy: validation

Validate before calling

const jsxIntegrations = ['@astrojs/react', '@astrojs/preact', '@astrojs/solid-js'];
const enabled = config.integrations.filter((i) => jsxIntegrations.includes(i.name));
if (enabled.length > 1 && !(reactOptions.include || reactOptions.exclude)) {
  throw new Error('Multiple JSX renderers require include/exclude scopes on react()');
}

Prevention

When it happens

Trigger: astro.config.mjs registers react() together with preact() or solid(), and the react() call has no include or exclude option; enabledKnownJsxRenderers.length > 1 in the astro:config:done hook.

Common situations: Dropping Preact or Solid components into a React codebase (or vice versa) during a migration; monorepo component libraries pulling in several renderer integrations; starter templates shipping all integrations by default.

Related errors


AI-assisted analysis of withastro/astro@52e6c34790 (2026-08-18). Data as JSON: /api/errors/8975b3f8f6debc63. Report an issue: GitHub.