W3C File API specification compliant FileReader polyfill for Node.js environments
npm install @lyleunderwood/filereader-polyfillA 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.
- ✅ 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
- Node.js 16.7.0 or higher (required for native Blob and EventTarget support)
``bash`
npm install @lyleunderwood/filereader-polyfill
`javascript
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);
`
`javascript
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);
`
The polyfill automatically installs itself globally if FileReader or File don't exist:
`javascript
import '@lyleunderwood/filereader-polyfill';
// Now you can use FileReader and File globally
const reader = new FileReader();
const file = new File(['data'], 'example.txt');
`
`javascript
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);
});
`
`javascript
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);
`
`javascript
const reader = new FileReader();
const blob = new Blob(['Large file content...']);
reader.readAsText(blob);
// Abort the reading operation
setTimeout(() => {
reader.abort();
}, 100);
`
The polyfill provides W3C-compliant error handling with proper DOMException types:
`javascript
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"
}
`
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 encodingreadAsDataURL(blob)
- : Read as Data URLreadAsArrayBuffer(blob)
- : Read as ArrayBufferreadAsBinaryString(blob)
- : Read as binary stringabort()
- : Abort the current reading operation
#### Events
- loadstart: Reading startedprogress
- : Reading progress (includes loaded and total properties)load
- : Reading completed successfullyerror
- : Error occurred during readingabort
- : Reading was abortedloadend
- : Reading finished (success, error, or abort)
Extends native Blob and supports both Web API and Node.js file path constructors.
#### Constructors
`javascript
// Web API style
new File(fileBits, fileName, options)
// Node.js file path style
new File(filePath)
`
#### Properties
- name: File namelastModified
- : Last modification timestampsize
- : File size in bytestype
- : MIME typepath
- : File path (Node.js specific, when created from path)
Full W3C specification-compliant TypeScript definitions are included:
`typescript
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
`
- IFileReader: W3C specification compliant FileReader interface
- IFile: W3C specification compliant File interface
- NodeFile: Extended File interface with Node.js specific path propertyEventHandler
- : W3C compliant event handler function typeProgressEvent
- : Progress event interface with lengthComputable, loaded, and totalFileReaderState
- : Enum for FileReader states (EMPTY, LOADING, DONE)BlobPart
- : Union type for valid Blob constructor partsFilePropertyBag
- : Options interface for File constructor
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
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.
This polyfill is designed for Node.js environments. For browser usage, use the native FileReader API which is widely supported.
Run the comprehensive test suite including W3C specification compliance tests:
`bash``
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
Contributions are welcome! Please ensure all tests pass and maintain W3C specification compliance when making changes.
MIT License - see LICENSE file for details.