Skip to content

Upload

GitHubnpmcrates.io
API Reference:

Upload files from disk to a remote server over HTTP. Download files from a remote HTTP server to disk.

This plugin requires a Rust version of at least 1.90

PlatformLevelNotes
windows
linux
macos
android
ios

Use your project’s package manager to add the dependency:

npm run tauri add upload

Once you’ve completed the registration and setup process for the plugin, you can access all of its APIs through the JavaScript guest bindings.

upload sends the file as the raw request body (not multipart/form-data) and returns the response body as text:

import { upload } from '@tauri-apps/plugin-upload';
// when using `"withGlobalTauri": true`, you may use
// const { upload } = window.__TAURI__.upload;
const response = await upload(
'https://example.com/file-upload',
'/path/to/my/file.txt',
({ progressTotal, total }) =>
console.log(`Uploaded ${progressTotal} of ${total} bytes`), // a callback that will be called with the upload progress
{ 'Content-Type': 'text/plain' } // optional headers to send with the request
);

It sends a POST request by default. To use PUT or PATCH, pass an HttpMethod as the fifth argument:

import { upload, HttpMethod } from '@tauri-apps/plugin-upload';
await upload(
'https://example.com/file-upload',
'/path/to/my/file.txt',
undefined, // no progress callback
{ 'Content-Type': 'text/plain' },
HttpMethod.Put
);

download saves the response body to the given file path:

import { download } from '@tauri-apps/plugin-upload';
// when using `"withGlobalTauri": true`, you may use
// const { download } = window.__TAURI__.upload;
await download(
'https://example.com/file-download-link',
'/path/to/save/my/file.txt',
({ progressTotal, total }) =>
console.log(`Downloaded ${progressTotal} of ${total} bytes`), // a callback that will be called with the download progress
{ Authorization: 'Bearer <token>' } // optional headers to send with the request
);

It sends a GET request by default. If you pass a body as the fifth argument, it sends a POST request with that body instead:

import { download } from '@tauri-apps/plugin-upload';
await download(
'https://example.com/export',
'/path/to/save/report.csv',
undefined, // no progress callback
{ 'Content-Type': 'application/json' },
JSON.stringify({ format: 'csv' })
);

The progress callback runs for each chunk and receives:

  • progress: bytes in the last chunk, not the running total
  • progressTotal: bytes transferred so far
  • total: total size in bytes. For downloads this comes from the Content-Length header and is 0 if the server doesn’t send it.
  • transferSpeed: approximate speed in bytes per second

Relative paths are resolved against the app’s working directory, which is different in tauri dev and in a bundled app. Use absolute paths instead, for example with the path API:

import { appDataDir, join } from '@tauri-apps/api/path';
const filePath = await join(await appDataDir(), 'file.txt');

When downloading, the parent directory must already exist, and any existing file at that path is overwritten. If the download fails, the partial file is not removed.

Both functions reject if the file can’t be read or written, the request fails, or the server returns an error status.

By default all potentially dangerous plugin commands and scopes are blocked and cannot be accessed. You must modify the permissions in your capabilities configuration to enable these.

See the Capabilities Overview for more information and the step by step guide to use plugin permissions.

src-tauri/capabilities/default.json
{
"permissions": [
...,
"upload:default",
]
}

Default Permission

This permission set configures what kind of operations are available from the upload plugin.

Granted Permissions

All operations are enabled by default.

This default permission set includes the following:

  • allow-upload
  • allow-download

Permission Table

Identifier Description

upload:allow-download

Enables the download command without any pre-configured scope.

upload:deny-download

Denies the download command without any pre-configured scope.

upload:allow-upload

Enables the upload command without any pre-configured scope.

upload:deny-upload

Denies the upload command without any pre-configured scope.


© 2026 Tauri Contributors. CC-BY / MIT