{"record":{"id":"b4b6db7179d415c0","repo":"oxc-project/oxc","slug":"fragments-should-contain-more-than-one-child","errorCode":null,"errorMessage":"Fragments should contain more than one child.","messagePattern":"Fragments should contain more than one child\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/react/jsx_no_useless_fragment.rs","lineNumber":24,"sourceCode":"    utils::is_jsx_fragment,\n};\nuse oxc_allocator::ArenaVec;\nuse oxc_ast::{\n    AstKind,\n    ast::{\n        JSXAttributeItem, JSXAttributeName, JSXChild, JSXElement, JSXElementName, JSXExpression,\n        JSXFragment,\n    },\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_semantic::NodeId;\nuse oxc_span::{GetSpan, Span};\nuse schemars::JsonSchema;\nuse serde::Deserialize;\n\nfn needs_more_children(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Fragments should contain more than one child.\").with_label(span)\n}\n\nfn child_of_html_element(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Passing a fragment to a HTML element is useless.\").with_label(span)\n}\n\n#[derive(Debug, Default, Clone, JsonSchema, Deserialize)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\npub struct JsxNoUselessFragment {\n    /// Allow fragments with a single expression child.\n    allow_expressions: bool,\n}\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Disallow unnecessary fragments.\n    ///","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/react/jsx_no_useless_fragment.rs#L6-L42","documentation":"Primary diagnostic of react/jsx-no-useless-fragment (category: pedantic, with autofix). A fragment (<>...</> or <React.Fragment>) with fewer than two children is unnecessary — grouping exists only to wrap multiple children, so a single child (element, expression, or none) does not need it. The rule skips fragments that carry a key attribute and, by default, reports fragments with a single expression child only when allowExpressions is false; a fragment containing only text that is not itself a child of another node is also exempt. oxlint attaches an automatic fix that unwraps the fragment.","triggerScenarios":"<>{foo}</> (single expression child, allowExpressions false), <><Card/></> (single element child), or an entirely empty fragment <></>; also render helpers returning <>{items}</> where items is a single expression. The suggestion fixer removes the fragment tags when safe (can_fix).","commonSituations":"Refactoring away wrapper elements by swapping div for a fragment but forgetting to remove it when only one child remains; prettier-style formatting that wraps single expressions in fragments; codemods that wrapped everything and left stragglers.","solutions":["Unwrap the fragment: replace <>{foo}</> with {foo} (oxlint's --fix applies this suggestion automatically)","If the single child is intentional grouping (rare), set { \"allowExpressions\": true } so <>{expr}</> is permitted","Give the fragment a second real child if grouping was the point, or add a key if it participates in a list","Run oxlint --fix across the repo once after enabling the rule to clear existing occurrences"],"exampleFix":"// before\nconst label = <>{count}</>;\n\n// after\nconst label = {count};  // or just: count","handlingStrategy":"validation","validationCode":"npx oxlint -D react/jsx-no-useless-fragment --fix src/  # autofix unwraps single-child fragments","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reach for fragments only when grouping two or more children (or forwarding keyed groups)","Enable allowExpressions: true only if <>{expr}</> is an accepted team pattern","Run oxlint --fix once after enabling the rule to clear the backlog automatically"],"tags":["react","jsx","fragment","dead-code","autofix","oxlint","lint"],"backgroundTag":"react-useless-fragment","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"}