# @rpldy/tus-sender

> react-uploady sender implementation of the TUS protocol

Latest version **1.13.0** (published 2025-11-26) · MIT license · 0 weekly downloads

## Install

```sh
npm install @rpldy/tus-sender
pnpm add @rpldy/tus-sender
yarn add @rpldy/tus-sender
bun add @rpldy/tus-sender
```

## Health

**Score 60/100 (C)** — status: stable.

Positive: has types; esm support; no vulnerabilities; high maintenance score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 1.13.0 |
| Published | 2025-11-26 |
| First published | 2020-05-31 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 5 |
| Unpacked size | 93.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1252 |
| Author | yoav niran (https://github.com/yoavniran) |
| Maintainers | yoavniran |
| Keywords | tus, resumable, upload, send, file upload |

## Links

- npm: https://www.npmjs.com/package/@rpldy/tus-sender
- Repository: https://github.com/rpldy/react-uploady
- Homepage: https://react-uploady.org
- Funding: https://opencollective.com/react-uploady
- npm.io page: https://npm.io/package/@rpldy/tus-sender

## Dependencies (5)

- [@rpldy/sender](https://npm.io/package/@rpldy/sender.md) 1.13.0
- [@rpldy/shared](https://npm.io/package/@rpldy/shared.md) 1.13.0
- [@rpldy/safe-storage](https://npm.io/package/@rpldy/safe-storage.md) 1.13.0
- [@rpldy/simple-state](https://npm.io/package/@rpldy/simple-state.md) 1.13.0
- [@rpldy/chunked-sender](https://npm.io/package/@rpldy/chunked-sender.md) 1.13.0

## Alternatives

- [@expo/fingerprint](https://npm.io/package/@expo/fingerprint.md) — 6.2M weekly downloads
- [@azure/monitor-opentelemetry-exporter](https://npm.io/package/@azure/monitor-opentelemetry-exporter.md) — 850.0K weekly downloads
- [@azure/monitor-opentelemetry](https://npm.io/package/@azure/monitor-opentelemetry.md) — 624.0K weekly downloads
- [@posthog/ai](https://npm.io/package/@posthog/ai.md) — 423.3K weekly downloads
- [fakefilter](https://npm.io/package/fakefilter.md) — 63.9K weekly downloads

## Recent versions

- 1.13.0 (latest) — 2025-11-26
- 1.12.0-rc.0 (next) — 2025-10-28
- 1.4.2-alpha.0 (alpha) — 2023-03-27
- 1.12.0 — 2025-10-30
- 1.11.0 — 2025-07-18
- 1.10.0 — 2025-04-18
- 1.9.1 — 2025-02-07
- 1.9.0 — 2024-12-13
- 1.9.0-rc.2 — 2024-12-08
- 1.9.0-rc.1 — 2024-11-10
- 1.9.0-rc.0 — 2024-11-04
- 1.8.3 — 2024-08-19
- 1.8.2 — 2024-07-30
- 1.8.1 — 2024-05-16
- 1.8.0 — 2024-02-22
- … 89 more at https://npm.io/package/@rpldy/tus-sender/versions

## README

<a href="https://opencollective.com/react-uploady">
    <img src="https://img.shields.io/opencollective/all/react-uploady?style=flat&logo=opencollective&label=Support%20us!&color=blue" alt="Support on Open Collective"/>
</a>
<a href="https://badge.fury.io/js/%40rpldy%2Ftus-sender">
    <img src="https://badge.fury.io/js/%40rpldy%2Ftus-sender.svg" alt="npm version" height="20"></a>
<a href="https://github.com/rpldy/react-uploady/actions/workflows/pr.yml">
        <img src="https://github.com/rpldy/react-uploady/actions/workflows/pr.yml/badge.svg" alt="Build Status"/></a>  
<a href="https://codecov.io/gh/rpldy/react-uploady">
    <img src="https://codecov.io/gh/rpldy/react-uploady/branch/master/graph/badge.svg" alt="codecov status"/></a> 
<a href="https://bundlephobia.com/result?p=@rpldy/tus-sender">
    <img src="https://badgen.net/bundlephobia/minzip/@rpldy/tus-sender" alt="bundlephobia badge"/></a>
<a href="https://react-uploady-storybook.netlify.app/?path=/docs/core-tus-sender--docs">
   <img src="https://cdn.jsdelivr.net/gh/storybookjs/brand@master/badge/badge-storybook.svg" alt="rpldy storybook"/></a> 


# TUS Sender

An Uploady sender implementation of the TUS protocol.

Supports version 1.0.0 of the [TUS protocol](https://tus.io/protocols/resumable-upload.html)

Under the hood, the tus-sender uses the [@rpldy/chunked-sender](https://react-uploady.org/docs/packages/rpldy-chunked-sender/) to upload the files as chunks 

**The best place to get started is at our: [React-Uploady Documentation Website](https://react-uploady.org)**

## Installation

```shell
#Yarn:
  $ yarn add @rpldy/tus-sender

#NPM:
  $ npm i @rpldy/tus-sender
``` 

## TUS Protocol

On top of the Core Protocol, Uploady supports the following extensions:

- [Creation](https://tus.io/protocols/resumable-upload.html#creation) (creation)
- [Creation with Upload](https://tus.io/protocols/resumable-upload.html#creation-with-upload) (creation-with-upload)
- [Concatenation](https://tus.io/protocols/resumable-upload.html#concatenation) (concatenation)
- [Creation Defer Length](https://tus.io/protocols/resumable-upload.html#upload-defer-length) (creation-defer-length)

It also supports the __Upload-Metadata__ header and will turn the destination/upload options __params__ prop into the metadata key/value.

## Options

| Name (* = mandatory)        | Type                      | Default         | Description                                                                                                            |
|-----------------------------|---------------------------|-----------------|------------------------------------------------------------------------------------------------------------------------|
| version                     | string                    | "1.0.0"         | The tus server version                                                                                                 |
| featureDetection            | boolean                   | false           | whether to query the server for supported extensions                                                                   |
| featureDetectionUrl         | string                    | null            | URL to query for TUS server feature detection, in case it's different from upload URL                                  |
| onFeaturesDetected          | (string[]) => ?TusOptions | void            | callback to handle the extensions the server broadcasts                                                                |
| resume                      | boolean                   | true            | whether to store information locally on files being uploaded to support resuming                                       |
| deferLength                 | boolean                   | false           | defer sending file length to server ([protocol](https://tus.io/protocols/resumable-upload.html#upload-defer-length))   |
| overrideMethod              | boolean                   | false           | whether to use X-HTTP-Method-Override header instead of PATCH                                                          |
| sendDataOnCreate            | boolean                   | false           | send first chunk with create request ([protocol](https://tus.io/protocols/resumable-upload.html#creation-with-upload)) |
| storagePrefix               | string                    | "__rpldy-tus__" | the key prefix to use for persisting resumable info about files                                                        |
| lockedRetryDelay            | number                    | 2000            | milliseconds to wait before retrying a locked (423) resumable file                                                     |
| forgetOnSuccess             | boolean                   | false           | whether to remove URL from localStorage when upload finishes successfully                                              |
| ignoreModifiedDateInStorage | boolean                   | false           | ignore File's modified date when creating key for storage                                                              |
| resumeHeaders               | Record<string, string>    | null            | Headers to use for the resume check (HEAD) request                                                                     |

> All of the [chunked-sender options](https://react-uploady.org/docs/api/senders/mockSender/#options) are supported with this sender

> When the chunked-sender parallel param is set to > 1, the Concatenation tus extension will be used.
>It will send the chunks as different parallel requests that are finalized once done.

> Params prop that is set on the Destination or upload options is serialized (encoded according to Tus protocol) and sent as the value of the Upload-Metadata header.

> Custom headers set on the Destination will be sent (and override existing headers) with the Creation request      

## Feature Detection

When the featureDetection option is enabled, the tus-sender will request the supported extensions' info from the server.

In case there are options that aren't supported by the extensions list the server provides, 
they will be turned off.

These options are:

- parallel: requiring the _concatenation_ extension
- sendDataOnCreate: requiring the _creation_with_upload_ extension
- deferLength: requiring the _creation_defer_length_ extension

When _onFeaturesDetected_ callback is provided, the responsibility to turn off options that aren't supported
is handed over to the callback. The object returned by the callback will be merged with options being used, overriding them as needed.

> For feature detection to work, when the TUS server is served from a different origin than the page making the request, 
the server must allow these headers: __Tus-Extension__ and __Tus-Version__ to be read over CORS. 
>Otherwise, it will not work and feature detection will be skipped.

## Example

```javascript
import React, { useCallback, useEffect, useRef } from "react";
import createUploader from "@rpldy/uploader";
import getTusEnhancer from "@rpldy/tus-sender";

export const App = () => {
	const inputRef = useRef(null);
	const uploaderRef = useRef(null);

	useEffect(() => {
		const tusEnhancer = getTusEnhancer({
            parallel: 2,                
		});

		uploaderRef.current = createUploader({
			enhancer: tusEnhancer,
			destination: {url: "my-tus-server.com"},
			params: {
				source: "rpldy",		
			}
		});
	}, []);

	const onClick = useCallback(() => {
		const input = inputRef.current;
		if (input) {
			input.value = "";
			input.click();
		}
	}, []);

	const onInputChange = useCallback(() => {
		uploaderRef.current?.add(inputRef.current?.files);
	}, []);

	return <div>
		<input type="file" ref={inputRef} style={{ display: "none" }} onChange={onInputChange}/>
		<button id="upload-button" onClick={onClick}>Upload with TUS</button>
	</div>
};

```

## Events

The TUS Sender exposes a RESUME_START event.
See [uploader events](https://react-uploady.org/docs/api/events/) section on more info regarding how to register for events.

### TUS_EVENTS.RESUME_START

Triggered before the (HEAD) request is issued on behalf of a potentially resumeable upload.

> This event is _[cancellable](https://react-uploady.org/docs/api/events/#cancellable-events)_

The event handler receives a [ResumeStartEventData](https://react-uploady.org/docs/api/types/#resumestarteventdata) object

### TUS_EVENTS.PART_START

Triggered before a (PATCH) request is issued to upload a chunk (part) of a file.

The event handler receives a [PartStartEventData](https://react-uploady.org/docs/api/types/#tuspartstarteventresponse) object

---
_Source: https://npm.io/package/@rpldy/tus-sender · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
