# Modules, files, and the command line
# Running a program
node reader.js notes.txt
process.argv[2] is notes.txt in this example. Treat command-line input as untrusted: validate the path and handle missing files and read errors. Use node:path to construct paths rather than concatenating platform-specific separators.
# Modules: two styles
Node's traditional module system is CommonJS:
const { readFile } = require('node:fs');
const { join } = require('node:path');
module.exports = { join };
Node also supports ECMAScript modules. In a .mjs file, or in a package with "type": "module":
import { readFile } from 'node:fs/promises';
export { readFile };
Use one module system consistently per project. Mixing export in a .js file with require elsewhere fails without the matching "type" declaration or a transform step; do not treat mixed syntax as a runnable recipe.
# Async filesystem APIs
An error-first callback receives an error before a value:
const { readFile } = require('node:fs');
readFile('notes.txt', 'utf8', (error, text) => {
if (error) {
console.error(error);
return;
}
console.log(text);
});
console.log('Reading started');
The Promise-based equivalent works with async/await:
const { readFile } = require('node:fs/promises');
async function showFile(path) {
try {
console.log(await readFile(path, 'utf8'));
} catch (error) {
console.error('Unable to read file:', error);
}
}
Without 'utf8', readFile returns a Buffer of bytes, not a string. Avoid synchronous filesystem operations on a busy server's request path because they block other callbacks.
# Relating this to the folder-activity task
The pet project asks for added/removed file detection. A naive setInterval + fs.readdir poll that only looks at the latest listing can report additions but misses removals. A robust polling approach keeps the previous filename set and compares it with the new set on each successful read:
const previous = new Set(oldNames);
const current = new Set(newNames);
const added = newNames.filter((name) => !previous.has(name));
const removed = oldNames.filter((name) => !current.has(name));
Start with an initial baseline snapshot, and handle read errors without treating an unreadable folder as empty. fs.watch is another API, but filesystem events can be platform-dependent.
Node filesystem API (opens new window) · Node packages and modules (opens new window)