{"record":{"id":"df9cabce3eb064dd","repo":"oxc-project/oxc","slug":"using-img-could-result-in-slower-lcp-and-highe","errorCode":null,"errorMessage":"Using `<img>` could result in slower LCP and higher bandwidth.","messagePattern":"Using `<img>` could result in slower LCP and higher bandwidth\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/nextjs/no_img_element.rs","lineNumber":12,"sourceCode":"use oxc_ast::{\n    AstKind,\n    ast::{JSXAttributeItem, JSXElementName},\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::{GetSpan, Span};\n\nuse crate::{AstNode, context::LintContext, rule::Rule};\n\nfn no_img_element_diagnostic(span: Span, src_span: Option<Span>) -> OxcDiagnostic {\n    let mut diagnostic = OxcDiagnostic::warn(\"Using `<img>` could result in slower LCP and higher bandwidth.\")\n        .with_help(\"Consider using `<Image />` from `next/image` or a custom image loader to automatically optimize images.\")\n        .with_note(\"See https://nextjs.org/docs/messages/no-img-element\")\n        .with_label(span.label(\"Use `<Image />` from `next/image` instead.\"));\n    if let Some(src_span) = src_span {\n        diagnostic = diagnostic.and_label(src_span.label(\"Use a static image import instead.\"));\n    }\n    diagnostic\n}\n\n#[derive(Debug, Default, Clone)]\npub struct NoImgElement;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Prevent the usage of the `<img>` element due to slower\n    /// [LCP](https://nextjs.org/learn/seo/lcp) and higher bandwidth.\n    ///","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/nextjs/no_img_element.rs#L1-L30","documentation":"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.","triggerScenarios":"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.'.","commonSituations":"Porting HTML mockups; avatar/thumbnail lists; using CMS URLs directly. This is the single most-reported Next.js lint warning.","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."],"exampleFix":"// before\n<img src=\"/hero.png\" alt=\"Hero\" />\n\n// after\nimport hero from '../public/hero.png';\nimport Image from 'next/image';\n<Image src={hero} alt=\"Hero\" />","handlingStrategy":"validation","validationCode":"// find native img tags:\n// rg -n '<img[ >]' -g '*.tsx' src","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["nextjs","performance","image","lint"],"backgroundTag":"lint-use-image-optimization","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}