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

  1. Replace `new Response(JSON.stringify(data), { headers: { 'content-type': 'application/json' } })` with `Response.json(data)`.
  2. 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`.
  3. 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

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


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/0cacd85bfae6438b. Report an issue: GitHub.