oxc-project/oxc · warning · OxcDiagnostic
Using `<img>` could result in slower LCP and higher bandwidt
Error message
Using `<img>` could result in slower LCP and higher bandwidth.
What it means
Warning from oxlint rule `nextjs/no-img-element`. The `next/image` component serves right-sized, modern-format, lazily-loaded images through the Next.js optimizer; raw `<img>` tags ship original bytes, hurt Largest Contentful Paint, and skip that pipeline. The rule reports every native `<img>` in JSX and, when it finds an `src` attribute, adds a second label on it suggesting a static image import.
Source
Thrown at crates/oxc_linter/src/rules/nextjs/no_img_element.rs:12
use oxc_ast::{
AstKind,
ast::{JSXAttributeItem, JSXElementName},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use crate::{AstNode, context::LintContext, rule::Rule};
fn no_img_element_diagnostic(span: Span, src_span: Option<Span>) -> OxcDiagnostic {
let mut diagnostic = OxcDiagnostic::warn("Using `<img>` could result in slower LCP and higher bandwidth.")
.with_help("Consider using `<Image />` from `next/image` or a custom image loader to automatically optimize images.")
.with_note("See https://nextjs.org/docs/messages/no-img-element")
.with_label(span.label("Use `<Image />` from `next/image` instead."));
if let Some(src_span) = src_span {
diagnostic = diagnostic.and_label(src_span.label("Use a static image import instead."));
}
diagnostic
}
#[derive(Debug, Default, Clone)]
pub struct NoImgElement;
declare_oxc_lint!(
/// ### What it does
///
/// Prevent the usage of the `<img>` element due to slower
/// [LCP](https://nextjs.org/learn/seo/lcp) and higher bandwidth.
///View on GitHub (pinned to e1e7af627c)
Solutions
- `import Image from 'next/image'` and add explicit `width`/`height`, or use a static import which infers dimensions.
- For remote hosts, allowlist them under `images.remotePatterns` in `next.config.js`.
- If the image must stay raw (e.g. inside rendered markdown), suppress with an inline oxlint-disable comment for this one line.
Example fix
// before
<img src="/hero.png" alt="Hero" />
// after
import hero from '../public/hero.png';
import Image from 'next/image';
<Image src={hero} alt="Hero" /> Defensive patterns
Strategy: validation
Validate before calling
// find native img tags: // rg -n '<img[ >]' -g '*.tsx' src
Prevention
- Reach for `next/image` first; static imports give you inferred width/height for free.
- Allowlist remote image hosts under `images.remotePatterns` before switching CMS images.
- Fix `<img>` during HTML-to-JSX conversion, not after; keep oxlint's nextjs plugin in CI.
When it happens
Trigger: Any native `<img>` JSX element in a component; when a `src` attribute exists, its span gets the extra label 'Use a static image import instead.'.
Common situations: Porting HTML mockups; avatar/thumbnail lists; using CMS URLs directly. This is the single most-reported Next.js lint warning.
Related errors
- A font-display parameter is missing (adding `&display=option
- `{font_display_value}` is not a recommended font-display val
- `rel="preconnect"` is missing from Google Font.
- Do not use `<a>` elements to navigate between Next.js pages.
- Custom fonts not added in `pages/_document.js` will only loa
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/df9cabce3eb064dd.
Report an issue: GitHub.