Library / SDK
apache/cordova-plugin-file-transfer avatar
apache/cordova-plugin-file-transfer

When cordova-plugin-file-transfer still beats the Fetch API

Apache Cordova File Transfer Plugin

608 stars873 forksJavaScriptApache-2.0

At a glance

What is it?
The Cordova File Transfer plugin uploads and downloads files through native code, and the project itself argues it is the better choice when downloads are large, slow to save, or crash-prone. It ships for Android, iOS and the browser under Apache 2.0.
Who is it for?
Adopt cordova-plugin-file-transfer when your Cordova app moves large files and the Fetch API or XMLHttpRequest path is failing on memory, timeouts or interrupted saves. Skip it for small payloads, where the project says the plugin is probably unnecessary, and for apps that have no Cordova runtime.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The plugin argues against itself, which is the interesting part

The usage notice at the top of the documentation is unusually candid for a plugin README. It says that with the Fetch API and XMLHttpRequest available, this plugin may not be needed for your use case, and that for small file transfers you probably will not require it. Then it narrows the scope where the native implementation still wins: large downloads, transfers suffering from slow saving, timeouts, or crashes. The reason is architectural. A web API transfer runs inside the webview process, where the response body is held in memory before the JavaScript layer can write it to disk. The native path streams to a file instead, so the size of the payload stops being a memory problem. That distinction is the whole value proposition, and it is also the reason the project points you at a Cordova blog post about migrating from FileTransfer to XMLHttpRequest rather than pretending the plugin is the only option.

A global constructor that does not exist until deviceready fires

The plugin defines the global `FileTransfer` object and the `FileUploadOptions` constructor. Both live in the global scope, but the documentation is emphatic that they are not available until after the `deviceready` event, which is the standard Cordova bridge start signal. The pattern to follow is the one the README gives.

js
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
    console.log(FileTransfer);
}

Touching `FileTransfer` earlier is the classic way this plugin fails for newcomers, and the failure is a reference error rather than a graceful message. The same ordering rule applies to any other Cordova plugin you pair with it. The `FileTransfer` object exposes three methods and one property: `upload` sends a file to a server, `download` fetches a file, `abort` cancels a transfer in progress, and `onprogress` is called with a `ProgressEvent` each time a new chunk of data is transferred. That last callback is what makes long transfers show a progress bar instead of appearing to hang.

Upload options decide the wire format on the server side

The `upload` method takes a filesystem URL for the file, a server URL, success and error callbacks, and an optional options object. Those options are where the real behaviour lives, because they determine what your server receives. The `fileKey` is the name of the form element and defaults to `file`. The `fileName` is the name used when saving on the server and defaults to `image.jpg`, a default that surprises people. The `httpMethod` is either `PUT` or `POST` and defaults to `POST`. The `mimeType` defaults to `image/jpeg`. `params` adds key/value pairs to the request and `headers` sets request headers, where a hash allows more than one value for the same header name. `chunkedMode` decides whether the upload is sent as chunked streaming and defaults to `true`. One header rule is worth memorising: on iOS, FireOS and Android, if a header named Content-Type is present, multipart form data will NOT be used. The `fileURL` parameter also accepts a data URI, and for backwards compatibility the full device path of the file.

js
// !! Assumes variable fileURL contains a valid URL to a text file on the device,
//    for example, cdvfile://localhost/persistent/path/to/file.txt

var win = function (r) {
    console.log("Code = " + r.responseCode);
    console.log("Response = " + r.response);
    console.log("Sent = " + r.bytesSent);
}

var fail = function (error) {
    alert("An error has occurred: Code = " + error.code);
    console.log("upload error source " + error.source);
    console.log("upload error target " + error.target);
}

The callbacks show the shape of the result object, with a response code, a response body and a byte count for the success path, and a code, a source and a target on failure.

Adding the plugin and the platform baseline it expects

Installation is a single Cordova command.

bash
cordova plugin add cordova-plugin-file-transfer

After that the plugin is available to the web layer under the same `deviceready` rule. The repository layout shows the split across native and JavaScript halves: a `src` directory for the native implementations, a `www` directory for the JavaScript interface, a `types` directory holding the TypeScript declarations, and a `tests` directory. The `plugin.xml` file is the manifest that maps those pieces onto the three supported platforms, which the README lists as Android, Browser and iOS. The browser target matters more than it first appears, since it lets you exercise transfer code in the browser during development rather than on a device, although the streaming behaviour that motivates the plugin exists only on the native targets.

The trustAllHosts option is the sharpest edge in the API

One option deserves to be read twice. `trustAllHosts` is an optional parameter that defaults to `false`, and when set to `true` it accepts all security certificates. The documentation says plainly that this is not recommended for production use, and it is supported on iOS. A developer wiring it up to silence a certificate error in staging has effectively disabled transport security for every transfer in the app, and because the option lives on the upload call rather than on a global setting, it is easy to leave enabled on one path and forgotten elsewhere. The safer handling is to install the correct certificate in the app bundle and leave the default in place. This is a reminder that the plugin still performs real network work with real credentials, and the failure mode of getting the security posture wrong is not a warning dialog.

Licence, release cadence and what the plugin does not cover

The plugin is published by the Apache Software Foundation under the Apache License 2.0, so using it in a closed source app carries no obligation to publish your own code, though the licence text and notices must be retained in any redistribution. The most recent published release is 2.0.1 on 2026-08-10, and the last push to the repository was on 2026-10-18, with the package manifest already at version 2.0.2-dev.0. The `package.json` also records a platform baseline through `cordovaDependencies`, where the 2.0.0 line requires cordova-android >=12.0.0 and the 3.0.0 line requires cordova >100, so the plugin version and the platform version are coupled and an upgrade of one implies an upgrade of the other. On the documentation side, the README covers the core object and its parameters but does not document a download options set in comparable detail, nor does it explain how `abort` interacts with a partially written file on disk. If your application depends on resuming or cancelling large downloads, that gap is the first thing to raise with the project, and the Cordova issue tracker is the place the README points to for it.

Editorial conclusion

Adopt cordova-plugin-file-transfer when your Cordova app moves large files and the Fetch API or XMLHttpRequest path is failing on memory, timeouts or interrupted saves. Skip it for small payloads, where the project says the plugin is probably unnecessary, and for apps that have no Cordova runtime. Before you commit, check the `trustAllHosts` default and decide how your server handles the multipart field names the upload options define, then confirm the plugin version matches your cordova-android baseline.

Frequently asked questions

Do I still need cordova-plugin-file-transfer now that Fetch exists?

Probably not for small transfers, according to the usage notice, which says the plugin may not be needed and that for small file transfers you probably will not require it. It recommends the plugin for large downloads that suffer from slow saving, timeouts or crashes.

How do I access FileTransfer in a Cordova app?

The global `FileTransfer` and `FileUploadOptions` constructors are not available until after the `deviceready` event fires. Register a listener for `deviceready` and use the constructor inside that callback.

Which platforms does cordova-plugin-file-transfer support?

The README lists Android, Browser and iOS, and the package manifest declares the same three platforms in its cordova block.

What does the trustAllHosts option do in cordova-plugin-file-transfer?

It is an optional parameter that defaults to `false`, and when set to `true` it accepts all security certificates. The documentation says it is not recommended for production use and that it is supported on iOS.

Official sources

  1. apache/cordova-plugin-file-transfer on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/apache-cordova-plugin-file-transfer.svg)](https://hysenlabs.com/projects/apache-cordova-plugin-file-transfer)

Was this useful?