tus is a protocol based on HTTP for resumable file uploads. Resumable here means that an interrupted upload can carry on without re-uploading already uploaded data again. An interruption may happen willingly, if the user wants to pause while switching to another workspace, or by accident in case of a network issue or server outage. When resumability is implemented with automatic retries, the user does not need to notice there was an interruption. Since HTTP/1.1 such a resumability is available for file downloads already but not for file uploads as tus offers.

tus-js-client is the official client implementation for the tus protocol in JavaScript. It not only supports web browsers, but can also be used in Node.js, React Native, and Apache Cordova applications.

This release addresses a few cases of odd-behavior from tus-js-client to make it more developer-friendly. We also drop support for older environments and add handy feature for handling parallel uploads and file-based streams.

New features

  • Add support for Parallel Uploads for fs.ReadStream
    In the previous major release of tus-js-client v2.0.0 we announced that it now supports parallel upload requests using the Concatenation extension. When enabled, an input file will be split into multiple equally sized parts which are uploaded in parallel. After all requests are finished, the parts will be stitched together on the server-side to produce the original file. The motivation behind this feature is to allow better utilization of network connections and available bandwidth. See the parallelUploads documentation for more details. In this release, support for parallel uploads has been extended to also cover fs.ReadStream as an input type. You can use it like so:
    const path = 'my/file.txt'
    const file = fs.createReadStream(path)
    
    const upload = new tus.Upload(file, {
      endpoint: 'https://tusd.tusdemo.net/files/',
      parallelUploads: 3,
    })
    
  • Add parallelUploadBoundaries option
    If parallel uploads are enabled, this setting can be used to have parts of different size distributions or parts with specific boundaries to satisfy server requirements. See the parallelUploadBoundaries documentation for more details.
  • Automatically obtain file size for fs.ReadStream
    tus-js-client has supported uploading an instance of fs.ReadStream directly for a long time. However, you always had to manually specify the file size, like this:
    const path = 'my/file.txt'
    const file = fs.createReadStream(path)
    const { size } = fs.statSync(path)
    
    const upload = new tus.Upload(file, {
      endpoint: 'https://tusd.tusdemo.net/files/',
      uploadSize: size,
    })
    

    The uploadSize option is now optional and can be left out:

    const path = 'my/file.txt'
    const file = fs.createReadStream(path)
    
    const upload = new tus.Upload(file, {
      endpoint: 'https://tusd.tusdemo.net/files/',
    })
    

    tus-js-client will automatically obtain the file size from disk.

Bug fixes

  • Fix resuming of streams in Node.js
    Previously, if you wanted to upload a non-file-based stream using tus-js-client and paused the upload using abort(), the resumption using start() could cause a hanging upload. This issue has been resolved and resuming properly works now.
  • Fix fingerprint removal after successful upload
    If the removeFingerprintOnSuccess option was used together with uploadDataDuringCreation, the fingerprint was not always properly removed from the URL storage. This issue has been fixed.

Breaking changes

The main behavior of tus-js-client and the vast majority of its API surface stay the same. However, the following breaking changes were necessary:

  • Drop support for Node.js v12 and earlier
    Only Node.js v14 or newer are fully supported and tested for compatibility with tus-js-client from now own. Earlier versions may work, but we don't guarantee or support it.
  • Drop support for Internet Explorer
    Many dependencies have dropped support for Internet Explorer, and so do we now. tus-js-client will not be compatible with any version of Internet Explorer from now on. Please note that we still support all other browsers as before.
  • Rename the exported HttpStack class to DefaultHttpStack
    tus-js-client allows you to provide a custom HTTP stack using which requests are sent out. If not configured, tus-js-client will use a default implementation depending on the environment. Previously, this class was exported under the HttpStack name. This class shared the name with the HttpStack interface and caused a collision when using our TypeScript definitions. As such, we have renamed the HttpStack class (not the interface) to DefaultHttpStack. Please update your references if you are using this class.
  • Do not close streams for abort() calls
    Previously, if you provided a Reader or Readable stream to tus-js-client and called the abort() method, tus-js-client would stop the upload and close the stream. This is problematic because the upload cannot be resumed later because one cannot read from the stream anymore. From now on, tus-js-client will not close the stream anymore to allow later resuming using start() again. If you do not want to continue the upload, you must close the stream now on your own. Please note that tus-js-client still closes the stream if the upload was completed successfully (i.e. onSuccess has been invoked), as it has done in previous releases.
  • Store upload URL provided by uploadUrl
    If you create a new upload, its upload URL will be stored in the URL storage by tus-js-client, so it can later be retrieved using tus.Upload#findPreviousUploads() for resuming the uploads. This behavior is controlled by the storeFingerprintForResuming option. However, not all servers allow clients to create uploads on their own. Sometimes, the server will supply the client with a pre-defined upload URL to use with the uploadUrl option (e.g. the Vimeo API). Previously, these upload URLs were not stored in the URL storage and could therefore not be retrieved for later resumption. This release changes this behavior, so that these URLs are also stored by default, and you can use tus.Upload#findPreviousUploads() to retrieve them. If you do not want to store the upload URL, you can revert to the old behavior by disabling it:
    const upload = new tus.Upload(file, {
      uploadUrl: 'https://tusd.tusdemo.net/files/...',
      storeFingerprintForResuming: false,
    })
    

Try it

If you'd like to try it out, we have updated our demo to use tus-js-client v3.0.0 as well. The code for it can be found here. Do leave a comment there how it went!

Finally, we want to thank everyone who helped to make this release happen! If you also want to contribute, you can find our open source code at GitHub. If you don't know where to start or have other questions, feel free to contact us!