CSV to JSON JavaScript — Converter + Code Examples
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.
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:
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:
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.
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
// 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.
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-formatReviver 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:
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()) // 2024JSON.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.
JSON.parse() parametrar:
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.
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) // 3En 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:
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.
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
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
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)
}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.
# 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));
"# 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
# 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.
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.
npm install papaparse
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.
npm install cli-highlight
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ärgerFä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.
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).
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.
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)
},
})Vanliga misstag
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.
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ängProblem: 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.
const row = { server: 'api-gateway', port: 8080 }
const output = row.toString()
// "[object Object]" — data är bortaconst row = { server: 'api-gateway', port: 8080 }
const output = JSON.stringify(row, null, 2)
// '{"server":"api-gateway","port":8080}'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.
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 felaktigtimport 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 parsadeProblem: 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.
const row = { port: '8443', debug: 'true', workers: '4' }
JSON.stringify(row)
// {"port":"8443","debug":"true","workers":"4"} — alla strängarconst row = {
port: Number('8443'), // 8443
debug: 'true' === 'true', // true
workers: Number('4'), // 4
}
JSON.stringify(row)
// {"port":8443,"debug":true,"workers":4} — korrekta typerManuell parsning mot bibliotek — snabb jämförelse
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.
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.
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.
// 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.
// 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.
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.
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
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.
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.