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.
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@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.adapterExpoDocumentPickerexpo-document-picker's getDocumentAsync(). This library resolves { canceled: true, assets: null } on cancel rather than throwing. That's handled internally.adapterExpoImagePickerexpo-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.adapterReactNativeImagePickerreact-native-image-picker's launchImageLibrary(). Translates its { errorCode, errorMessage } failure shape into a thrown error; same ignored-accept warning as above.Root: native-only props
pickFiles(accept, { multiple }) => Promise<TFileSource[]>suppressDeprecationWarningsbooleanpickFiles 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.What's different from web
File sourceFile. Every shared type is generic over TFileSource and infers it from whichever adapter you pass to pickFiles.No drag-and-droponDrop / onDragOver are absent from the native UplofileRootRef. Trigger opens the picker instead.