CSV to JSON JavaScript — Converter + Code Examples

·Front-end & Node.js Developer·Granskad avSophie Laurent·Publicerad

Använd det kostnadsfria CSV to JSON direkt i webbläsaren — ingen installation krävs.

Prova CSV to JSON online →

Mest CSV-data jag stöter på anländer som en platt sträng från en filuppladdning, en databasexport eller ett API som fortfarande talar 1970-talets format. För att konvertera CSV till JSON i JavaScript behöver du två saker som språket ger dig gratis: strängdelning för att parsa raderna och JSON.stringify() för att serialisera resultatet. Inga npm-paket krävs för grunderna — den här guiden täcker hela pipelinen från ett återanvändbart csvToJson() verktyg via PapaParse och Node.js fil-I/O. För snabba konverteringar utan kod hanterar CSV till JSON-konverteraren online det direkt. Alla exempel riktar sig mot Node.js 18+ och moderna webbläsare.

  • Dela CSV med radbrytning, extrahera rubriker från rad 0, mappa återstående rader till objekt, sedan JSON.stringify(array, null, 2) för formaterad utdata.
  • JSON.stringify() producerar en sträng; JSON.parse() konverterar tillbaka den till en levande JavaScript-array — vet vilken du har innan du opererar på den.
  • Map-instanser serialiseras inte till JSON automatiskt — anropa Object.fromEntries(map) först.
  • För CSV med citerade fält, kommatecken inuti värden eller radbrytningar i celler, använd PapaParse eller csv-parse istället för manuell delning.
  • csvtojson (npm) hanterar typtvång, streaming och RFC 4180-kantfall i ett enda anrop.

Vad är CSV till JSON-konvertering?

CSV till JSON-konvertering omvandlar ett platt, kommaavgränsat textformat till en strukturerad array av objekt där varje rad blir ett JavaScript-objekt med kolumnrubrikerna som nycklar. CSV-formatet har inga datatyper — allt är en sträng. JSON lägger till struktur, nästling och explicita typer (tal, booleaner, null). Denna konvertering är det första steget i nästan varje datapipeline som börjar med en kalkylbladsexport, en äldre systemdump eller en användarladdad fil. Den underliggande datan förblir densamma; formatet ändras från positionsbaserade kolumner till namngivna egenskaper.

Before · json
After · json
name,email,role,active
Erik Johansson,erik@nexuslabs.se,Engineering Lead,true
Anna Lindgren,anna@nexuslabs.se,Product Manager,true
[
  {
    "name": "Erik Johansson",
    "email": "erik@nexuslabs.se",
    "role": "Engineering Lead",
    "active": "true"
  },
  {
    "name": "Anna Lindgren",
    "email": "anna@nexuslabs.se",
    "role": "Product Manager",
    "active": "true"
  }
]

csvToJson() — Bygga en återanvändbar konverteringsfunktion

Den fullständiga CSV-till-JSON-pipelinen i JavaScript delas upp i tre steg: dela CSV-strängen med radbrytning för att få rader, extrahera rubriker från den första raden med split(','), mappa sedan varje återstående rad till ett vanligt JavaScript-objekt där nycklarna kommer från rubrikerna och värdena från motsvarande kolumnpositioner. Det slutliga anropet till JSON.stringify() konverterar den arrayen av objekt till en JSON-sträng. Här är en minimal fungerande version:

JavaScript — minimal csvToJson
function csvToJson(csv) {
  const lines = csv.trim().split('\n')
  const headers = lines[0].split(',').map(h => h.trim())

  const rows = lines.slice(1)
    .filter(line => line.trim() !== '')
    .map(line => {
      const values = line.split(',')
      return Object.fromEntries(
        headers.map((header, i) => [header, values[i]?.trim()])
      )
    })

  return JSON.stringify(rows, null, 2)
}

const csv = `server,port,region,status
api-gateway,8080,eu-north-1,healthy
auth-service,8443,eu-west-1,degraded
payments-api,9090,eu-central-1,healthy`

console.log(csvToJson(csv))
// [
//   { "server": "api-gateway", "port": "8080", "region": "eu-north-1", "status": "healthy" },
//   { "server": "auth-service", "port": "8443", "region": "eu-west-1", "status": "degraded" },
//   { "server": "payments-api", "port": "9090", "region": "eu-central-1", "status": "healthy" }
// ]

Den funktionen hanterar grunderna: avslutande radbrytningar, tomma rader, mellanslag runt värden. Varje CSV-fält kommer igenom som en sträng. Notera att port är "8080" (en sträng), inte 8080 (ett tal). Om du behöver korrekta typer i JSON-utdata måste du tvinga dem själv. Här är en utökad version med typdetektering:

JavaScript — csvToJson med typtvång
function coerceValue(val) {
  if (val === undefined || val === '') return null
  if (val === 'true') return true
  if (val === 'false') return false
  if (val === 'null') return null
  const num = Number(val)
  if (!isNaN(num) && val.trim() !== '') return num
  return val
}

function csvToJson(csv, { coerce = false } = {}) {
  const lines = csv.trim().split('\n')
  const headers = lines[0].split(',').map(h => h.trim())

  const rows = lines.slice(1)
    .filter(line => line.trim() !== '')
    .map(line => {
      const values = line.split(',')
      return Object.fromEntries(
        headers.map((header, i) => [
          header,
          coerce ? coerceValue(values[i]?.trim()) : values[i]?.trim()
        ])
      )
    })

  return JSON.stringify(rows, null, 2)
}

const csv = `endpoint,port,max_connections,debug
/api/v2/orders,8443,500,true
/api/v2/health,8080,100,false`

console.log(csvToJson(csv, { coerce: true }))
// [
//   { "endpoint": "/api/v2/orders", "port": 8443, "max_connections": 500, "debug": true },
//   { "endpoint": "/api/v2/health", "port": 8080, "max_connections": 100, "debug": false }
// ]

Flaggan coerce är opt-in eftersom automatisk typdetektering kan slå tillbaka — ett fält som ett postnummer ("07302") förlorar sin inledande nolla när det konverteras till ett tal. Håll typtvång avstängt som standard och aktivera det bara när du kontrollerar schemat. En snabb notis: JSON.stringify() accepterar ett tredje space argument för indentering. Skicka 2 för två mellanslag, 4 för fyra, eller "\t" för tabbar. Utelämna det helt för kompakt enkelsradsutdata — användbart när du skickar JSON-strängen som en API-förfrågans brödtext där blanktecken bara slösar bandbredd.

Obs:En rå CSV-sträng är inte JSON. Att anropa JSON.parse() direkt på CSV-text kastar ett SyntaxError. Du måste först konvertera CSV:n till JavaScript-objekt med din csvToJson()-funktion, som internt anropar JSON.stringify() för att producera den faktiska JSON-strängen.

Hantera Maps, datum och anpassade objekt från CSV-data

Inte varje CSV-konvertering slutar med en platt array av vanliga objekt. Ibland behöver du bygga en Map från rubrik-värde-par, parsa datumsträngar till Date-objekt eller fästa beräknade egenskaper innan serialisering. JavaScript har ett quirk som lurar folk: Map-instanser serialiseras inte med JSON.stringify(). Du får ett tomt objekt. Lösningen är Object.fromEntries() för att konvertera Map tillbaka till ett vanligt objekt innan stringifiering.

Anledningen till att Map serialiseras till {} är att JSON.stringify() itererar över ett objekts egna uppräkningsbara egenskaper. En Map lagrar sina poster i en intern slot, inte som uppräkningsbara egenskaper på objektet självt, så serialiseraren ser ett objekt utan nycklar. Map-prototypen saknar också en toJSON() metod, som är kroken JSON.stringify() anropar först på vilket värde som helst innan den bestämmer hur det ska serialiseras. Om ett värde har toJSON(), är metodens returvärde det som serialiseras — inte objektet självt. Det är därför Date objekt serialiseras korrekt: Date.prototype.toJSON returnerar en ISO 8601-sträng, så JSON.stringify(new Date()) producerar en citerad tidsstämpel snarare än ett tomt objekt. Att förstå denna krok låter dig definiera samma beteende på dina egna klasser — som visas i EmployeeRecord exemplet nedan — för att kontrollera exakt vilka CSV-härledda fält som visas i den slutliga JSON-utdata.

Konvertera en Map till JSON

JavaScript — Map till JSON via Object.fromEntries()
// Bygg en Map från CSV rubrik→värde-par
const headers = ['server', 'port', 'region']
const values = ['payments-api', '9090', 'eu-central-1']
const rowMap = new Map(headers.map((h, i) => [h, values[i]]))

// Map serialiseras INTE direkt
console.log(JSON.stringify(rowMap))
// "{}"  — tomt objekt, data förlorad!

// Konvertera till vanligt objekt först
const rowObj = Object.fromEntries(rowMap)
console.log(JSON.stringify(rowObj, null, 2))
// {
//   "server": "payments-api",
//   "port": "9090",
//   "region": "eu-central-1"
// }

Datumsträngar och toJSON()

CSV-datumfält anländer som strängar. Om du parsar dem till Date-objekt under bearbetningen serialiseras dessa datum korrekt eftersom Date har en inbyggd toJSON() metod som returnerar en ISO 8601-sträng. Du kan också definiera anpassade toJSON() på dina egna klasser för att kontrollera vilka CSV-kolumner som visas i den serialiserade utdata — till exempel utelämna interna spårningsfält som _rowIndex.

JavaScript — toJSON() för anpassad serialisering
class EmployeeRecord {
  constructor(csvRow) {
    this._rowIndex = csvRow._rowIndex  // internt, inte för JSON
    this.employeeId = csvRow.employee_id
    this.name = csvRow.name
    this.hiredAt = new Date(csvRow.hired_date)
    this.salary = Number(csvRow.salary)
  }

  toJSON() {
    // Exponera bara fält vi vill ha i JSON-utdata
    return {
      employee_id: this.employeeId,
      name: this.name,
      hired_at: this.hiredAt,  // Date.toJSON() → ISO-sträng automatiskt
      salary: this.salary,
    }
  }
}

const csvRow = {
  _rowIndex: 42,
  employee_id: 'EMP-2847',
  name: 'Erik Johansson',
  hired_date: '2024-03-15',
  salary: '128000',
}

const record = new EmployeeRecord(csvRow)
console.log(JSON.stringify(record, null, 2))
// {
//   "employee_id": "EMP-2847",
//   "name": "Erik Johansson",
//   "hired_at": "2024-03-15T00:00:00.000Z",
//   "salary": 128000
// }
// Obs: _rowIndex är exkluderat, lön är ett tal, datum är i ISO-format

Reviver för datumdeserialisering

Efter att ha skrivit CSV-härledd JSON till en fil eller skickat den över nätverket ger JSON.parse() tillbaka vanliga objekt — Date-objekten blir strängar igen. Använd en reviver-funktion för att konvertera ISO 8601-strängar tillbaka till Date-objekt under parsning:

JavaScript — reviver för att rekonstruera Date-objekt
const jsonString = '{"employee_id":"EMP-2847","name":"Erik Johansson","hired_at":"2024-03-15T00:00:00.000Z","salary":128000}'

const isoDatePattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/

const parsed = JSON.parse(jsonString, (key, value) => {
  if (typeof value === 'string' && isoDatePattern.test(value)) {
    return new Date(value)
  }
  return value
})

console.log(parsed.hired_at instanceof Date)  // true
console.log(parsed.hired_at.getFullYear())    // 2024
Varning:JSON.stringify() returnerar undefined (inte en sträng) för värden som innehåller funktioner, Symbols eller undefined-egenskaper. Om dina CSV-härledda objekt råkar plocka upp ett undefined-värde från en saknad kolumn försvinner den egenskapen tyst från JSON-utdata. Använd alltid null som standard för saknade värden istället.

JSON.stringify() parametrar — referens

Funktionssignaturen är JSON.stringify(value, replacer?, space?). Argumenten replacer och space är båda valfria — skicka null för replacer när du bara behöver indentering.

Parameter
Typ
Standard
Beskrivning
value
any
(obligatorisk)
JavaScript-värdet som ska serialiseras — objekt, array, sträng, tal, boolean eller null
replacer
Function | Array | null
undefined
Filtrera eller transformera värden under serialisering. Array vitlistar egenskapsnamn; funktion tar emot (key, value)-par
space
number | string
undefined
Indentering: tal 0–10 för mellanslag, sträng (t.ex. "\t") för anpassad indentering. Utelämna för kompakt enkelsradsutdata

JSON.parse() parametrar:

Parameter
Typ
Standard
Beskrivning
text
string
(obligatorisk)
JSON-strängen som ska parsas — måste vara giltig JSON, annars kastas SyntaxError
reviver
Function | undefined
undefined
Anropas för varje nyckel-värde-par. Returvärdet ersätter originalet; returnera undefined för att ta bort egenskapen

JSON.parse() — Konsumera JSON-utdata

När du har en JSON-sträng från csvToJson()är nästa steg vanligtvis att parsa tillbaka den till en levande JavaScript-array för filtrering, mappning eller matning till ett API. Skillnaden mellan en JSON-sträng (typeof === "string") och ett JavaScript-objekt spelar roll. Du kan inte anropa .filter() eller komma åt [0].name på en sträng — du behöver JSON.parse() först. Denna rundtur (stringify sedan parse) fungerar också som en valideringsteknik: om din CSV-konvertering producerade något som inte är giltig JSON kastar parse. Det valfriareviver-argumentet låter dig transformera varje nyckel-värde-par under parsning — användbart för att återställa Date-objekt från ISO-strängar eller byta namn på nycklar utan ett separat genomgångspass.

JavaScript — parsa JSON-utdata och fråga rader
const csv = `endpoint,method,avg_latency_ms,error_rate
/api/v2/orders,POST,342,0.02
/api/v2/health,GET,12,0.00
/api/v2/payments,POST,890,0.15
/api/v2/users,GET,45,0.01`

// Steg 1: konvertera CSV till JSON-sträng
const jsonString = csvToJson(csv, { coerce: true })

// Steg 2: parsa tillbaka till JavaScript-array
const endpoints = JSON.parse(jsonString)

// Verifiera att det är en array
console.log(Array.isArray(endpoints))  // true

// Filtrera slutpunkter med hög latens
const slow = endpoints.filter(ep => ep.avg_latency_ms > 200)
console.log(slow.map(ep => ep.endpoint))
// ["/api/v2/orders", "/api/v2/payments"]

// Destrukturera den första raden
const [first, ...rest] = endpoints
console.log(first.endpoint)  // "/api/v2/orders"
console.log(rest.length)     // 3

En säker omslutning för JSON.parse() är användbar när du validerar konverteringsutdata innan nedströmsbearbetning. Om CSV-konverteringen producerar felaktig JSON av någon anledning (trunkerad indata, kodningsfel) fångar detta det utan att krascha:

JavaScript — säker parse-omslutning
function safeParse(jsonString) {
  try {
    return { data: JSON.parse(jsonString), error: null }
  } catch (err) {
    return { data: null, error: err.message }
  }
}

// Giltig utdata
const result = safeParse(csvToJson(csv))
if (result.error) {
  console.error('CSV-konvertering producerade ogiltig JSON:', result.error)
} else {
  console.log(`Parsade ${result.data.length} rader`)
}

// Av misstag skicka rå CSV till JSON.parse — detta misslyckas
const bad = safeParse('name,email\nErik,erik@nexuslabs.se')
console.log(bad.error)  // "Unexpected token 'a', "name,email"... is not valid JSON"

Reviver för nyckelnamnsändring och validering

Reviver-funktionen tar emot varje nyckel-värde-par under parsning, från de innersta egenskaperna utåt. Att returnera undefined för en nyckel tar bort den från resultatet helt; att returnera ett annat värde ersätter det. Revivern är användbar för att byta namn på rubriker (camelCase till snake_case), ta bort interna fält eller kontrollera att obligatoriska kolumner finns. Den anropas med rotvärdet sist (tom strängnyckel), vilket är där du kastar om resultatet inte är en array.

JavaScript — reviver för nyckelnamnsändring och formvalidering
const jsonString = csvToJson(`employeeId,firstName,hiredDate
EMP-2847,Erik,2024-03-15
EMP-3012,Anna,2023-11-01`, { coerce: false })

const camelToSnake = str => str.replace(/[A-Z]/g, c => '_' + c.toLowerCase())

const employees = JSON.parse(jsonString, function(key, value) {
  // Rotvärde — validera form
  if (key === '') {
    if (!Array.isArray(value)) throw new Error('Förväntade JSON-array från CSV')
    return value
  }
  // Byt namn på camelCase-rubriknycklar till snake_case
  if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
    return Object.fromEntries(
      Object.entries(value).map(([k, v]) => [camelToSnake(k), v])
    )
  }
  return value
})

console.log(employees[0])
// { employee_id: 'EMP-2847', first_name: 'Erik', hired_date: '2024-03-15' }

Konvertera CSV från en fil och API-svar

De två ställena CSV-data faktiskt kommer ifrån i produktion: filer på disk och HTTP-svar. Båda scenarier behöver felhantering eftersom indata är extern och okontrollerad.

Läs CSV-fil, konvertera, skriv JSON

Node.js 18+ — filkonvertering
import { readFileSync, writeFileSync } from 'node:fs'

function csvToJsonFromFile(inputPath, outputPath) {
  let csvText
  try {
    csvText = readFileSync(inputPath, 'utf8')
  } catch (err) {
    throw new Error(`Misslyckades med att läsa ${inputPath}: ${err.message}`)
  }

  const lines = csvText.trim().split('\n')
  if (lines.length < 2) {
    throw new Error(`${inputPath} har inga datarader (bara ${lines.length} rad)`)
  }

  const headers = lines[0].split(',').map(h => h.trim())
  const rows = lines.slice(1)
    .filter(line => line.trim() !== '')
    .map(line => {
      const values = line.split(',')
      return Object.fromEntries(headers.map((h, i) => [h, values[i]?.trim()]))
    })

  const jsonOutput = JSON.stringify(rows, null, 2)
  writeFileSync(outputPath, jsonOutput, 'utf8')
  console.log(`Konverterade ${rows.length} rader → ${outputPath}`)
  return rows
}

// Användning
const data = csvToJsonFromFile('inventory.csv', 'inventory.json')
console.log(data[0])
// { sku: "WDG-2847", warehouse: "eu-north-1", quantity: "150", ... }

Hämta CSV från en API-slutpunkt

Node.js 18+ — API-svarskonvertering
async function fetchCsvAsJson(url) {
  const response = await fetch(url)
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.statusText}`)
  }

  const contentType = response.headers.get('content-type') || ''
  if (!contentType.includes('text/csv') && !contentType.includes('text/plain')) {
    console.warn(`Oväntat content-type: ${contentType}`)
  }

  const csvText = await response.text()
  const lines = csvText.trim().split('\n')
  const headers = lines[0].split(',').map(h => h.trim())
  const rows = lines.slice(1)
    .filter(line => line.trim() !== '')
    .map(line => {
      const values = line.split(',')
      return Object.fromEntries(headers.map((h, i) => [h, values[i]?.trim()]))
    })

  return rows
}

// Exempel: hämta valutakurs-CSV från en dataleverantör
try {
  const rates = await fetchCsvAsJson('https://data.ecb.internal/rates/daily.csv')
  console.log(JSON.stringify(rates.slice(0, 3), null, 2))
  // Skicka som JSON till nedströmstjänst
  await fetch('https://api.internal/v2/rates', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ data: rates }),
  })
} catch (err) {
  console.error('Kurssynkronisering misslyckades:', err.message)
}
Obs:Replacer-argumentet i JSON.stringify() låter dig vitlista specifika kolumner från CSV:n. Skicka en array med rubriknamn för att inkludera bara de fälten: JSON.stringify(rows, ['name', 'email', 'department']). Egenskaper som inte finns i arrayen exkluderas tyst från utdata.

CSV till JSON-konvertering via kommandoraden

Node.js kan köra inline-skript, och det finns dedikerade CLI-verktyg som hanterar CSV-till-JSON-konvertering utan att skriva ett skript.

bash — Node.js en-liner
# Pipe CSV till ett Node.js inline-skript
cat servers.csv | node -e "
  const lines = require('fs').readFileSync('/dev/stdin','utf8').trim().split('\n');
  const h = lines[0].split(',');
  const rows = lines.slice(1).map(l => Object.fromEntries(h.map((k,i) => [k.trim(), l.split(',')[i]?.trim()])));
  console.log(JSON.stringify(rows, null, 2));
"
bash — Miller (mlr) för CSV till JSON
# Miller är en schweizisk armékniv för strukturerad data
# Installera: brew install miller (macOS) eller apt install miller (Debian/Ubuntu)
mlr --icsv --ojson cat inventory.csv

# Filtrera rader under konvertering
mlr --icsv --ojson filter '$quantity > 100' inventory.csv

# Välj specifika kolumner
mlr --icsv --ojson cut -f sku,warehouse,quantity inventory.csv
bash — csvtojson CLI
# Installera globalt
npm install -g csvtojson

# Konvertera fil
csvtojson servers.csv > servers.json

# Pipe från stdin
cat exports/q1-metrics.csv | csvtojson > q1-metrics.json

För stora filer är Miller vanligtvis det bättre valet framför csvtojson. Miller är implementerat i C och bearbetar CSV som en ström utan att ladda hela filen i minnet, vilket innebär att det hanterar gigabyte-stora exporter med konstant minnesanvändning. Det stöder också in-place fältnivåoperationer — byta namn på kolumner, typomvandla värden, filtrera rader — innan datan ens blir JSON, så du undviker en tvåstegs parse-sedan-transformera-pipeline. csvtojson, å andra sidan, körs i Node.js och är mer bekvämt när resten av din verktygskedja är JavaScript: du kan piping dess utdata direkt till Node.js-strömmar, importera det som ett bibliotek eller använda dess colParser API för per-kolumn-typtvång i kod. Föredra Miller för rå genomströmning och skalrörledningar; föredra csvtojson när du behöver tät integration med en Node.js-applikation.

Obs:jq parsar inte CSV nativt. Om du behöver jq i pipelinen, konvertera till JSON först med csvtojson eller mlr, piping sedan JSON-utdata till jq för filtrering och transformation.

Högpresterande alternativ — PapaParse

Den manuella split(',') metoden misslyckas på verkliga CSV-filer. Citerade fält med kommatecken, inbäddade radbrytningar, escapade dubbla citattecken — alla dessa bryter en naiv splitter. PapaParse är biblioteket jag väljer när CSV:n kommer från en okänd källa. Det hanterar varje RFC 4180 kantfall, autodetekterar avgränsare och fungerar i både Node.js och webbläsare.

bash — installera PapaParse
npm install papaparse
JavaScript — PapaParse med typtvång
import Papa from 'papaparse'

const csv = `product,description,price,in_stock
"Widget, Large","A premium widget with ""extra"" features",29.99,true
Bolt Assembly,Standard M8 bolt kit,4.50,true
"Gasket Set","Includes gasket, seal, and O-ring",12.75,false`

const { data, errors, meta } = Papa.parse(csv, {
  header: true,
  dynamicTyping: true,     // konverterar automatiskt tal och booleaner
  skipEmptyLines: true,
  transformHeader: h => h.trim().toLowerCase().replace(/\s+/g, '_'),
})

if (errors.length > 0) {
  console.error('Parsningsfel:', errors)
}

console.log(JSON.stringify(data, null, 2))
// [
//   {
//     "product": "Widget, Large",
//     "description": "A premium widget with \"extra\" features",
//     "price": 29.99,
//     "in_stock": true
//   },
//   ...
// ]
console.log(`Parsade ${data.length} rader, avgränsare: "${meta.delimiter}"`)

PapaParse:s dynamicTyping alternativ gör typtvånget automatiskt — tal blir tal, "true"/"false" blir booleaner. Återanropet transformHeader normaliserar kolumnnamn till snake_case, vilket sparar dig från att hantera inkonsekventa rubriker från olika CSV-exporter. För snabba konverteringar utan att skriva någon parsningskod hanterar CSV till JSON-konverteraren allt detta i webbläsaren.

Terminalutdata med syntaxmarkering

Att dumpa en stor JSON-array i terminalen gör att ögonen glasar över snabbt. Att lägga till syntaxmarkering i utdata gör det läsbart under felsökning och utveckling. Paketet cli-highlight färglägger JSON-utdata i Node.js-terminaler.

bash — installera cli-highlight
npm install cli-highlight
JavaScript — färglagd JSON-utdata i terminal
import { highlight } from 'cli-highlight'

// Efter att ha konverterat CSV till JSON-array
const jsonOutput = JSON.stringify(rows, null, 2)

// Skriv ut med syntaxmarkering
console.log(highlight(jsonOutput, { language: 'json' }))
// Nycklar, strängar, tal och booleaner får var sina distinkta färger

Färglagd utdata är värd sin plats när du inspekterar ett stort konverteringsresultat interaktivt. JSON-nycklar, strängvärden, tal och booleaner får var sina distinkta ANSI-färger, vilket gör det enkelt att upptäcka ett fält vars typ är fel — till exempel ett portnummer som borde vara 8080 men är markerat som en sträng eftersom typtvång var avstängt. Detta är särskilt användbart vid felsökning av CSV-filer exporterade från kalkylbladsverktyg där kolumntyper är inkonsekventa mellan rader. Utan färg innebär att skanna 50 rader JSON för ett enda felaktigt fält att läsa varje värde individuellt. Med färg hoppar ett strängfärgat tal ut direkt.

Varning:Syntaxmarkering lägger till ANSI-escapekoder i utdata. Använd det inte när du skriver JSON till en fil, piping till ett annat program eller skickar som ett API-svarsorgan — escapekoderna skulle korruptera JSON. Använd bara markering för terminalvisning.

Arbeta med stora CSV-filer

Att ladda en 500 MB CSV-fil till en sträng med readFileSync() äter minne och kan potentiellt krascha din process. För stora filer, strömma CSV:n rad för rad och emittera JSON-objekt när de anländer. Paketet csv-parse (del av csv-ekosystemet på npm) tillhandahåller en strömmande parser som fungerar med Node.js-strömmar.

Strömma CSV till NDJSON med csv-parse

NDJSON (Newline-Delimited JSON) är ett format där varje rad i utdatafilen är ett självständigt JSON-objekt. Till skillnad från en enda stor JSON-array — som kräver att hela filen är i minnet innan du kan börja läsa den — kan NDJSON-filer bearbetas rad för rad. Detta gör NDJSON idealiskt för stora datamängder som kommer att konsumeras av loggprocessorer, strömpipelines eller databaser med bulk-import-API:er. csv-parsepaketet emitterar ett JavaScript-objekt per CSV-rad i objektläge, så du kan piping det direkt till en transformationsström som lägger till \n efter varje JSON.stringify(row).

Node.js 18+ — strömma CSV till NDJSON
import { createReadStream, createWriteStream } from 'node:fs'
import { parse } from 'csv-parse'
import { Transform } from 'node:stream'
import { pipeline } from 'node:stream/promises'

// Transformera varje CSV-radobjekt till en JSON-rad
const toNdjson = new Transform({
  objectMode: true,
  transform(record, encoding, callback) {
    callback(null, JSON.stringify(record) + '\n')
  },
})

await pipeline(
  createReadStream('telemetry-2026-03.csv'),
  parse({
    columns: true,       // använd första raden som rubriker
    skip_empty_lines: true,
    trim: true,
    cast: true,          // konvertera automatiskt tal och booleaner
  }),
  toNdjson,
  createWriteStream('telemetry-2026-03.ndjson')
)

console.log('Strömmande konvertering klar')
// Varje rad i utdatafilen är ett JSON-objekt:
// {"timestamp":"2026-03-15T08:22:00Z","service":"gateway","latency_ms":42,"status":200}
// {"timestamp":"2026-03-15T08:22:01Z","service":"auth","latency_ms":156,"status":401}
// ...

PapaParse-strömning för webbläsare och Node.js

PapaParse:s strömmande läge använder ett step återanrop som utlöses en gång per rad istället för att samla alla rader i minnet. Du skickar det en Node.js ReadStream (i Node.js) eller ett File objekt (i webbläsaren) och PapaParse hanterar chunking internt. Ingen strömpipeline att koppla ihop — bara ett återanrop. Använd det när du behöver RFC 4180-efterlevnad utan att dra in csv-parse.

Node.js — PapaParse strömmande stor fil
import Papa from 'papaparse'
import { createReadStream } from 'node:fs'

let rowCount = 0
const errors = []

const fileStream = createReadStream('warehouse-inventory.csv')

Papa.parse(fileStream, {
  header: true,
  dynamicTyping: true,
  step(result) {
    // Bearbeta en rad åt gången — konstant minne
    rowCount++
    if (result.data.quantity === 0) {
      errors.push(`Rad ${rowCount}: ${result.data.sku} är slut i lager`)
    }
  },
  complete() {
    console.log(`Bearbetade ${rowCount} rader`)
    if (errors.length > 0) {
      console.log(`Problem hittades: ${errors.length}`)
      errors.forEach(e => console.log(`  ${e}`))
    }
  },
  error(err) {
    console.error('Parsning misslyckades:', err.message)
  },
})
Obs:Byt till strömning när din CSV-fil överstiger 50 MB eller när du bearbetar en obegränsad indata (WebSocket-flöde, server-sent events, pipad stdin). NDJSON-formatet (ett JSON-objekt per rad) är ofta ett bättre utdataformat än en jättelik JSON-array för stora datamängder — det kan bearbetas rad för rad utan att ladda hela filen i minnet.

Vanliga misstag

Anropa JSON.parse() direkt på en CSV-sträng

Problem: CSV är inte JSON. Att skicka en rå CSV-sträng till JSON.parse() kastar ett SyntaxError eftersom kommatecken och radbrytningar inte är giltig JSON-syntax.

Lösning: Parsa CSV:n till JavaScript-objekt först med split() eller ett bibliotek, använd sedan JSON.stringify() för att producera JSON. Anropa bara JSON.parse() på strängar som redan är giltig JSON.

Before · JavaScript
After · JavaScript
const csv = 'name,email\nErik Johansson,erik@nexuslabs.se'
const data = JSON.parse(csv)
// SyntaxError: Unexpected token 'a'
const csv = 'name,email\nErik Johansson,erik@nexuslabs.se'
const lines = csv.trim().split('\n')
const headers = lines[0].split(',')
const rows = lines.slice(1).map(line =>
  Object.fromEntries(headers.map((h, i) => [h, line.split(',')[i]]))
)
const json = JSON.stringify(rows, null, 2)  // giltig JSON-sträng
Använda toString() istället för JSON.stringify()

Problem: Att anropa toString() på ett JavaScript-objekt returnerar den värdelösa strängen '[object Object]' istället för den faktiska datan. Detta förstör tyst din CSV-till-JSON-utdata.

Lösning: Använd alltid JSON.stringify() för att konvertera JavaScript-objekt till JSON-strängar. toString() finns för primitiv-till-sträng-tvång, inte för serialisering.

Before · JavaScript
After · JavaScript
const row = { server: 'api-gateway', port: 8080 }
const output = row.toString()
// "[object Object]"  — data är borta
const row = { server: 'api-gateway', port: 8080 }
const output = JSON.stringify(row, null, 2)
// '{"server":"api-gateway","port":8080}'
Dela på kommatecken utan att hantera citerade fält

Problem: En naiv split(",") bryter när CSV-värden innehåller kommatecken inuti citerade fält: "Widget, Large" blir två separata värden istället för ett.

Lösning: Använd PapaParse eller csv-parse för all CSV-data du inte fullständigt kontrollerar. Om du måste parsa manuellt, implementera en tillståndsmaskin-parser som spårar om den aktuella positionen är inuti ett citerat fält.

Before · JavaScript
After · JavaScript
const line = '"Widget, Large","Premium quality",29.99'
const values = line.split(',')
// ["\"Widget", " Large\"", "\"Premium quality\"", "29.99"]
// 4 värden istället för 3 — första fältet delat felaktigt
import Papa from 'papaparse'
const { data } = Papa.parse('"Widget, Large","Premium quality",29.99')
// data[0] = ["Widget, Large", "Premium quality", "29.99"]
// 3 värden, korrekt parsade
Glömma att alla CSV-värden är strängar

Problem: Utan typtvång förblir port: "8080" en sträng i JSON istället för ett tal. Nedströmssystem som förväntar sig numeriska typer avvisar eller hanterar data felaktigt.

Lösning: Tillämpa explicit typtvång under mappningssteget, eller använd PapaParse med dynamicTyping: true. Var alltid medveten om vilka fält som ska vara numeriska.

Before · JavaScript
After · JavaScript
const row = { port: '8443', debug: 'true', workers: '4' }
JSON.stringify(row)
// {"port":"8443","debug":"true","workers":"4"}  — alla strängar
const row = {
  port: Number('8443'),           // 8443
  debug: 'true' === 'true',      // true
  workers: Number('4'),           // 4
}
JSON.stringify(row)
// {"port":8443,"debug":true,"workers":4}  — korrekta typer

Manuell parsning mot bibliotek — snabb jämförelse

Metod
Formaterad utdata
Giltig JSON
Anpassade typer
Streaming
Kräver installation
JSON.stringify()
✓ (med space)
✓ via toJSON()/replacer
Nej (inbyggd)
JSON.parse()
Ej aktuellt (parsning)
✓ (validerar)
✓ via reviver
Nej (inbyggd)
csv-parse (Node.js)
✗ (returnerar objekt)
✗ (inte JSON)
npm install
PapaParse
✗ (returnerar objekt)
✗ (inte JSON)
npm install
csvtojson
✓ via colParser
npm install
jq (CLI)
Ej aktuellt
Systeminstallation
Miller (CLI)
Ej aktuellt
Systeminstallation

För snabba skript där du kontrollerar CSV-formatet och vet att det inte finns några citerade fält, fungerar den inbyggda split() + JSON.stringify() metoden och kräver inga beroenden. För produktionssystem som bearbetar användarladdade CSV-filer, använd PapaParse i webbläsaren eller csv-parse i Node.js — båda hanterar RFC 4180 korrekt och stöder strömning. Paketet csvtojson är det enda som producerar JSON direkt och hanterar både parsning och serialisering i ett enda anrop. När du behöver den snabbaste vägen från inklistring till resultat hanterar CSV till JSON-konverteraren allt i webbläsaren utan någon konfiguration.

Vanliga frågor

Hur konverterar jag CSV till JSON i JavaScript utan ett bibliotek?

Dela CSV-strängen med radbrytning för att få rader, extrahera rubriker från den första raden med split(","), mappa sedan de återstående raderna till objekt med rubrikerna som nycklar. Avsluta med JSON.stringify(array, null, 2) för att producera en formaterad JSON-sträng. Den här metoden fungerar bra för enkla CSV-filer där du kontrollerar formatet och vet att det inte finns några citerade fält eller inbäddade kommatecken. För data från kalkylbladsexporter eller tredjepartssystem bryter citerade fält och flerradsvärden en naiv splitter — använd PapaParse eller csv-parse i sådana fall. För mycket små filer som bearbetas i webbläsaren är detta nollberoende-tillvägagångssättet idealiskt.

JavaScript
const csv = `name,email,department
Erik Johansson,erik@nexuslabs.se,Engineering
Anna Lindgren,anna@nexuslabs.se,Product`

const lines = csv.trim().split('\n')
const headers = lines[0].split(',')
const rows = lines.slice(1).map(line => {
  const values = line.split(',')
  return Object.fromEntries(headers.map((h, i) => [h.trim(), values[i]?.trim()]))
})

console.log(JSON.stringify(rows, null, 2))
// [
//   { "name": "Erik Johansson", "email": "erik@nexuslabs.se", "department": "Engineering" },
//   { "name": "Anna Lindgren", "email": "anna@nexuslabs.se", "department": "Product" }
// ]

Vad är skillnaden mellan JSON.stringify() och toString() för objekt?

toString() på ett vanligt objekt returnerar den värdelösa strängen "[object Object]" — den säger ingenting om den faktiska datan. JSON.stringify() producerar en giltig JSON-sträng med alla nycklar och värden korrekt serialiserade, inklusive nästlade objekt och arrayer. Använd alltid JSON.stringify() när du behöver konvertera ett JavaScript-objekt (som en CSV-härledd rad) till en JSON-sträng. För att vända operationen — rekonstruera levande JavaScript-objekt från en JSON-sträng — använd JSON.parse(), som är den exakta inversionen av JSON.stringify(). Dessa två funktioner bildar en komplett rundtur: stringify för att lagra eller sända data, parse för att konsumera den.

JavaScript
const row = { name: 'Erik Johansson', role: 'Engineer' }

console.log(row.toString())       // "[object Object]"
console.log(JSON.stringify(row))   // '{"name":"Erik Johansson","role":"Engineer"}'

Hur hanterar jag CSV-fält som innehåller kommatecken eller citattecken?

RFC 4180 anger att fält som innehåller kommatecken, radbrytningar eller dubbla citattecken måste omslutas av dubbla citattecken, där inbäddade citattecken escapes genom att fördubblas ("" inuti ett citerat fält representerar ett enda literalt citattecken). En manuell split(",") bryter på dessa filer — fältgränsen är inte längre ett enkelt kommatecken. Använd PapaParse eller csv-parse för produktionsdata, eller skriv en tillståndsmaskin-parser som spårar om du är inne i ett citerat fält. Att skriva en korrekt tillståndsmaskin från grunden är förvånansvärt knepigt: du måste hantera citattecken i början av ett fält, midfält-escapade citattecken, radbrytningar inuti citerade fält och olika radslutkonventioner (CRLF mot LF). För allt bortom leksaks-CSV-data, använd ett vältestat bibliotek.

JavaScript
// PapaParse hanterar RFC 4180 korrekt
import Papa from 'papaparse'

const csv = `product,description,price
"Widget, Large","A big ""widget""",29.99
Bolt,Standard bolt,1.50`

const { data } = Papa.parse(csv, { header: true })
console.log(JSON.stringify(data, null, 2))
// description-fältet innehåller korrekt: A big "widget"

Kan jag konvertera CSV till JSON direkt i webbläsaren?

Ja. Både JSON.stringify() och JSON.parse() är inbyggda i varje webbläsarmotor. För CSV-parsningssteget kan du dela med radbrytning och kommatecken för enkla filer, eller inkludera PapaParse via ett CDN (det har inga Node.js-beroenden). Hela konverteringen sker på klientsidan utan serveranrop, vilket är användbart för filsekretess — den råa CSV-datan lämnar aldrig användarens dator. När en användare laddar upp en CSV-fil via ett <input type="file">-element returnerar File API:s file.text()-metod ett Promise som löser till filens innehåll som en sträng, som du sedan kan skicka till din konverteringsfunktion. Detta gör fullständig in-webbläsare CSV-till-JSON-konvertering praktisk för instrumentpaneler, utvecklarverktyg och alla appar som behöver bearbeta uppladdad data utan en backend.

JavaScript
// Webbläsare: användaren laddar upp en CSV-fil
const fileInput = document.querySelector('input[type="file"]')
fileInput.addEventListener('change', async (event) => {
  const file = event.target.files[0]
  const text = await file.text()
  const lines = text.trim().split('\n')
  const headers = lines[0].split(',')
  const rows = lines.slice(1).map(line =>
    Object.fromEntries(headers.map((h, i) => [h.trim(), line.split(',')[i]?.trim()]))
  )
  console.log(JSON.stringify(rows, null, 2))
})

Hur parsar jag numeriska och booleska värden från CSV istället för att behålla allt som strängar?

CSV har inget typsystem — varje fält är en sträng. Du måste tvinga värden under mappningssteget. Kontrollera efter numeriska mönster med Number() eller parseFloat(), konvertera "true"/"false" till booleaner och hantera tomma strängar som null. Var försiktig med fält som ser ut som tal men måste förbli strängar: postnummer som "07302" förlorar sin inledande nolla när de tvingas med Number(), och telefonnummer eller produktkoder med numeriska tecken är på liknande sätt ömtåliga. csvtojson-biblioteket gör automatisk typtvång via dess colParser-alternativ, vilket låter dig specificera konverteringsfunktioner per kolumn och åsidosätta auto-detekteringen för problematiska kolumner. PapaParse:s dynamicTyping-alternativ tillämpar samma tvång globalt på alla kolumner.

JavaScript
function coerceValue(val) {
  if (val === '') return null
  if (val === 'true') return true
  if (val === 'false') return false
  const num = Number(val)
  if (!isNaN(num) && val.trim() !== '') return num
  return val
}

// Tillämpas under CSV-till-objekt-mappning
const row = { port: coerceValue('8443'), debug: coerceValue('true'), host: coerceValue('api.internal') }
// { port: 8443, debug: true, host: "api.internal" }

Hur skriver jag CSV-till-JSON-utdata till en fil i Node.js?

Använd fs.writeFileSync() med JSON.stringify()-utdata. Det tredje argumentet till JSON.stringify styr indenteringen — skicka 2 för tvåstegs-indragsrad eller "\t" för tabbar. För att läsa tillbaka filen, använd JSON.parse(fs.readFileSync(path, "utf8")), som rekonstruerar den levande JavaScript-arrayen av objekt. Om du skriver filen i ett asynkront sammanhang (inuti en async-funktion eller på toppnivå i en ES-modul), föredra fs.promises.writeFile() för att undvika att blockera händelseloopen medan filskrivningen slutförs. För stora JSON-utdatan över några megabyte, överväg att strömma en JSON-ström till en WriteStream istället för att bygga hela strängen i minnet innan skrivning.

JavaScript
import { writeFileSync, readFileSync } from 'node:fs'

// Skriv
const jsonOutput = JSON.stringify(rows, null, 2)
writeFileSync('employees.json', jsonOutput, 'utf8')

// Läs tillbaka
const parsed = JSON.parse(readFileSync('employees.json', 'utf8'))
console.log(Array.isArray(parsed))  // true
console.log(parsed[0].name)         // "Erik Johansson"

Relaterade verktyg

Finns även på:Python
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.

SL
Sophie LaurentTeknisk granskare

Sophie is a full-stack developer focused on TypeScript across the entire stack — from React frontends to Express and Fastify backends. She has a particular interest in type-safe API design, runtime validation, and the patterns that make large JavaScript codebases stay manageable. She writes about TypeScript idioms, Node.js internals, and the ever-evolving JavaScript module ecosystem.