JSON Formatter JavaScript โ€” JSON.stringify()

ยทFront-end & Node.js DeveloperยทDitinjau olehMarcus WebbยทDiterbitkan

Gunakan JSON Formatter & Beautifier gratis langsung di browser Anda โ€” tidak perlu instalasi.

Coba JSON Formatter & Beautifier Online โ†’

Saat men-debug respons API di Node.js, tembok JSON yang termampatkan adalah hal pertama yang memperlambat saya โ€” satu panggilan ke JSON.stringify(data, null, 2) dan strukturnya langsung terbaca. Untuk memformat JSON di JavaScript, Anda tidak butuh apa pun selain runtime: JSON.stringify sudah ada di setiap browser dan lingkungan Node.js, tanpa perlu install. Jika Anda hanya butuh hasil cepat tanpa menulis kode, Formatter JSON dari ToolDeck melakukannya secara instan. Panduan ini mencakup semua hal praktis: parameter space, array dan fungsi replacer, penanganan Date, BigInt, dan referensi circular, membaca dan menulis file JSON di Node.js (18+), pretty-printing dari CLI, dan library fast-json-stringify untuk serialisasi produksi.

  • โœ“JSON.stringify(data, null, 2) sudah ada di setiap browser dan Node.js โ€” tidak perlu install.
  • โœ“Parameter replacer menerima array (whitelist key) atau fungsi (transformasi nilai) โ€” gunakan untuk menyembunyikan field sensitif.
  • โœ“Objek Date diserialisasi otomatis via toJSON() โ†’ string ISO 8601; BigInt melempar TypeError dan memerlukan replacer kustom.
  • โœ“Referensi circular melempar TypeError โ€” perbaiki dengan seen Set dalam fungsi replacer, atau gunakan library flatted.
  • โœ“Untuk pretty-printing CLI gunakan node -p "JSON.stringify(require('./file.json'),null,2)" โ€” tidak perlu alat tambahan.

Apa Itu Format JSON?

Pemformatan JSON (disebut juga pretty-printing) mengubah string JSON yang ringkas dan termampatkan menjadi tata letak yang mudah dibaca manusia dengan indentasi dan jeda baris yang konsisten. Data dasarnya identik โ€” hanya spasi yang berubah. JSON ringkas optimal untuk transfer jaringan di mana setiap byte penting; JSON yang diformat optimal untuk debugging, tinjauan kode, dan inspeksi log. Fungsi JSON.stringify() di JavaScript menangani keduanya dalam satu panggilan dengan mengubah parameter space.

Before ยท json
After ยท json
{"orderId":"ord_8f2a91bc","status":"shipped","items":[{"sku":"HDMI-4K-2M","qty":2,"unitPrice":12.99}],"total":25.98}
{
  "orderId": "ord_8f2a91bc",
  "status": "shipped",
  "items": [
    {
      "sku": "HDMI-4K-2M",
      "qty": 2,
      "unitPrice": 12.99
    }
  ],
  "total": 25.98
}

JSON.stringify() โ€” Pemformat Bawaan

JSON.stringify() adalah fungsi global di setiap lingkungan JavaScript โ€” browser, Node.js, Deno, Bun โ€” tanpa perlu import. Argumen ketiganya, space, mengontrol indentasi: masukkan angka untuk spasi sebanyak itu per level, atau string '\t' untuk tab. Hilangkan (atau masukkan null) dan Anda mendapatkan output ringkas satu baris.

JavaScript โ€” contoh kerja minimal
const serverConfig = {
  host: "api.payments.internal",
  port: 8443,
  workers: 4,
  tls: { enabled: true, cert: "/etc/ssl/certs/api.pem" },
  rateLimit: { requestsPerMinute: 1000, burst: 50 }
}

console.log(JSON.stringify(serverConfig, null, 2))
// {
//   "host": "api.payments.internal",
//   "port": 8443,
//   "workers": 4,
//   "tls": {
//     "enabled": true,
//     "cert": "/etc/ssl/certs/api.pem"
//   },
//   "rateLimit": {
//     "requestsPerMinute": 1000,
//     "burst": 50
//   }
// }

Parameter space menerima angka (1โ€“10 spasi) atau string. Memasukkan karakter tab menghasilkan output yang disukai banyak editor dan alat diff. Anda juga bisa menggabungkan ketiga parameter โ€” inilah pola dunia nyata yang saya gunakan saat menulis JSON terformat ke file config:

JavaScript โ€” variasi space
const telemetryEvent = {
  eventId: "evt_3c7f9a2b",
  service: "checkout-api",
  severity: "warn",
  latencyMs: 342,
  region: "eu-west-1",
  tags: ["payment", "timeout", "retry"]
}

// Indentasi 2 spasi (paling umum di proyek JS)
JSON.stringify(telemetryEvent, null, 2)

// Indentasi tab (disukai beberapa linter dan alat config)
JSON.stringify(telemetryEvent, null, '\t')

// Ringkas โ€” tanpa spasi (untuk transfer jaringan)
JSON.stringify(telemetryEvent)
// {"eventId":"evt_3c7f9a2b","service":"checkout-api",...}
Catatan:Nilai undefined, fungsi, dan Symbol dihilangkan secara diam-diam dari output. Jika nilai properti adalah undefined, key tersebut tidak akan muncul sama sekali dalam string terserialisasi โ€” ini sumber bug umum saat logging objek yang memiliki field opsional.

Fungsi Replacer โ€” Filter dan Transformasi Output

Argumen kedua dari JSON.stringify() adalah replacer. Ada dua bentuk: sebuah array yang memberi whitelist key tertentu, atau sebuah fungsi yang dipanggil untuk setiap pasangan key/value dan dapat memfilter, mentransformasi, atau menyunting nilai. Saya menggunakan bentuk array ketika butuh subset cepat, dan bentuk fungsi ketika perlu menyembunyikan data sensitif sebelum logging.

Array Replacer โ€” Whitelist Key Tertentu

JavaScript โ€” array replacer
const order = {
  orderId: "ord_8f2a91bc",
  customer: {
    id: "usr_4421",
    email: "b.santoso@contoh.id",
    passwordHash: "bcrypt:$2b$12$XKzV..."
  },
  items: [{ sku: "HDMI-4K-2M", qty: 2, unitPrice: 12.99 }],
  createdAt: "2026-03-10T14:22:00Z"
}

// Hanya sertakan field aman dalam output log
const safeLog = JSON.stringify(order, ["orderId", "items", "createdAt"], 2)
// {
//   "orderId": "ord_8f2a91bc",
//   "items": [{ "sku": "HDMI-4K-2M", "qty": 2, "unitPrice": 12.99 }],
//   "createdAt": "2026-03-10T14:22:00Z"
// }
// passwordHash dan customer.email dikecualikan

Fungsi Replacer โ€” Transformasi Nilai

JavaScript โ€” fungsi replacer
const auditRecord = {
  requestId: "req_7d2e91",
  user: { id: "usr_4421", email: "b.santoso@contoh.id", apiKey: "sk-live-eKx9..." },
  action: "update_billing",
  timestamp: new Date("2026-03-10T14:22:00Z"),
  durationMs: 87
}

function safeReplacer(key, value) {
  // Sembunyikan field yang terlihat seperti rahasia atau data pribadi
  if (key === "apiKey") return "[DISUNTING]"
  if (key === "email") return value.replace(/(?<=.{2}).+(?=@)/, "***")
  return value
}

console.log(JSON.stringify(auditRecord, safeReplacer, 2))
// {
//   "requestId": "req_7d2e91",
//   "user": { "id": "usr_4421", "email": "b.***@contoh.id", "apiKey": "[DISUNTING]" },
//   "action": "update_billing",
//   "timestamp": "2026-03-10T14:22:00.000Z",
//   "durationMs": 87
// }
Catatan:Fungsi replacer dipanggil dengan this yang mengacu pada objek yang berisi key saat ini. Pemanggilan pertama memasukkan string kosong sebagai key dan seluruh nilai yang diserialisasi sebagai value โ€” kembalikan tanpa perubahan untuk melanjutkan serialisasi normal.

Menangani Tipe Tidak Terserialisasi

Tidak semua nilai JavaScript memetakan dengan bersih ke JSON. Mengetahui bagaimana setiap tipe berperilaku mencegah kehilangan data diam-diam dan error runtime tak terduga dalam kode produksi.

Date โ€” Otomatis via toJSON()

Objek Date mengimplementasikan metode toJSON() yang mengembalikan string ISO 8601. JSON.stringify() memanggil toJSON() secara otomatis sebelum serialisasi, sehingga tidak diperlukan penanganan khusus.

JavaScript โ€” serialisasi Date
const webhook = {
  eventType: "payment.succeeded",
  occurredAt: new Date("2026-03-10T14:22:00Z"),
  processedAt: new Date()
}

JSON.stringify(webhook, null, 2)
// {
//   "eventType": "payment.succeeded",
//   "occurredAt": "2026-03-10T14:22:00.000Z",
//   "processedAt": "2026-03-10T14:22:01.347Z"
// }

// Objek apa pun dengan metode toJSON() mendapat perlakuan yang sama:
const custom = { toJSON: () => "custom-value", hidden: 42 }
JSON.stringify(custom) // '"custom-value"'

Kelas Kustom โ€” Implementasikan toJSON()

Kelas apa pun dapat mengimplementasikan metode toJSON() dan JSON.stringify() akan memanggilnya secara otomatis saat serialisasi. Ini lebih bersih daripada replacer global untuk tipe domain yang muncul di seluruh codebase.

JavaScript โ€” toJSON() kustom
class Money {
  constructor(amount, currency) {
    this.amount = amount
    this.currency = currency
  }
  toJSON() {
    // Dipanggil otomatis oleh JSON.stringify
    return { amount: this.amount, currency: this.currency, formatted: `${this.currency} ${this.amount.toFixed(2)}` }
  }
}

class OrderId {
  constructor(id) { this.id = id }
  toJSON() { return this.id }  // Serialisasi sebagai string biasa
}

const invoice = {
  invoiceId: new OrderId('inv_8f2a91bc'),
  subtotal: new Money(199.00, 'IDR'),
  tax:      new Money(15.92, 'IDR'),
  issuedAt: new Date('2026-03-10T14:22:00Z')
}

JSON.stringify(invoice, null, 2)
// {
//   "invoiceId": "inv_8f2a91bc",
//   "subtotal": { "amount": 199, "currency": "IDR", "formatted": "IDR 199.00" },
//   "tax": { "amount": 15.92, "currency": "IDR", "formatted": "IDR 15.92" },
//   "issuedAt": "2026-03-10T14:22:00.000Z"
// }
Catatan:toJSON() lebih diprioritaskan daripada fungsi replacer. Jika keduanya ada, toJSON() berjalan lebih dulu โ€” replacer menerima nilai yang sudah dikonversi, bukan instance kelas aslinya.

BigInt โ€” TypeError Tanpa Replacer

JavaScript โ€” replacer BigInt
// Ini melempar: TypeError: Do not know how to serialize a BigInt
// JSON.stringify({ sessionId: 9007199254741234n })

// Solusi: konversi BigInt ke string dalam replacer
function bigIntReplacer(_key, value) {
  return typeof value === 'bigint' ? value.toString() : value
}

const metrics = {
  requestCount: 9007199254741234n,  // melebihi Number.MAX_SAFE_INTEGER
  service: "ingestion-worker",
  region: "us-east-1"
}

JSON.stringify(metrics, bigIntReplacer, 2)
// {
//   "requestCount": "9007199254741234",
//   "service": "ingestion-worker",
//   "region": "us-east-1"
// }

Referensi Circular โ€” TypeError Tanpa Seen Set

JavaScript โ€” replacer referensi circular
// Ini melempar: TypeError: Converting circular structure to JSON
// const node = { id: "n1" }; node.self = node; JSON.stringify(node)

// Solusi: lacak objek yang sudah dilihat dengan WeakSet
function circularReplacer() {
  const seen = new WeakSet()
  return function (_key, value) {
    if (typeof value === 'object' && value !== null) {
      if (seen.has(value)) return '[Circular]'
      seen.add(value)
    }
    return value
  }
}

const parent = { id: "node_parent", label: "akar" }
const child  = { id: "node_child", parent }
parent.child = child  // circular

JSON.stringify(parent, circularReplacer(), 2)
// {
//   "id": "node_parent",
//   "label": "akar",
//   "child": { "id": "node_child", "parent": "[Circular]" }
// }

// Alternatif: npm install flatted
// import { stringify } from 'flatted'
// stringify(parent)  // menangani ref circular secara native

Referensi Parameter JSON.stringify()

Ketiga parameter didukung penuh di setiap runtime JavaScript modern. Default menghasilkan JSON ringkas satu baris โ€” masukkan parameter secara eksplisit untuk output yang mudah dibaca.

Parameter
Tipe
Default
Deskripsi
value
any
โ€”
Nilai yang akan diserialisasi. Objek, array, string, angka, boolean, dan null didukung secara native.
replacer
function | Array<string | number> | null
null
Filter atau transformasi pasangan key/value. Array = daftar putih key yang disertakan. Function = dipanggil untuk setiap key/value.
space
number | string | null
null
Indentasi. Angka = spasi per level (maks. 10). String = indentasi literal (mis. "\t"). null atau 0 = output ringkas.

Format JSON dari File dan Respons API

Di Node.js (18+) Anda sering perlu memformat ulang file config JSON atau mencetak respons API dengan rapi untuk debugging. Kedua pola menggunakan pendekatan dua langkah yang sama: parse teks mentah dengan JSON.parse(), lalu serialisasi ulang dengan JSON.stringify().

Membaca dan Menulis Ulang File Config JSON

Node.js 18+ โ€” format ulang file JSON (ESM)
import { readFileSync, writeFileSync } from 'fs'

try {
  const raw = readFileSync('./config/database.json', 'utf8')
  const config = JSON.parse(raw)
  writeFileSync('./config/database.json', JSON.stringify(config, null, 2))
  console.log('Config berhasil diformat ulang')
} catch (err) {
  console.error('Gagal memformat ulang config:', err.message)
  // JSON.parse melempar SyntaxError jika file berisi JSON tidak valid
  // readFileSync melempar ENOENT jika file tidak ada
}

Format Ulang File Async (fs/promises)

Node.js 18+ โ€” format ulang file async
import { readFile, writeFile } from 'fs/promises'

async function reformatJson(filePath) {
  const raw = await readFile(filePath, 'utf8')
  const parsed = JSON.parse(raw)
  const formatted = JSON.stringify(parsed, null, 2)
  await writeFile(filePath, formatted, 'utf8')
  return { keys: Object.keys(parsed).length }
}

// Penggunaan
const { keys } = await reformatJson('./config/feature-flags.json')
console.log(`Berhasil memformat ulang ${keys} key tingkat atas`)

Pretty Print JSON dari Respons fetch()

Saat membangun atau men-debug klien API di Node.js 18+ atau browser, mencetak body respons dengan rapi adalah cara tercepat untuk memahami apa yang dikembalikan server. Pola standarnya adalah response.json() (objek yang sudah diparsing) lalu JSON.stringify(). Jika Anda butuh string mentah terlebih dahulu โ€” misalnya untuk menghitung hash atau mencatatnya apa adanya โ€” gunakan response.text() lalu JSON.parse().

JavaScript โ€” fetch + pretty print (Node.js 18+ atau browser)
// Pola 1: response.json() โ†’ pretty print
async function debugEndpoint(url) {
  const res = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.API_TOKEN}` }
  })
  if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`)

  const data = await res.json()
  console.log(JSON.stringify(data, null, 2))
}

await debugEndpoint('https://api.stripe.com/v1/charges?limit=3')
JavaScript โ€” response.text() saat butuh string mentah terlebih dahulu
// Pola 2: response.text() โ†’ parse โ†’ format
// Berguna saat ingin log respons mentah DAN pretty-print-nya
async function inspectRawResponse(url) {
  const res = await fetch(url)
  const raw = await res.text()

  console.log('Panjang respons mentah:', raw.length)
  try {
    const parsed = JSON.parse(raw)
    console.log('Terformat:')
    console.log(JSON.stringify(parsed, null, 2))
  } catch {
    console.error('Respons bukan JSON valid:', raw.slice(0, 200))
  }
}

Pretty Printing dari Command Line

Node.js sudah memiliki kemampuan untuk mencetak JSON dengan rapi dari terminal tanpa alat tambahan. One-liner ini berguna dalam skrip CI, pipeline deployment, dan alias shell. Untuk penggunaan interaktif yang lebih cepat, instal jq โ€” standar de-facto untuk manipulasi JSON di command line.

bash โ€” pretty print file JSON dengan Node.js
# Pretty-print package.json menggunakan node -p (print)
node -p "JSON.stringify(require('./package.json'), null, 2)"

# Pretty-print dari stdin (ramah pipe, berfungsi di CI)
echo '{"port":3000,"env":"production"}' | node -e "
  const d = require('fs').readFileSync(0, 'utf8')
  console.log(JSON.stringify(JSON.parse(d), null, 2))
"

# Pretty-print respons API yang disimpan ke file
cat api-response.json | node -e "
  process.stdin.setEncoding('utf8')
  let s = ''
  process.stdin.on('data', c => s += c)
  process.stdin.on('end', () => console.log(JSON.stringify(JSON.parse(s), null, 2)))
"
bash โ€” alternatif universal
# Fallback Python (terinstal di macOS dan sebagian besar distro Linux)
cat api-response.json | python3 -m json.tool

# jq โ€” tercepat dan terkaya fitur (brew install jq / apt install jq)
cat api-response.json | jq .

# jq โ€” pretty-print dan filter dalam satu langkah
cat api-response.json | jq '.data.users[] | {id, email}'
Catatan:Saat menjalankan Node.js dalam mode ESM (misalnya dengan "type": "module" di package.json), require() tidak tersedia dalam one-liner. Gunakan --input-type=module dan fs.readFileSync sebagai gantinya, atau beralih ke node -e dengan cuplikan CommonJS seperti yang ditunjukkan di atas.

Jika Anda sama sekali tidak di terminal โ€” menempel respons Postman atau file log โ€” Formatter JSON dari ToolDeck memungkinkan Anda menempel, memformat, dan menyalin dalam satu langkah dengan penyorotan sintaks dan validasi bawaan.

Alternatif Berkinerja Tinggi โ€” fast-json-stringify

fast-json-stringify menghasilkan fungsi serializer khusus dari JSON Schema. Karena mengetahui bentuk data di awal, ia bisa melewati pemeriksaan tipe dan menggunakan concatenation string daripada recursive descent โ€” benchmark biasanya menunjukkan peningkatan throughput 2โ€“5ร— dibanding JSON.stringify() pada payload besar dan berulang. Saya menggunakannya di route API bervolume tinggi di mana biaya serialisasi terlihat dalam profiler trace.

bash
npm install fast-json-stringify
JavaScript โ€” fast-json-stringify untuk event telemetri
import fastJson from 'fast-json-stringify'

const serializeTelemetryEvent = fastJson({
  title: 'TelemetryEvent',
  type: 'object',
  properties: {
    eventId:   { type: 'string' },
    service:   { type: 'string' },
    severity:  { type: 'string', enum: ['info', 'warn', 'error'] },
    latencyMs: { type: 'integer' },
    timestamp: { type: 'string' },
    region:    { type: 'string' }
  },
  required: ['eventId', 'service', 'severity', 'latencyMs', 'timestamp']
})

const event = {
  eventId:   'evt_3c7f9a2b',
  service:   'checkout-api',
  severity:  'warn',
  latencyMs: 342,
  timestamp: new Date().toISOString(),
  region:    'eu-west-1'
}

const json = serializeTelemetryEvent(event)
// '{"eventId":"evt_3c7f9a2b","service":"checkout-api","severity":"warn",...}'
Catatan:fast-json-stringify dirancang untuk serialisasi produksi data terstruktur โ€” selalu menghasilkan output ringkas (tanpa pretty-printing). Untuk output yang mudah dibaca manusia saat pengembangan, gunakan JSON.stringify(data, null, 2) seperti biasa.

Output Terminal dengan Syntax Highlighting

Fungsi bawaan util.inspect() milik Node.js menghasilkan output berwarna yang mudah dibaca, dioptimalkan untuk tampilan terminal. Ia menangani referensi circular dan BigInt secara native, dan merender objek bersarang secara rekursif hingga kedalaman berapa pun. Outputnya bukan JSON valid โ€” menggunakan sintaks JavaScript (misalnya merender fungsi dan Symbol daripada menghilangkannya), yang membuatnya ideal untuk skrip debugging Node.js tetapi tidak cocok untuk respons API atau output file.

Node.js 18+ โ€” util.inspect dengan warna
import { inspect } from 'util'

const payload = {
  requestId: "req_7d2e91",
  user: { id: "usr_4421", roles: ["admin", "billing"] },
  metadata: { ipAddress: "203.0.113.42", userAgent: "Mozilla/5.0" },
  createdAt: new Date()
}

// depth: null โ†’ perluas semua level bersarang; colors: true โ†’ warna terminal ANSI
console.log(inspect(payload, { colors: true, depth: null }))
Peringatan:Jangan gunakan util.inspect() untuk JSON yang ditulis ke file, dikirim melalui jaringan, atau disimpan dalam database. Outputnya bukan JSON valid dan akan menyebabkan error parse di sistem downstream mana pun yang memanggil JSON.parse() pada outputnya. Gunakan hanya untuk debugging terminal interaktif.

Bekerja dengan File JSON Besar

JSON.parse() memuat seluruh file ke memori sebelum parsing โ€” tidak masalah untuk payload kecil, tapi tidak praktis untuk file di atas 50โ€“100 MB seperti ekspor database, dump log aplikasi, atau batch analitik. Untuk kasus ini, Node.js Streams dan library stream-json memungkinkan Anda memproses record satu per satu tanpa menghabiskan heap.

Parsing Streaming dengan stream-json

bash
npm install stream-json
Node.js 18+ โ€” stream-json untuk array besar
import { pipeline } from 'stream/promises'
import { createReadStream } from 'fs'
import { parser } from 'stream-json'
import { streamArray } from 'stream-json/streamers/StreamArray.js'

// events.json = array jutaan objek โ€” tidak pernah dimuat penuh ke memori
await pipeline(
  createReadStream('./events.json'),
  parser(),
  streamArray(),
  async function* (source) {
    for await (const { value: event } of source) {
      if (event.severity === 'error') {
        console.log(JSON.stringify(event, null, 2))
      }
    }
  }
)

NDJSON / JSON Lines โ€” Tanpa Dependensi Tambahan

NDJSON (Newline Delimited JSON) menyimpan satu objek JSON per baris dan umum digunakan dalam ekspor Kafka, output BigQuery, dan pipeline log terstruktur. Modul bawaan readline di Node.js menanganinya tanpa paket pihak ketiga.

Node.js 18+ โ€” NDJSON dengan readline
import { createReadStream } from 'fs'
import { createInterface } from 'readline'

// Format: satu objek JSON per baris (log, ekspor Kafka, BigQuery)
const rl = createInterface({
  input: createReadStream('./logs.ndjson'),
  crlfDelay: Infinity
})

for await (const line of rl) {
  if (!line.trim()) continue
  const entry = JSON.parse(line)
  if (entry.level === 'error') {
    console.log(JSON.stringify(entry, null, 2))
  }
}
Catatan:Beralih dari JSON.parse() ke streaming saat file JSON Anda melebihi 50โ€“100 MB atau saat memproses stream tak terbatas (Kafka, pipeline log). Untuk NDJSON / JSON Lines, gunakan readline โ€” tidak memerlukan dependensi tambahan.

Kesalahan Umum

Keempat kesalahan ini muncul berulang kali dalam code review dan laporan bug produksi. Masing-masing melibatkan perilaku halus dari JSON.stringify() yang mudah terlewat dan sulit di-debug setelah kejadian.

โŒ Lupa bahwa nilai undefined dihilangkan secara diam-diam

Masalah: Properti objek dengan nilai undefined dihilangkan sepenuhnya dari output JSON โ€” tidak ada peringatan atau error. Ini menyebabkan kehilangan data yang tidak terlihat ketika ada field opsional pada objek.

Solusi: Gunakan null untuk nilai yang sengaja tidak ada yang harus muncul dalam output yang diserialisasi. Simpan undefined hanya untuk field yang harus dikecualikan dari JSON.

Before ยท JavaScript
After ยท JavaScript
const userProfile = {
  userId: "usr_4421",
  displayName: "Budi Santoso",
  avatarUrl: undefined,   // akan menghilang diam-diam
  bio: undefined          // akan menghilang diam-diam
}

JSON.stringify(userProfile, null, 2)
// { "userId": "usr_4421", "displayName": "Budi Santoso" }
// avatarUrl dan bio hilang โ€” tidak ada peringatan
const userProfile = {
  userId: "usr_4421",
  displayName: "Budi Santoso",
  avatarUrl: null,   // sengaja tidak ada โ€” muncul dalam output
  bio: null          // sengaja tidak ada โ€” muncul dalam output
}

JSON.stringify(userProfile, null, 2)
// {
//   "userId": "usr_4421",
//   "displayName": "Budi Santoso",
//   "avatarUrl": null,
//   "bio": null
// }
โŒ BigInt melempar TypeError

Masalah: Memasukkan nilai BigInt ke JSON.stringify() melempar TypeError di runtime. Ini adalah crash keras, bukan penghapusan diam-diam โ€” akan muncul di produksi jika ada field numerik yang melebihi Number.MAX_SAFE_INTEGER.

Solusi: Gunakan fungsi replacer yang mengonversi nilai BigInt ke string sebelum serialisasi. Atau, konversi BigInt ke string atau Number di lapisan data sebelum meneruskannya ke JSON.stringify.

Before ยท JavaScript
After ยท JavaScript
const session = {
  sessionId: 9007199254741234n,  // literal BigInt
  userId: "usr_4421",
  startedAt: "2026-03-10T14:00:00Z"
}

JSON.stringify(session, null, 2)
// Uncaught TypeError: Do not know how to serialize a BigInt
function bigIntReplacer(_key, value) {
  return typeof value === 'bigint' ? value.toString() : value
}

const session = {
  sessionId: 9007199254741234n,
  userId: "usr_4421",
  startedAt: "2026-03-10T14:00:00Z"
}

JSON.stringify(session, bigIntReplacer, 2)
// {
//   "sessionId": "9007199254741234",
//   "userId": "usr_4421",
//   "startedAt": "2026-03-10T14:00:00Z"
// }
โŒ Crash referensi circular

Masalah: Objek yang mereferensikan dirinya sendiri โ€” umum di pohon DOM, linked list, dan beberapa result set ORM โ€” melempar TypeError saat diberikan ke JSON.stringify(). Error hanya terjadi pada saat serialisasi, sering kali jauh dari tempat referensi circular dibuat.

Solusi: Gunakan fungsi replacer dengan WeakSet untuk mendeteksi dan mengganti referensi circular, atau instal library flatted sebagai pengganti drop-in yang menangani struktur circular secara native.

Before ยท JavaScript
After ยท JavaScript
const dept = { id: "dept_eng", name: "Engineering" }
const team = { id: "team_frontend", dept }
dept.teams = [team]  // circular: dept โ†’ team โ†’ dept

JSON.stringify(dept, null, 2)
// Uncaught TypeError: Converting circular structure to JSON
import { stringify } from 'flatted'  // npm install flatted

const dept = { id: "dept_eng", name: "Engineering" }
const team = { id: "team_frontend", dept }
dept.teams = [team]

// flatted menangani ref circular โ€” catatan: output dalam format flatted, bukan JSON standar
stringify(dept)

// Atau gunakan replacer berbasis WeakSet jika butuh output JSON standar:
function circularReplacer() {
  const seen = new WeakSet()
  return (_key, value) => {
    if (typeof value === 'object' && value !== null) {
      if (seen.has(value)) return '[Circular]'
      seen.add(value)
    }
    return value
  }
}
JSON.stringify(dept, circularReplacer(), 2)
โŒ Menggunakan space > 10 (dibatasi diam-diam)

Masalah: Memasukkan nilai space lebih dari 10 ke JSON.stringify() tidak melempar error โ€” nilainya dibatasi diam-diam ke 10. Developer yang mengharapkan 20 spasi per indentasi untuk nested dalam akan mendapatkan hanya 10, menyebabkan format yang tidak terduga dalam file yang dihasilkan.

Solusi: Indentasi maksimum adalah 10 spasi. Untuk struktur dalam, lebih baik gunakan indentasi 2 spasi (konvensi paling umum di proyek JavaScript) dan andalkan editor yang bisa dilipat untuk navigasi.

Before ยท JavaScript
After ยท JavaScript
const deepConfig = { server: { tls: { certs: { primary: "/etc/ssl/api.pem" } } } }

// Mengharapkan indentasi 20 spasi โ€” tapi space dibatasi ke 10
JSON.stringify(deepConfig, null, 20)
// Output sama dengan JSON.stringify(deepConfig, null, 10)
// Tidak ada error, tidak ada peringatan โ€” dibatasi diam-diam
const deepConfig = { server: { tls: { certs: { primary: "/etc/ssl/api.pem" } } } }

// Gunakan 2 (kebanyakan proyek) atau 4 spasi โ€” jangan lebih dari 10
JSON.stringify(deepConfig, null, 2)
// {
//   "server": {
//     "tls": {
//       "certs": {
//         "primary": "/etc/ssl/api.pem"
//       }
//     }
//   }
// }

JSON.stringify vs Alternatif โ€” Perbandingan Cepat

Situasi berbeda membutuhkan alat berbeda. JSON.stringify dengan replacer mencakup sebagian besar kasus penggunaan produksi tanpa dependensi apa pun. util.inspect adalah pilihan tepat untuk debugging terminal cepat saat butuh output berwarna dan tidak perlu JSON valid. fast-json-stringify sepadan di route bervolume tinggi di mana profiling menunjukkan biaya serialisasi; untuk yang lainnya, overhead pemeliharaan schema tidak sebanding.

Metode
Output Rapi
JSON Valid
Non-ASCII
Tipe Kustom
Ref. Circular
Perlu Install
JSON.stringify
โœ“
โœ“
โœ“
โš ๏ธ via replacer
โœ— (melempar error)
Tidak
JSON.stringify + replacer
โœ“
โœ“
โœ“
โœ… kontrol penuh
โœ“
Tidak
util.inspect
โœ“
โœ—
โœ“
โœ… native
โœ“
Tidak (bawaan Node)
fast-json-stringify
โœ—
โœ“
โœ“
โŒ schema saja
โœ—
npm install
flatted
โœ“
โœ— (format khusus)
โœ“
โœ… circular saja
โœ“
npm install
jq (CLI)
โœ“
โœ“
โœ“
N/A
N/A
Install sistem

Pertanyaan yang Sering Diajukan

Bagaimana cara mencetak JSON dengan rapi di JavaScript?

Panggil JSON.stringify(data, null, 2) โ€” argumen ketiga mengontrol indentasi. Masukkan 2 atau 4 untuk spasi, atau "\t" untuk tab. Tidak perlu import atau install: JSON adalah objek global di setiap lingkungan JavaScript, termasuk browser dan Node.js.

JavaScript
const config = { host: "api.payments.internal", port: 8443, tls: true }
console.log(JSON.stringify(config, null, 2))
// {
//   "host": "api.payments.internal",
//   "port": 8443,
//   "tls": true
// }

Apa fungsi parameter `space` dalam JSON.stringify()?

Parameter space mengontrol indentasi dalam output. Masukkan angka (1โ€“10) untuk jumlah spasi per level, atau string seperti "\t" untuk menggunakan karakter tab. Nilai di atas 10 akan dibatasi diam-diam ke 10. Memasukkan null, 0, atau menghilangkan parameter akan menghasilkan JSON ringkas satu baris.

JavaScript
const data = { service: "payments", version: 3, active: true }

JSON.stringify(data, null, 2)   // indentasi 2 spasi
JSON.stringify(data, null, 4)   // indentasi 4 spasi
JSON.stringify(data, null, '\t') // indentasi tab
JSON.stringify(data)            // ringkas: {"service":"payments","version":3,"active":true}

Mengapa JSON.stringify() mengembalikan undefined untuk beberapa nilai?

JSON.stringify secara diam-diam menghilangkan properti objek yang nilainya undefined, fungsi, atau Symbol โ€” tipe-tipe ini tidak memiliki representasi JSON. Jika nilai tingkat atas sendiri undefined, fungsi mengembalikan undefined (bukan string "undefined"). Gunakan null sebagai pengganti undefined untuk field opsional yang harus muncul dalam output.

JavaScript
const event = {
  traceId: "tr_9a2f",
  handler: () => {},        // fungsi โ€” dihilangkan
  requestId: undefined,     // undefined โ€” dihilangkan
  sessionId: Symbol("s"),   // Symbol โ€” dihilangkan
  status: "ok"
}
JSON.stringify(event, null, 2)
// { "traceId": "tr_9a2f", "status": "ok" }

Bagaimana menangani objek Date saat memformat JSON?

Objek Date memiliki metode toJSON() bawaan yang mengembalikan string ISO 8601, sehingga JSON.stringify menanganinya secara otomatis. Anda tidak perlu replacer khusus untuk tanggal โ€” nilai yang diserialisasi akan berupa string seperti "2026-03-10T14:22:00.000Z".

JavaScript
const order = {
  orderId: "ord_8f2a91bc",
  placedAt: new Date("2026-03-10T14:22:00Z"),
  total: 42.98
}
JSON.stringify(order, null, 2)
// {
//   "orderId": "ord_8f2a91bc",
//   "placedAt": "2026-03-10T14:22:00.000Z",
//   "total": 42.98
// }

Bagaimana memformat string JSON (bukan objek) di JavaScript?

Parse string terlebih dahulu dengan JSON.parse(), lalu serialisasi ulang dengan JSON.stringify(). Kedua pemanggilan bisa dirantai dalam satu baris untuk debugging cepat.

JavaScript
const raw = '{"endpoint":"/api/v2/users","timeout":30,"retry":true}'
const formatted = JSON.stringify(JSON.parse(raw), null, 2)
console.log(formatted)
// {
//   "endpoint": "/api/v2/users",
//   "timeout": 30,
//   "retry": true
// }

Apakah JSON.stringify() bisa digunakan di browser?

Ya. JSON adalah global bawaan di setiap browser modern sejak IE8 โ€” tidak perlu tag script atau import. Buka konsol DevTools dan panggil JSON.stringify() langsung. Fungsinya identik dengan versi Node.js, dengan tanda tangan parameter yang sama dan batasan yang sama seputar BigInt dan referensi circular.

JavaScript
// Berfungsi di Chrome, Firefox, Safari, Edge โ€” tidak perlu import
const payload = { userId: "usr_7b3c", action: "checkout", cart: ["SKU-001", "SKU-002"] }
copy(JSON.stringify(payload, null, 2)) // copy() adalah helper DevTools

JavaScript memberi Anda kendali penuh โ€” fungsi replacer, toJSON() kustom, pemrosesan file besar di Node.js. Saat Anda hanya perlu memeriksa atau berbagi cuplikan yang diformat, Formatter JSON dari ToolDeck adalah jalur tercepat: tempel JSON dan dapatkan hasil yang diformat dan disorot tanpa pengaturan lingkungan apa pun.

Alat Terkait

Tersedia juga dalam:PythonGoBash
AC
Alex ChenFront-end & Node.js Developer

Alex is a front-end and Node.js developer with extensive experience building web applications and developer tooling. He is passionate about web standards, browser APIs, and the JavaScript ecosystem. In his spare time he contributes to open-source projects and writes about modern JavaScript patterns, performance optimisation, and everything related to the web platform.

MW
Marcus WebbPeninjau teknis

Marcus specialises in JavaScript performance, build tooling, and the inner workings of the V8 engine. He has spent years profiling and optimising React applications, working on bundler configurations, and squeezing every millisecond out of critical rendering paths. He writes about Core Web Vitals, JavaScript memory management, and the tools developers reach for when performance really matters.