React Native

Same primitives, a second entry point. uplofile/native swaps the DOM file dialog for a picker you choose: expo-image-picker, expo-document-picker, react-native-image-picker, or your own.

import { Root, Trigger, Preview } from "uplofile/native";

The picker is yours

Native Root takes one extra prop, pickFiles, invoked instead of a built-in call. If you omit it, Root falls back to @react-native-documents/picker directly and logs a one-time deprecation warning. Pass suppressDeprecationWarnings to silence it if that fallback is intentional.

Deprecated: this fallback, and the @react-native-documents/picker peer dependency it requires, will be removed in the next major version. Migrate to pickFiles, with an adapter above or your own implementation, when you're able to.

Uploader.native.tsx
import * as ImagePicker from "expo-image-picker";
import {
Root,
Trigger,
Preview,
adapterExpoImagePicker,
} from "uplofile/native";
const pickFiles = adapterExpoImagePicker(
ImagePicker.launchImageLibraryAsync,
);
async function putToS3(file: { uri: string; fileName?: string | null }) {
const body = new FormData();
body.append("file", {
uri: file.uri,
name: file.fileName ?? "upload",
} as unknown as Blob);
const response = await fetch("/api/upload", { method: "POST", body });
if (!response.ok) throw new Error("Upload failed");
return response.json(); // { url, id?, meta?, previewUrl? }
}
export function Uploader() {
return (
<Root upload={putToS3} pickFiles={pickFiles}>
<Trigger>Choose photo</Trigger>
<Preview />
</Root>
);
}

Adapters

Four functions in uplofile/native, each wrapping one library's picker call into the shape pickFiles expects. Cancellation and per-library result shapes are handled for you.

adapterReactNativeDocumentsPicker
Wraps @react-native-documents/picker's pick(). Catches its OPERATION_CANCELED throw and resolves an empty array instead. This is also the fallback Root uses when no pickFiles is given.
documents
adapterExpoDocumentPicker
Wraps expo-document-picker's getDocumentAsync(). This library resolves { canceled: true, assets: null } on cancel rather than throwing. That's handled internally.
documents
adapterExpoImagePicker
Wraps expo-image-picker's launchImageLibraryAsync(). Image pickers filter by media category only, so a non-image/video accept is ignored, with a one-time dev warning.
images/video
adapterReactNativeImagePicker
Wraps react-native-image-picker's launchImageLibrary(). Translates its { errorCode, errorMessage } failure shape into a thrown error; same ignored-accept warning as above.
images/video

Root: native-only props

pickFiles(accept, { multiple }) => Promise<TFileSource[]>
Replaces the built-in picker call. Use one of the four adapters above, or write your own function of this shape.
suppressDeprecationWarningsboolean
Temporarily silences the one-time warning logged when pickFiles is omitted and Root falls back to @react-native-documents/picker. It quiets the log, not the removal: that fallback is still going away in the next major version, so treat this as a stopgap while you migrate.
false

What's different from web

File source
No DOM File. Every shared type is generic over TFileSource and infers it from whichever adapter you pass to pickFiles.
No drag-and-drop
onDrop / onDragOver are absent from the native UplofileRootRef. Trigger opens the picker instead.