# How to Read a File in Node.js: Complete Guide to nodejs read file Methods

> Master nodejs read file operations with fs.readFile, fs.promises.readFile, and fs.createReadStream. Learn efficient file handling in our complete Node.js guide.

- Repository: [Node.js/node](https://github.com/nodejs/node)
- Tags: how-to-guide
- Published: 2026-02-14

---

**Use the built-in `fs` (File System) module to read files via callback-based `fs.readFile()`, Promise-based `fs.promises.readFile()`, or streaming `fs.createReadStream()` for memory-efficient processing.**

Node.js provides robust file reading capabilities through its built-in `fs` module, implemented in the `nodejs/node` repository. Whether you're building CLI tools or web servers, understanding how to perform a **nodejs read file** operation is essential for working with local data. The module exposes both callback and Promise-based APIs defined in [`lib/fs.js`](https://github.com/nodejs/node/blob/main/lib/fs.js) that delegate to native C++ bindings for cross-platform performance.

## Three Methods for nodejs read file Operations

The `fs` module offers three distinct patterns for reading file contents, each optimized for different use cases. According to the `nodejs/node` source code, all methods ultimately invoke the same native file descriptors in `src/node_file.cc`, ensuring consistent behavior across POSIX and Windows systems.

### Callback-Based Approach with fs.readFile

The traditional callback approach uses `fs.readFile`, defined in [`lib/fs.js`](https://github.com/nodejs/node/blob/main/lib/fs.js). This method is suitable for quick scripts or when you want to avoid Promise overhead.

```javascript
const fs = require('fs');
const path = './example.txt';

fs.readFile(path, 'utf8', (err, data) => {
  if (err) {
    console.error('Error reading file:', err);
    return;
  }
  console.log('File contents:', data);
});

```

The function signature accepts a file path, optional encoding (specify `'utf8'` to receive a string instead of a Buffer), and a callback function handling `(err, data)`.

### Promise-Based Approach with fs.promises.readFile

For modern async/await patterns, use the Promise-based API exposed via `fs.promises`. In ES modules, import directly from `fs`:

```javascript
import { promises as fs } from 'fs';
const path = './example.txt';

async function read() {
  try {
    const data = await fs.readFile(path, 'utf8');
    console.log('File contents:', data);
  } catch (err) {
    console.error('Error reading file:', err);
  }
}

read();

```

This approach integrates cleanly with modern JavaScript and avoids callback nesting. The implementation in [`lib/fs.js`](https://github.com/nodejs/node/blob/main/lib/fs.js) wraps the underlying callback API with native Promise resolution.

### Streaming Large Files with fs.createReadStream

For large files or when processing data chunk-by-chunk, use `fs.createReadStream` to avoid loading entire files into memory. As implemented in `nodejs/node`, this creates a readable stream that emits data events:

```javascript
import { createReadStream } from 'fs';
import { pipeline } from 'stream';
import { createWriteStream } from 'fs';

const source = createReadStream('./large-file.txt', { encoding: 'utf8' });
const destination = createWriteStream('./copy.txt');

pipeline(source, destination, (err) => {
  if (err) console.error('Pipeline failed:', err);
  else console.log('File streamed successfully');
});

```

The `pipeline` utility handles stream cleanup and error propagation automatically.

## Internal Architecture of nodejs read file

Understanding the implementation details helps debug performance issues. The **nodejs read file** stack consists of three layers:

- **[`lib/fs.js`](https://github.com/nodejs/node/blob/main/lib/fs.js)**: High-level JavaScript wrapper exposing both callback and Promise APIs (`fs.readFile`, `fs.promises.readFile`)
- **`src/node_file.cc`**: Native C++ implementation that interacts with OS file descriptors
- **[`test/parallel/test-fs-readfile.js`](https://github.com/nodejs/node/blob/main/test/parallel/test-fs-readfile.js)**: Comprehensive test suite validating edge cases and cross-platform consistency

When you call `fs.readFile()`, the JavaScript layer in [`lib/fs.js`](https://github.com/nodejs/node/blob/main/lib/fs.js) validates arguments and forwards calls to the C++ bindings in `src/node_file.cc`, which execute non-blocking I/O via libuv.

## Summary

- **Callback API**: Use `require('fs').readFile()` for legacy compatibility or minimal overhead in CommonJS modules
- **Promise API**: Use `import { promises as fs }` with `async/await` for cleaner error handling and modern JavaScript patterns
- **Streaming**: Use `createReadStream()` for files larger than available memory or when processing data incrementally
- **Encoding**: Always specify `'utf8'` when reading text files to receive strings instead of Buffer objects
- **Source Location**: The implementation spans [`lib/fs.js`](https://github.com/nodejs/node/blob/main/lib/fs.js) (JavaScript API) and `src/node_file.cc` (native bindings)

## Frequently Asked Questions

### What is the difference between fs.readFile and fs.promises.readFile?

`fs.readFile` uses a traditional callback pattern where you provide a function to handle `(err, data)`, while `fs.promises.readFile` returns a Promise that resolves with the file contents. According to the `nodejs/node` source in [`lib/fs.js`](https://github.com/nodejs/node/blob/main/lib/fs.js), the Promise API is a wrapper around the callback implementation, offering better integration with `async/await` syntax and centralized error handling through try/catch blocks.

### When should I use fs.createReadStream instead of fs.readFile?

Use `fs.createReadStream` when reading files larger than your available memory or when you need to process data incrementally without loading the entire file into RAM. As implemented in `src/node_file.cc`, streams use chunked reading via file descriptors, whereas `fs.readFile` buffers the entire contents before invoking your callback or resolving the Promise.

### Where is the fs module implemented in the Node.js source code?

The `fs` module implementation is split between [`lib/fs.js`](https://github.com/nodejs/node/blob/main/lib/fs.js) (high-level JavaScript APIs including both callback and Promise variants) and `src/node_file.cc` (low-level C++ bindings that interact with the operating system). Documentation is generated from [`doc/api/fs.md`](https://github.com/nodejs/node/blob/main/doc/api/fs.md), and behavior is validated by [`test/parallel/test-fs-readfile.js`](https://github.com/nodejs/node/blob/main/test/parallel/test-fs-readfile.js).

### How do I handle file encoding when using nodejs read file methods?

Always pass the encoding string (typically `'utf8'`) as the second argument to `fs.readFile()` or `fs.promises.readFile()`. Without this parameter, the methods return a raw Buffer object; with it, they return a decoded JavaScript string. The encoding logic is handled in the JavaScript layer of [`lib/fs.js`](https://github.com/nodejs/node/blob/main/lib/fs.js) before returning data to your application.