[{"data":1,"prerenderedAt":1225},["ShallowReactive",2],{"guide-large-csv-processing":3},{"id":4,"title":5,"body":6,"date":1217,"description":1218,"extension":1219,"meta":1220,"navigation":136,"path":1221,"readingTime":140,"seo":1222,"stem":1223,"__hash__":1224},"guides\u002Fguides\u002Flarge-csv-processing.md","Processing Large CSV Files in the Browser",{"type":7,"value":8,"toc":1206},"minimark",[9,14,18,21,25,37,386,389,393,396,412,419,531,534,538,541,699,706,710,713,780,783,917,921,924,1102,1108,1112,1159,1163,1190,1194,1202],[10,11,13],"h2",{"id":12},"the-browser-memory-problem","The Browser Memory Problem",[15,16,17],"p",{},"Opening a 500MB CSV file in the browser sounds straightforward — read the file, parse it, display it. But browsers allocate memory for the raw file, the parsed string, the array of rows, and often a duplicate for transformation. A 500MB CSV can easily consume 2GB of RAM, exceeding the typical tab's memory limit and causing an out-of-crash.",[15,19,20],{},"The solution is not a bigger machine. It is processing the file incrementally — reading chunks, transforming rows one at a time, and never holding the entire dataset in memory simultaneously.",[10,22,24],{"id":23},"streaming-file-reads","Streaming File Reads",[15,26,27,28,32,33,36],{},"The ",[29,30,31],"code",{},"File"," API combined with ",[29,34,35],{},"ReadableStream"," lets you read files in manageable chunks rather than loading everything at once:",[38,39,44],"pre",{"className":40,"code":41,"language":42,"meta":43,"style":43},"language-javascript shiki shiki-themes github-light github-dark","async function processFile(file) {\n  const stream = file.stream();\n  const reader = stream.getReader();\n  const decoder = new TextDecoder();\n\n  let buffer = '';\n\n  while (true) {\n    const { done, value } = await reader.read();\n    if (done) break;\n\n    buffer += decoder.decode(value, { stream: true });\n    const lines = buffer.split('\\n');\n\n    \u002F\u002F Keep the last (potentially incomplete) line in the buffer\n    buffer = lines.pop();\n\n    for (const line of lines) {\n      processRow(line);\n    }\n  }\n\n  \u002F\u002F Process any remaining data\n  if (buffer) processRow(buffer);\n}\n","javascript","",[29,45,46,73,95,113,131,138,157,162,176,210,224,229,252,281,286,293,308,313,333,342,348,354,359,365,380],{"__ignoreMap":43},[47,48,51,55,58,62,66,70],"span",{"class":49,"line":50},"line",1,[47,52,54],{"class":53},"szBVR","async",[47,56,57],{"class":53}," function",[47,59,61],{"class":60},"sScJk"," processFile",[47,63,65],{"class":64},"sVt8B","(",[47,67,69],{"class":68},"s4XuR","file",[47,71,72],{"class":64},") {\n",[47,74,76,79,83,86,89,92],{"class":49,"line":75},2,[47,77,78],{"class":53},"  const",[47,80,82],{"class":81},"sj4cs"," stream",[47,84,85],{"class":53}," =",[47,87,88],{"class":64}," file.",[47,90,91],{"class":60},"stream",[47,93,94],{"class":64},"();\n",[47,96,98,100,103,105,108,111],{"class":49,"line":97},3,[47,99,78],{"class":53},[47,101,102],{"class":81}," reader",[47,104,85],{"class":53},[47,106,107],{"class":64}," stream.",[47,109,110],{"class":60},"getReader",[47,112,94],{"class":64},[47,114,116,118,121,123,126,129],{"class":49,"line":115},4,[47,117,78],{"class":53},[47,119,120],{"class":81}," decoder",[47,122,85],{"class":53},[47,124,125],{"class":53}," new",[47,127,128],{"class":60}," TextDecoder",[47,130,94],{"class":64},[47,132,134],{"class":49,"line":133},5,[47,135,137],{"emptyLinePlaceholder":136},true,"\n",[47,139,141,144,147,150,154],{"class":49,"line":140},6,[47,142,143],{"class":53},"  let",[47,145,146],{"class":64}," buffer ",[47,148,149],{"class":53},"=",[47,151,153],{"class":152},"sZZnC"," ''",[47,155,156],{"class":64},";\n",[47,158,160],{"class":49,"line":159},7,[47,161,137],{"emptyLinePlaceholder":136},[47,163,165,168,171,174],{"class":49,"line":164},8,[47,166,167],{"class":53},"  while",[47,169,170],{"class":64}," (",[47,172,173],{"class":81},"true",[47,175,72],{"class":64},[47,177,179,182,185,188,191,194,197,199,202,205,208],{"class":49,"line":178},9,[47,180,181],{"class":53},"    const",[47,183,184],{"class":64}," { ",[47,186,187],{"class":81},"done",[47,189,190],{"class":64},", ",[47,192,193],{"class":81},"value",[47,195,196],{"class":64}," } ",[47,198,149],{"class":53},[47,200,201],{"class":53}," await",[47,203,204],{"class":64}," reader.",[47,206,207],{"class":60},"read",[47,209,94],{"class":64},[47,211,213,216,219,222],{"class":49,"line":212},10,[47,214,215],{"class":53},"    if",[47,217,218],{"class":64}," (done) ",[47,220,221],{"class":53},"break",[47,223,156],{"class":64},[47,225,227],{"class":49,"line":226},11,[47,228,137],{"emptyLinePlaceholder":136},[47,230,232,235,238,241,244,247,249],{"class":49,"line":231},12,[47,233,234],{"class":64},"    buffer ",[47,236,237],{"class":53},"+=",[47,239,240],{"class":64}," decoder.",[47,242,243],{"class":60},"decode",[47,245,246],{"class":64},"(value, { stream: ",[47,248,173],{"class":81},[47,250,251],{"class":64}," });\n",[47,253,255,257,260,262,265,268,270,273,276,278],{"class":49,"line":254},13,[47,256,181],{"class":53},[47,258,259],{"class":81}," lines",[47,261,85],{"class":53},[47,263,264],{"class":64}," buffer.",[47,266,267],{"class":60},"split",[47,269,65],{"class":64},[47,271,272],{"class":152},"'",[47,274,275],{"class":81},"\\n",[47,277,272],{"class":152},[47,279,280],{"class":64},");\n",[47,282,284],{"class":49,"line":283},14,[47,285,137],{"emptyLinePlaceholder":136},[47,287,289],{"class":49,"line":288},15,[47,290,292],{"class":291},"sJ8bj","    \u002F\u002F Keep the last (potentially incomplete) line in the buffer\n",[47,294,296,298,300,303,306],{"class":49,"line":295},16,[47,297,234],{"class":64},[47,299,149],{"class":53},[47,301,302],{"class":64}," lines.",[47,304,305],{"class":60},"pop",[47,307,94],{"class":64},[47,309,311],{"class":49,"line":310},17,[47,312,137],{"emptyLinePlaceholder":136},[47,314,316,319,321,324,327,330],{"class":49,"line":315},18,[47,317,318],{"class":53},"    for",[47,320,170],{"class":64},[47,322,323],{"class":53},"const",[47,325,326],{"class":81}," line",[47,328,329],{"class":53}," of",[47,331,332],{"class":64}," lines) {\n",[47,334,336,339],{"class":49,"line":335},19,[47,337,338],{"class":60},"      processRow",[47,340,341],{"class":64},"(line);\n",[47,343,345],{"class":49,"line":344},20,[47,346,347],{"class":64},"    }\n",[47,349,351],{"class":49,"line":350},21,[47,352,353],{"class":64},"  }\n",[47,355,357],{"class":49,"line":356},22,[47,358,137],{"emptyLinePlaceholder":136},[47,360,362],{"class":49,"line":361},23,[47,363,364],{"class":291},"  \u002F\u002F Process any remaining data\n",[47,366,368,371,374,377],{"class":49,"line":367},24,[47,369,370],{"class":53},"  if",[47,372,373],{"class":64}," (buffer) ",[47,375,376],{"class":60},"processRow",[47,378,379],{"class":64},"(buffer);\n",[47,381,383],{"class":49,"line":382},25,[47,384,385],{"class":64},"}\n",[15,387,388],{},"This approach keeps memory usage roughly constant regardless of file size because only the current chunk and buffer remain in memory at any time.",[10,390,392],{"id":391},"chunked-parsing-strategy","Chunked Parsing Strategy",[15,394,395],{},"CSV parsing gets tricky at chunk boundaries — a chunk might split a row that contains quoted fields with embedded newlines. Handle this by buffering partial lines:",[397,398,399,403,406,409],"ol",{},[400,401,402],"li",{},"Append each chunk to a string buffer.",[400,404,405],{},"Split on newlines.",[400,407,408],{},"Keep the last segment in the buffer (it may be incomplete).",[400,410,411],{},"Parse complete lines only.",[15,413,414,415,418],{},"For robust parsing, use a streaming CSV parser like ",[29,416,417],{},"papaparse"," in stream mode:",[38,420,422],{"className":40,"code":421,"language":42,"meta":43,"style":43},"Papa.parse(file, {\n  header: true,\n  chunk: function(results) {\n    for (const row of results.data) {\n      processRow(row);\n    }\n  },\n  complete: function() {\n    console.log('Processing complete');\n  }\n});\n",[29,423,424,435,445,463,479,486,490,495,507,522,526],{"__ignoreMap":43},[47,425,426,429,432],{"class":49,"line":50},[47,427,428],{"class":64},"Papa.",[47,430,431],{"class":60},"parse",[47,433,434],{"class":64},"(file, {\n",[47,436,437,440,442],{"class":49,"line":75},[47,438,439],{"class":64},"  header: ",[47,441,173],{"class":81},[47,443,444],{"class":64},",\n",[47,446,447,450,453,456,458,461],{"class":49,"line":97},[47,448,449],{"class":60},"  chunk",[47,451,452],{"class":64},": ",[47,454,455],{"class":53},"function",[47,457,65],{"class":64},[47,459,460],{"class":68},"results",[47,462,72],{"class":64},[47,464,465,467,469,471,474,476],{"class":49,"line":115},[47,466,318],{"class":53},[47,468,170],{"class":64},[47,470,323],{"class":53},[47,472,473],{"class":81}," row",[47,475,329],{"class":53},[47,477,478],{"class":64}," results.data) {\n",[47,480,481,483],{"class":49,"line":133},[47,482,338],{"class":60},[47,484,485],{"class":64},"(row);\n",[47,487,488],{"class":49,"line":140},[47,489,347],{"class":64},[47,491,492],{"class":49,"line":159},[47,493,494],{"class":64},"  },\n",[47,496,497,500,502,504],{"class":49,"line":164},[47,498,499],{"class":60},"  complete",[47,501,452],{"class":64},[47,503,455],{"class":53},[47,505,506],{"class":64},"() {\n",[47,508,509,512,515,517,520],{"class":49,"line":178},[47,510,511],{"class":64},"    console.",[47,513,514],{"class":60},"log",[47,516,65],{"class":64},[47,518,519],{"class":152},"'Processing complete'",[47,521,280],{"class":64},[47,523,524],{"class":49,"line":212},[47,525,353],{"class":64},[47,527,528],{"class":49,"line":226},[47,529,530],{"class":64},"});\n",[15,532,533],{},"PapaParse handles quoted fields, escaped delimiters, and chunk boundaries correctly, which is much harder to get right with manual splitting.",[10,535,537],{"id":536},"progressive-output","Progressive Output",[15,539,540],{},"For large files, users need feedback that something is happening. Show progress and stream results incrementally:",[38,542,544],{"className":40,"code":543,"language":42,"meta":43,"style":43},"let processed = 0;\nconst totalSize = file.size;\n\nfunction processRow(row) {\n  \u002F\u002F Transform and emit the row\n  output.push(transform(row));\n  processed++;\n\n  if (processed % 10000 === 0) {\n    const progress = (chunkOffset \u002F totalSize * 100).toFixed(1);\n    updateProgressBar(progress);\n  }\n}\n",[29,545,546,561,573,577,591,596,612,622,626,646,683,691,695],{"__ignoreMap":43},[47,547,548,551,554,556,559],{"class":49,"line":50},[47,549,550],{"class":53},"let",[47,552,553],{"class":64}," processed ",[47,555,149],{"class":53},[47,557,558],{"class":81}," 0",[47,560,156],{"class":64},[47,562,563,565,568,570],{"class":49,"line":75},[47,564,323],{"class":53},[47,566,567],{"class":81}," totalSize",[47,569,85],{"class":53},[47,571,572],{"class":64}," file.size;\n",[47,574,575],{"class":49,"line":97},[47,576,137],{"emptyLinePlaceholder":136},[47,578,579,581,584,586,589],{"class":49,"line":115},[47,580,455],{"class":53},[47,582,583],{"class":60}," processRow",[47,585,65],{"class":64},[47,587,588],{"class":68},"row",[47,590,72],{"class":64},[47,592,593],{"class":49,"line":133},[47,594,595],{"class":291},"  \u002F\u002F Transform and emit the row\n",[47,597,598,601,604,606,609],{"class":49,"line":140},[47,599,600],{"class":64},"  output.",[47,602,603],{"class":60},"push",[47,605,65],{"class":64},[47,607,608],{"class":60},"transform",[47,610,611],{"class":64},"(row));\n",[47,613,614,617,620],{"class":49,"line":159},[47,615,616],{"class":64},"  processed",[47,618,619],{"class":53},"++",[47,621,156],{"class":64},[47,623,624],{"class":49,"line":164},[47,625,137],{"emptyLinePlaceholder":136},[47,627,628,630,633,636,639,642,644],{"class":49,"line":178},[47,629,370],{"class":53},[47,631,632],{"class":64}," (processed ",[47,634,635],{"class":53},"%",[47,637,638],{"class":81}," 10000",[47,640,641],{"class":53}," ===",[47,643,558],{"class":81},[47,645,72],{"class":64},[47,647,648,650,653,655,658,661,664,667,670,673,676,678,681],{"class":49,"line":212},[47,649,181],{"class":53},[47,651,652],{"class":81}," progress",[47,654,85],{"class":53},[47,656,657],{"class":64}," (chunkOffset ",[47,659,660],{"class":53},"\u002F",[47,662,663],{"class":64}," totalSize ",[47,665,666],{"class":53},"*",[47,668,669],{"class":81}," 100",[47,671,672],{"class":64},").",[47,674,675],{"class":60},"toFixed",[47,677,65],{"class":64},[47,679,680],{"class":81},"1",[47,682,280],{"class":64},[47,684,685,688],{"class":49,"line":226},[47,686,687],{"class":60},"    updateProgressBar",[47,689,690],{"class":64},"(progress);\n",[47,692,693],{"class":49,"line":231},[47,694,353],{"class":64},[47,696,697],{"class":49,"line":254},[47,698,385],{"class":64},[15,700,701,702,705],{},"Avoid updating the DOM on every row — batch updates every few thousand rows or use ",[29,703,704],{},"requestAnimationFrame"," to keep the UI responsive.",[10,707,709],{"id":708},"handling-the-output","Handling the Output",[15,711,712],{},"Even if you stream the input, accumulating all output rows in an array defeats the purpose. Consider these output strategies:",[714,715,716,732],"table",{},[717,718,719],"thead",{},[720,721,722,726,729],"tr",{},[723,724,725],"th",{},"Strategy",[723,727,728],{},"How It Works",[723,730,731],{},"Memory Impact",[733,734,735,747,758,769],"tbody",{},[720,736,737,741,744],{},[738,739,740],"td",{},"Download as file",[738,742,743],{},"Write rows to a Blob incrementally, trigger download",[738,745,746],{},"Constant — only current row in memory",[720,748,749,752,755],{},[738,750,751],{},"Virtual scrolling",[738,753,754],{},"Only render visible rows in the DOM",[738,756,757],{},"Proportional to viewport",[720,759,760,763,766],{},[738,761,762],{},"IndexedDB storage",[738,764,765],{},"Write rows to browser database in batches",[738,767,768],{},"Constant — backed by disk",[720,770,771,774,777],{},[738,772,773],{},"Server upload",[738,775,776],{},"Stream transformed rows to an API endpoint",[738,778,779],{},"Constant — sent and forgotten",[15,781,782],{},"For a CSV-to-JSON converter, the most practical approach is writing results to a Blob and offering a download when finished:",[38,784,786],{"className":40,"code":785,"language":42,"meta":43,"style":43},"const chunks = [];\n\nfunction processRow(row) {\n  chunks.push(JSON.stringify(row) + '\\n');\n}\n\nfunction onFinish() {\n  const blob = new Blob(chunks, { type: 'application\u002Fjson' });\n  const url = URL.createObjectURL(blob);\n  \u002F\u002F Trigger download\n}\n",[29,787,788,800,804,816,849,853,857,866,888,908,913],{"__ignoreMap":43},[47,789,790,792,795,797],{"class":49,"line":50},[47,791,323],{"class":53},[47,793,794],{"class":81}," chunks",[47,796,85],{"class":53},[47,798,799],{"class":64}," [];\n",[47,801,802],{"class":49,"line":75},[47,803,137],{"emptyLinePlaceholder":136},[47,805,806,808,810,812,814],{"class":49,"line":97},[47,807,455],{"class":53},[47,809,583],{"class":60},[47,811,65],{"class":64},[47,813,588],{"class":68},[47,815,72],{"class":64},[47,817,818,821,823,825,828,831,834,837,840,843,845,847],{"class":49,"line":115},[47,819,820],{"class":64},"  chunks.",[47,822,603],{"class":60},[47,824,65],{"class":64},[47,826,827],{"class":81},"JSON",[47,829,830],{"class":64},".",[47,832,833],{"class":60},"stringify",[47,835,836],{"class":64},"(row) ",[47,838,839],{"class":53},"+",[47,841,842],{"class":152}," '",[47,844,275],{"class":81},[47,846,272],{"class":152},[47,848,280],{"class":64},[47,850,851],{"class":49,"line":133},[47,852,385],{"class":64},[47,854,855],{"class":49,"line":140},[47,856,137],{"emptyLinePlaceholder":136},[47,858,859,861,864],{"class":49,"line":159},[47,860,455],{"class":53},[47,862,863],{"class":60}," onFinish",[47,865,506],{"class":64},[47,867,868,870,873,875,877,880,883,886],{"class":49,"line":164},[47,869,78],{"class":53},[47,871,872],{"class":81}," blob",[47,874,85],{"class":53},[47,876,125],{"class":53},[47,878,879],{"class":60}," Blob",[47,881,882],{"class":64},"(chunks, { type: ",[47,884,885],{"class":152},"'application\u002Fjson'",[47,887,251],{"class":64},[47,889,890,892,895,897,900,902,905],{"class":49,"line":178},[47,891,78],{"class":53},[47,893,894],{"class":81}," url",[47,896,85],{"class":53},[47,898,899],{"class":81}," URL",[47,901,830],{"class":64},[47,903,904],{"class":60},"createObjectURL",[47,906,907],{"class":64},"(blob);\n",[47,909,910],{"class":49,"line":212},[47,911,912],{"class":291},"  \u002F\u002F Trigger download\n",[47,914,915],{"class":49,"line":226},[47,916,385],{"class":64},[10,918,920],{"id":919},"web-workers-for-heavy-processing","Web Workers for Heavy Processing",[15,922,923],{},"Parsing and transforming millions of rows on the main thread blocks the UI. Move the work to a Web Worker:",[38,925,927],{"className":40,"code":926,"language":42,"meta":43,"style":43},"\u002F\u002F main.js\nconst worker = new Worker('csv-worker.js');\nworker.postMessage({ file }, [file]);\nworker.onmessage = (e) => {\n  if (e.data.type === 'progress') updateProgress(e.data.value);\n  if (e.data.type === 'result') downloadResult(e.data.blob);\n};\n\n\u002F\u002F csv-worker.js\nself.onmessage = async (e) => {\n  const file = e.data.file;\n  \u002F\u002F ... streaming parse + transform\n  self.postMessage({ type: 'result', blob });\n};\n",[29,928,929,934,955,966,989,1010,1029,1034,1038,1043,1065,1077,1082,1098],{"__ignoreMap":43},[47,930,931],{"class":49,"line":50},[47,932,933],{"class":291},"\u002F\u002F main.js\n",[47,935,936,938,941,943,945,948,950,953],{"class":49,"line":75},[47,937,323],{"class":53},[47,939,940],{"class":81}," worker",[47,942,85],{"class":53},[47,944,125],{"class":53},[47,946,947],{"class":60}," Worker",[47,949,65],{"class":64},[47,951,952],{"class":152},"'csv-worker.js'",[47,954,280],{"class":64},[47,956,957,960,963],{"class":49,"line":97},[47,958,959],{"class":64},"worker.",[47,961,962],{"class":60},"postMessage",[47,964,965],{"class":64},"({ file }, [file]);\n",[47,967,968,970,973,975,977,980,983,986],{"class":49,"line":115},[47,969,959],{"class":64},[47,971,972],{"class":60},"onmessage",[47,974,85],{"class":53},[47,976,170],{"class":64},[47,978,979],{"class":68},"e",[47,981,982],{"class":64},") ",[47,984,985],{"class":53},"=>",[47,987,988],{"class":64}," {\n",[47,990,991,993,996,999,1002,1004,1007],{"class":49,"line":133},[47,992,370],{"class":53},[47,994,995],{"class":64}," (e.data.type ",[47,997,998],{"class":53},"===",[47,1000,1001],{"class":152}," 'progress'",[47,1003,982],{"class":64},[47,1005,1006],{"class":60},"updateProgress",[47,1008,1009],{"class":64},"(e.data.value);\n",[47,1011,1012,1014,1016,1018,1021,1023,1026],{"class":49,"line":140},[47,1013,370],{"class":53},[47,1015,995],{"class":64},[47,1017,998],{"class":53},[47,1019,1020],{"class":152}," 'result'",[47,1022,982],{"class":64},[47,1024,1025],{"class":60},"downloadResult",[47,1027,1028],{"class":64},"(e.data.blob);\n",[47,1030,1031],{"class":49,"line":159},[47,1032,1033],{"class":64},"};\n",[47,1035,1036],{"class":49,"line":164},[47,1037,137],{"emptyLinePlaceholder":136},[47,1039,1040],{"class":49,"line":178},[47,1041,1042],{"class":291},"\u002F\u002F csv-worker.js\n",[47,1044,1045,1048,1050,1052,1055,1057,1059,1061,1063],{"class":49,"line":212},[47,1046,1047],{"class":64},"self.",[47,1049,972],{"class":60},[47,1051,85],{"class":53},[47,1053,1054],{"class":53}," async",[47,1056,170],{"class":64},[47,1058,979],{"class":68},[47,1060,982],{"class":64},[47,1062,985],{"class":53},[47,1064,988],{"class":64},[47,1066,1067,1069,1072,1074],{"class":49,"line":226},[47,1068,78],{"class":53},[47,1070,1071],{"class":81}," file",[47,1073,85],{"class":53},[47,1075,1076],{"class":64}," e.data.file;\n",[47,1078,1079],{"class":49,"line":231},[47,1080,1081],{"class":291},"  \u002F\u002F ... streaming parse + transform\n",[47,1083,1084,1087,1089,1092,1095],{"class":49,"line":254},[47,1085,1086],{"class":64},"  self.",[47,1088,962],{"class":60},[47,1090,1091],{"class":64},"({ type: ",[47,1093,1094],{"class":152},"'result'",[47,1096,1097],{"class":64},", blob });\n",[47,1099,1100],{"class":49,"line":283},[47,1101,1033],{"class":64},[15,1103,1104,1105,1107],{},"Workers run on a separate thread, keeping the UI responsive even during heavy computation. Transfer the ",[29,1106,31],{}," object to the worker to avoid duplicating the file in memory.",[10,1109,1111],{"id":1110},"common-pitfalls","Common Pitfalls",[1113,1114,1115,1125,1131,1145],"ul",{},[400,1116,1117,1124],{},[1118,1119,1120,1121],"strong",{},"Reading the entire file with ",[29,1122,1123],{},"FileReader.readAsText()"," — loads the whole file as a single string. Use streaming instead.",[400,1126,1127,1130],{},[1118,1128,1129],{},"Accumulating all rows in an array"," — defeats the purpose of streaming input. Write to a Blob or storage incrementally.",[400,1132,1133,1136,1137,1140,1141,1144],{},[1118,1134,1135],{},"Ignoring quoted newlines"," — a CSV field like ",[29,1138,1139],{},"\"line1\\nline2\""," contains a real newline. Naive ",[29,1142,1143],{},"split('\\n')"," breaks these rows.",[400,1146,1147,1150,1151,1154,1155,1158],{},[1118,1148,1149],{},"Not yielding to the event loop"," — long synchronous loops freeze the UI. Use ",[29,1152,1153],{},"await"," or ",[29,1156,1157],{},"setTimeout(0)"," to yield periodically.",[10,1160,1162],{"id":1161},"key-takeaways","Key Takeaways",[1113,1164,1165,1172,1175,1178,1181,1184],{},[400,1166,1167,1168,1171],{},"Never load an entire large CSV into memory — use streaming reads via ",[29,1169,1170],{},"File.stream()"," or PapaParse.",[400,1173,1174],{},"Buffer partial lines at chunk boundaries to avoid splitting rows mid-field.",[400,1176,1177],{},"Write output incrementally to Blobs, IndexedDB, or a server — avoid accumulating all rows in an array.",[400,1179,1180],{},"Use Web Workers to keep the main thread responsive during heavy parsing.",[400,1182,1183],{},"Update progress indicators in batches, not on every row.",[400,1185,1186,1187,1189],{},"Handle quoted fields with embedded newlines — they break naive ",[29,1188,1143],{}," parsing.",[10,1191,1193],{"id":1192},"try-it-yourself","Try It Yourself",[15,1195,1196,1197,830],{},"Convert CSV files of any size directly in the browser with the ",[1198,1199,1201],"a",{"href":1200},"\u002Ftools\u002Fcsv-json","CSV to JSON Converter",[1203,1204,1205],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":43,"searchDepth":75,"depth":75,"links":1207},[1208,1209,1210,1211,1212,1213,1214,1215,1216],{"id":12,"depth":75,"text":13},{"id":23,"depth":75,"text":24},{"id":391,"depth":75,"text":392},{"id":536,"depth":75,"text":537},{"id":708,"depth":75,"text":709},{"id":919,"depth":75,"text":920},{"id":1110,"depth":75,"text":1111},{"id":1161,"depth":75,"text":1162},{"id":1192,"depth":75,"text":1193},"2026-05-28","Strategies for parsing and converting CSV files over 100MB without crashing the browser.","md",{"immutable":136},"\u002Fguides\u002Flarge-csv-processing",{"title":5,"description":1218},"guides\u002Flarge-csv-processing","D-zerQaDrhOFjF_KppeKT-Mo4vNEJ6JwnirFXM0be6A",1780401334821]