oxc-project/oxc · warning · OxcDiagnostic
Prefer using `Response.json(…)` over `JSON.stringify()`.
Error message
Prefer using `Response.json(…)` over `JSON.stringify()`.
What it means
This is the oxlint rule `unicorn/prefer-response-static-json` firing. It flags `new Response(JSON.stringify(...))` because the Fetch API provides a static `Response.json(data)` factory that serializes the body and sets the correct `Content-Type: application/json` header for you. The rule is emitted as a style warning by the `unicorn` plugin inside oxc's linter.
Source
Thrown at crates/oxc_linter/src/rules/unicorn/prefer_response_static_json.rs:17
use oxc_ast::{
AstKind,
ast::{CallExpression, Expression, NewExpression},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};
use crate::{
AstNode,
ast_util::{could_be_asi_hazard, is_method_call, is_new_expression},
context::LintContext,
rule::Rule,
};
fn prefer_response_static_json_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Prefer using `Response.json(…)` over `JSON.stringify()`.").with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct PreferResponseStaticJson;
declare_oxc_lint!(
/// ### What it does
///
/// Enforces the use of `Response.json()` over `new Response(JSON.stringify())`.
///
/// ### Why is this bad?
///
/// `Response.json()` is a more concise and semantically clear way to create JSON responses.
/// It automatically sets the correct `Content-Type` header (`application/json`) and handles
/// serialization, making the code more maintainable and less error-prone.
///
/// ### Examples
///View on GitHub (pinned to e1e7af627c)
Solutions
- Replace `new Response(JSON.stringify(data), { headers: { 'content-type': 'application/json' } })` with `Response.json(data)`.
- If you support runtimes without `Response.json` (older Node < 18.11 / old service-worker scopes), disable the rule: `"unicorn/prefer-response-static-json": "off"` in `.oxlintrc.json`.
- If you intentionally need custom serialization (replacer/space args), keep `JSON.stringify` and add an eslint-disable/oxlint-disable comment for that line.
Example fix
// before
return new Response(JSON.stringify({ ok: true }), {
headers: { 'content-type': 'application/json' },
});
// after
return Response.json({ ok: true }); Defensive patterns
Strategy: validation
Validate before calling
// CI gate: fail the build on the rule before merge
// package.json script: "lint": "oxlint --deny-warn unicorn/prefer-response-static-json src/"
import { execSync } from 'node:child_process';
execSync('npx oxlint src/', { stdio: 'inherit' }); Prevention
- Prefer the static factories `Response.json(data)` / `Response.error()` / `Response.redirect()` whenever you construct JSON responses.
- Configure oxlint in CI (`oxlint --deny-warn`) so style regressions surface in the PR, not production review.
- Check runtime support (Node 18.11+/modern browsers) for Response.json before standardizing on it.
When it happens
Trigger: A `new Response(...)` expression (or `Response` constructor call) whose single argument is a `JSON.stringify()` call, e.g. in a service worker, Cloudflare Worker, or fetch handler returning `new Response(JSON.stringify(data))`. The rule matches via `is_new_expression` on `Response` combined with a `JSON.stringify` argument.
Common situations: Writing or reviewing fetch handlers / edge functions that hand-serialize payloads with `JSON.stringify` and manually set a JSON content-type header; migrating an ESLint `unicorn` config to oxlint and seeing the rule activate for the first time.
Related errors
- Prefer `{} {}` over `{} {}` to check {}.
- Invalid escape sequence in template literal.
- No spaces inside empty pair of braces allowed
- Use uppercase characters for the value of the escape sequenc
- The {expr_type} is useless
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/0cacd85bfae6438b.
Report an issue: GitHub.