Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Reliable FileReader

FileReader + Promises + Timeout Period

  • Wraps FileReader onload/onerror events with a Promise for ease of use.
  • Enforces a timeout period in case FileReader does not call onload or onerror within a reasonable timeframe. In some cases, we've found that FileReader just stalls out and never fires an event.
  • Native FileReader will actually call both onload & onerror if an error is thrown downstream in an onload callback, so by using this library you avoid that footgun.

Getting Started

Let me know if you actually use this and I'll start publishing it to npm. In the meantime:

npm i git+
import reliableFileReader from 'reliable-filereader';

reliableFileReader('readAsDataURL', blob)
    .then((base64String) => {
        // Do something with base64 string
    .catch((error) => {
        if (/timed out/.test(error)) {
            // FileReader has not responded within 15 seconds
        } else {
            // FileReader fired an error event.
            const errorEvent = error;


method - {string}

Name of FileReader method (e.g. "readAsDataURL")

blob - {Blob}

Blob or File to read

options.timeoutMs - {number}

Milliseconds to wait before timing out. Defaults to 15 seconds.

// Only wait 10 seconds before giving up
reliableFileReader('readAsDataURL', blob, { timeoutMs: 10000 });

options.onFinishAfterTimeout - {function}

Passed { error } or { result } when FileReader completes after it times out. Could be useful for determing the ideal timeout period.

const startTime =;
reliableFileReader('readAsDataURL', blob, {
    onFinishAfterTimeout: ({ result, error }) => {
        const ellapsedSeconds = ( - startTime) / 1000;
        if (result) {
            reportToAnalytics(`FileReader completed after ${ellapsedSeconds}s`);
        } else {
            reportToAnalytics(`FileReader failed after ${ellapsedSeconds}s`);

options.timeoutFunction - {function}

The timeout function to be overriden. By default, it's just a simple wrapper around setTimeout that accepts a callback {function} and timeoutMs {number} and returns a cancellation function, e.g.

function simpleTimeout(callback, timeoutMs) {
    const timeoutId = setTimeout(callback, timeoutMs);
    return stopWaiting;

    function stopWaiting() {

If you want to pause the timer while the tab is in the background, you could use this drop-in replacement:

import whileTabVisibleTimeout from 'while-tab-visible-setTimeout';

// Pause timer if user is not viewing this tab, since FileReader will be throttled
// by the browser and will take much longer to complete its task.
reliableFileReader('readAsDataURL', blob, { timeoutFunction: whileTabVisibleTimeout });

See micahjon/while-tab-visible-setTimeout


Reliable FileReader wrapper with promises & timeout period.






No releases published


No packages published