Back to List

Handling Experiment Data Files with Node.js

Read and write experiment data files with Node.js. Learn runtime, modules, and sync/async concepts through bio examples.

Beginner
|
60min
|
Verified (2026-06)
Node.jsRuntimeFile SystemModuleSync and AsyncCallback
Progress0/19 (0%)

Handling Experiment Data Files with Node.js

Last time you learned variables, functions, conditionals, and loops in JavaScript. But all that code ran inside the browser. Browser JavaScript can't read or write files on your computer for security reasons.

For researchers, this is a critical limitation. To read experiment result CSVs, parse FASTA sequence files, and save analysis results to new files โ€” JavaScript needs direct access to your computer's file system.

Node.js solves exactly this problem. It's a runtime that lets JavaScript run outside the browser. In lab terms โ€” JavaScript was a protocol you could only run on a specific instrument called the browser, but Node.js lets you run it on any computer.

What Is a Runtime?

Runtime = the environment that executes code.

  • Browser = JavaScript runtime (only inside web pages)
  • Node.js = JavaScript runtime (anywhere on your computer)

It's like making analysis software that only ran on the qPCR machine executable on any computer.

bash
# Check installation (in terminal)
node --version
# If you see a version like v22.x.x, it's installed
# Run a JavaScript file
node my_script.js

In the browser, you put code inside <script> tags, but in Node.js you create .js files and run them with node filename.js in the terminal.

Modules: Pulling Out Feature Toolboxes

Node.js can read files, handle network communication, and process paths thanks to modules. A module is a toolbox bundling specific functionality.

Just as you pull out PCR kits, DNA extraction kits, and electrophoresis kits in the lab, in Node.js you pull out the modules you need with require():

javascript
const fs = require("fs");
const path = require("path");
  • fs โ€” File System module. Read, write, delete files
  • path โ€” Path processing module. Auto-handles OS-specific path differences

These modules are built into Node.js โ€” no separate installation needed.

Reading Files: fs.readFileSync

The most basic operation โ€” read a file and print its contents:

javascript
const fs = require("fs");

const data = fs.readFileSync("samples.csv", "utf8");
console.log(data);

The Sync in readFileSync means synchronous. It won't move to the next line until the file is fully read. Like waiting next to the centrifuge until it stops.

"utf8" is the character encoding โ€” omit it and you get an unreadable Buffer (binary data).

An example reading and processing experiment data:

javascript
const fs = require("fs");

const raw = fs.readFileSync("qc_results.csv", "utf8");
const lines = raw.trim().split("\n");
const header = lines[0].split(",");

console.log("Columns:", header);
console.log("Data rows:", lines.length - 1);

for (let i = 1; i < lines.length; i++) {
  const cols = lines[i].split(",");
  const sampleId = cols[0];
  const od = parseFloat(cols[1]);

  if (od < 0.5) {
    console.log(sampleId, "โ€” OD", od, "โ€” FAIL");
  }
}

Reads a CSV file, splits by lines, and filters samples below the OD threshold. You can do QC checks right in the terminal without opening Excel.

Sync vs Async: Why Two Options?

readFileSync (synchronous) is intuitive but has a problem. If the file is large, the entire program freezes while reading. Read a multi-GB sequencing raw data file synchronously and nothing else can happen in the meantime.

readFile (asynchronous) solves this:

javascript
const fs = require("fs");

fs.readFile("sequences.fasta", "utf8", function(err, data) {
  if (err) {
    console.log("File read failed:", err.message);
    return;
  }
  console.log("Sequence data length:", data.length);
});

console.log("File request sent, continuing other work");

Output:

text
File request sent, continuing other work
Sequence data length: 4823910

Notice the order. console.log("File request sent...") prints first. readFile kicks off the file read and immediately moves to the next line. When the file reading finishes, the callback function function(err, data) is called.

It's like sending samples to an external sequencing service. You don't stand there waiting until results arrive โ€” you continue other experiments and check the results when they come back.

Synchronous (Sync)Asynchronous (Async)
Functionfs.readFileSync()fs.readFile()
BehaviorWaits until completeRequests then immediately moves on
Getting resultReturn value (const data = ...)Callback function (function(err, data))
AnalogyWaiting by the centrifugeOutsourcing sequencing and doing other experiments
Best forSmall config files, initializationLarge data, server request handling

Callbacks and Error Handling

Async function callbacks always follow the (err, data) pattern. First argument is the error, second is the result. This is a Node.js convention:

javascript
const fs = require("fs");

fs.readFile("experiment_log.txt", "utf8", function(err, data) {
  if (err) {
    console.log("Error type:", err.code);
    console.log("Error message:", err.message);
    return;
  }
  console.log("Log contents:", data);
});

If the file doesn't exist, err.code is "ENOENT" (Error NO ENTry) โ€” meaning "file not found." Remember this pattern:

  1. Check err first
  2. If there's an error, handle it and return
  3. If no error, use data

Writing Files: Saving Analysis Results

Writing is just as important as reading. To save QC results to a file:

javascript
const fs = require("fs");

const results = [
  "Sample_ID,OD,Status",
  "S001,1.85,PASS",
  "S002,0.42,FAIL",
  "S003,2.10,PASS"
];

const output = results.join("\n");

fs.writeFileSync("qc_report.csv", output, "utf8");
console.log("QC report saved:", results.length - 1, "entries");

writeFileSync creates the file if it doesn't exist, or overwrites if it does. To append to existing content, use fs.appendFileSync().

Creating a Simple Web Server

Node.js's real power is the ability to create servers. The http module lets you run a web server in 3 lines:

javascript
const http = require("http");

const server = http.createServer(function(req, res) {
  res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" });
  res.end("LIMS server running");
});

server.listen(3000, function() {
  console.log("Server started: http://localhost:3000");
});

Run node server.js and visit http://localhost:3000 in your browser to see "LIMS server running."

But serving different data based on URLs or handling POST requests makes the code extremely complex. Express โ€” the framework you'll learn next โ€” solves exactly this complexity.

npm: Using Other Developers' Tools

Node.js comes with npm (Node Package Manager) installed. You can install libraries made by other developers with a single command:

bash
# Initialize project (creates package.json)
npm init -y
# Install packages example
npm install csv-parser
npm install express

Just as you browse a reagent catalog and order what you need in the lab, npm lets you pick and install from millions of JavaScript packages. package.json is the "reagent list" showing which packages your project needs.

Try It Yourself (Faded Example)

Fill in the blanks to complete Node.js code that reads a CSV and counts lines.

Fill in the Blanksjavascript
const fs = require("");
const data = fs.readFileSync("samples.csv", "");
const lines = data.trim().("\n");
console.log("Total", lines., "lines");

Common Errors & Solutions

Q: Error: Cannot find module 'fs'

You're likely running in the browser. The fs module is Node.js only. Run with node filename.js in the terminal. It cannot be used in browser console or HTML <script> tags.

Q: File read returns strange characters (<Buffer 48 65 6c ...>)

You forgot "utf8" encoding in readFileSync. Without encoding, it returns a Buffer (raw bytes). Fix with fs.readFileSync("file.txt", "utf8").

Q: ENOENT: no such file or directory

The file path is wrong. Node.js resolves relative paths from the directory where the node command was run. Check the file exists in the current directory with ls (Mac/Linux) or dir (Windows). For certainty, construct an absolute path with path.join(__dirname, "filename").

Q: Can't use async function results outside the callback

javascript
let result;
fs.readFile("data.txt", "utf8", function(err, data) {
  result = data;
});
console.log(result); // undefined!

readFile moves to the next line immediately, so console.log runs before the callback executes. Code that uses the result must be placed inside the callback function. Or use readFileSync to avoid this issue.

Q: What exactly is a "runtime"?

A runtime is the execution environment that enables running code in a specific language.

JavaScript originally could only run inside browsers. You'd put code in an HTML file's <script> tag and open it in a browser. The browser was JavaScript's runtime.

With Node.js installed on your computer, you can run JavaScript from the terminal with node script.js without a browser. Here Node.js is JavaScript's runtime.

text
Running JS in browser:  HTML file โ†’ open in browser (runtime)
Running JS in Node.js:  .js file โ†’ run with node command (runtime) in terminal

Analogy โ€” just as you can't observe cells without a microscope, you can't execute code without a runtime. Writing code (typing in VS Code) and executing it (runtime interprets it) are separate steps.

๐Ÿ’ฌ Questions & Comments

0 comments

You can post without signing in. Guest comments cannot be edited or deleted by their author.

0/2000

Loading...