npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@lyleunderwood/filereader-polyfill

v1.0.0

Published

W3C File API specification compliant FileReader polyfill for Node.js environments

Readme

FileReader Polyfill

A comprehensive FileReader API polyfill for Node.js environments that provides 100% W3C File API specification compliance with full compatibility with the Web FileReader API, including support for both File and Blob objects.

Features

  • W3C File API Specification Compliant - Passes comprehensive spec compliance tests
  • ✅ Complete FileReader API implementation
  • ✅ Support for all read methods: readAsText, readAsDataURL, readAsArrayBuffer, readAsBinaryString
  • ✅ Full event support: loadstart, progress, load, error, abort, loadend
  • ✅ Proper error handling with DOMException types (InvalidStateError, NotReadableError, AbortError)
  • ✅ Works with both File and Blob objects
  • ✅ Stream-based reading with progress events
  • ✅ Proper abort functionality
  • ✅ File path support for Node.js environments
  • ✅ TypeScript support with full type definitions
  • ✅ Event-driven architecture with EventTarget inheritance

Requirements

  • Node.js 16.7.0 or higher (required for native Blob and EventTarget support)

Installation

npm install @lyleunderwood/filereader-polyfill

Usage

Basic Usage

import { FileReader, File } from '@lyleunderwood/filereader-polyfill';

// Reading from a Blob
const blob = new Blob(['Hello, World!'], { type: 'text/plain' });
const reader = new FileReader();

reader.onload = (event) => {
  console.log('Result:', reader.result);
};

reader.readAsText(blob);

Reading from File Paths (Node.js specific)

import { FileReader, File } from '@lyleunderwood/filereader-polyfill';

// Create File from file path
const file = new File('/path/to/your/file.txt');
const reader = new FileReader();

reader.onload = () => {
  console.log('File content:', reader.result);
};

reader.readAsText(file);

Global Polyfill

The polyfill automatically installs itself globally if FileReader or File don't exist:

import '@lyleunderwood/filereader-polyfill';

// Now you can use FileReader and File globally
const reader = new FileReader();
const file = new File(['data'], 'example.txt');

Event Handling

const reader = new FileReader();

reader.onloadstart = () => console.log('Started reading');
reader.onprogress = (event) => {
  if (event.lengthComputable) {
    const progress = (event.loaded / event.total) * 100;
    console.log(`Progress: ${progress}%`);
  }
};
reader.onload = () => console.log('Reading completed');
reader.onerror = () => console.error('Error occurred:', reader.error);
reader.onabort = () => console.log('Reading aborted');
reader.onloadend = () => console.log('Reading finished');

// You can also use addEventListener
reader.addEventListener('load', (event) => {
  console.log('Load event:', event);
});

Reading Different Formats

const reader = new FileReader();
const blob = new Blob(['Hello, World!']);

// Read as text
reader.readAsText(blob);

// Read as ArrayBuffer
reader.readAsArrayBuffer(blob);

// Read as Data URL
reader.readAsDataURL(blob);

// Read as binary string
reader.readAsBinaryString(blob);

Abort Reading

const reader = new FileReader();
const blob = new Blob(['Large file content...']);

reader.readAsText(blob);

// Abort the reading operation
setTimeout(() => {
  reader.abort();
}, 100);

Error Handling

The polyfill provides W3C-compliant error handling with proper DOMException types:

const reader = new FileReader();

// Handle different error scenarios
reader.onerror = (event) => {
  console.log('Error name:', reader.error.name);
  console.log('Error message:', reader.error.message);
};

reader.onabort = (event) => {
  console.log('Operation was aborted');
  // reader.error will be AbortError
};

// Reading from non-existent file (Node.js path constructor)
try {
  const file = new File('/path/to/nonexistent/file.txt');
  reader.readAsText(file); // Will trigger error event with NotReadableError
} catch (error) {
  // File constructor errors are deferred to read operations
}

// Attempting to read while already reading
try {
  reader.readAsText(blob);
  reader.readAsText(blob); // Throws InvalidStateError
} catch (error) {
  console.log(error.name); // "InvalidStateError"
}

API Reference

FileReader Class

Extends EventTarget and implements the complete Web FileReader API.

Properties

  • readyState: Current state (EMPTY, LOADING, DONE)
  • result: The file's contents (available after successful read)
  • error: Error information if reading failed

Methods

  • readAsText(blob, encoding?): Read as text with optional encoding
  • readAsDataURL(blob): Read as Data URL
  • readAsArrayBuffer(blob): Read as ArrayBuffer
  • readAsBinaryString(blob): Read as binary string
  • abort(): Abort the current reading operation

Events

  • loadstart: Reading started
  • progress: Reading progress (includes loaded and total properties)
  • load: Reading completed successfully
  • error: Error occurred during reading
  • abort: Reading was aborted
  • loadend: Reading finished (success, error, or abort)

File Class

Extends native Blob and supports both Web API and Node.js file path constructors.

Constructors

// Web API style
new File(fileBits, fileName, options)

// Node.js file path style
new File(filePath)

Properties

  • name: File name
  • lastModified: Last modification timestamp
  • size: File size in bytes
  • type: MIME type
  • path: File path (Node.js specific, when created from path)

TypeScript Support

Full W3C specification-compliant TypeScript definitions are included:

import { 
  FileReader, 
  File,
  type IFileReader,
  type IFile,
  type NodeFile,
  type EventHandler,
  type ProgressEvent,
  type FileReaderState,
  type BlobPart,
  type FilePropertyBag
} from '@lyleunderwood/filereader-polyfill';

// W3C compliant usage
const reader: FileReader = new FileReader();
const file: File = new File(['content'], 'example.txt');

// Type-safe event handlers
reader.onload = (event: Event) => {
  console.log(reader.result);
};

reader.onprogress = (event: Event) => {
  const progressEvent = event as ProgressEvent;
  if (progressEvent.lengthComputable) {
    const progress = progressEvent.loaded / progressEvent.total;
    console.log(`Progress: ${Math.round(progress * 100)}%`);
  }
};

// File constructor with proper types
const fileFromBits: File = new File(
  ['Hello, World!'] as BlobPart[],
  'hello.txt',
  { type: 'text/plain', lastModified: Date.now() } as FilePropertyBag
);

// Node.js specific file path constructor
const fileFromPath: NodeFile = new File('/path/to/file.txt');
console.log(fileFromPath.path); // string | undefined

Available Types

  • IFileReader: W3C specification compliant FileReader interface
  • IFile: W3C specification compliant File interface
  • NodeFile: Extended File interface with Node.js specific path property
  • EventHandler: W3C compliant event handler function type
  • ProgressEvent: Progress event interface with lengthComputable, loaded, and total
  • FileReaderState: Enum for FileReader states (EMPTY, LOADING, DONE)
  • BlobPart: Union type for valid Blob constructor parts
  • FilePropertyBag: Options interface for File constructor

W3C Specification Compliance

This polyfill implements the W3C File API specification with 100% compliance for Node.js environments. It includes comprehensive test coverage that verifies:

  • ✅ All FileReader interface requirements (constants, attributes, methods, events)
  • ✅ All File interface requirements (constructor, properties, Blob inheritance)
  • ✅ Proper error handling with correct DOMException types
  • ✅ Event firing order and timing per specification
  • ✅ State management and concurrent operation prevention
  • ✅ Progress events with proper lengthComputable, loaded, and total properties

Known Limitations

Due to the Node.js environment, some aspects cannot be implemented with 100% browser fidelity:

  • File system access: Cannot detect file changes after File creation (deferred to read operations)
  • Event objects: Uses generic Event instead of native ProgressEvent (properties are preserved)
  • Microtask timing: Event firing may differ slightly from browser microtask scheduling
  • Memory management: Cannot replicate exact browser garbage collection behavior
  • Security restrictions: Cannot enforce same-origin policies or file access permissions

These limitations do not affect functional compatibility with the W3C specification.

Browser Compatibility

This polyfill is designed for Node.js environments. For browser usage, use the native FileReader API which is widely supported.

Testing

Run the comprehensive test suite including W3C specification compliance tests:

npm test

The test suite includes:

  • Unit tests for all functionality
  • W3C File API specification compliance tests
  • Error handling and edge case coverage
  • Integration tests between File and FileReader

Contributing

Contributions are welcome! Please ensure all tests pass and maintain W3C specification compliance when making changes.

License

MIT License - see LICENSE file for details.