Compress File Before Uploading

Stream supports image and file uploads up to 100 MB. Compressing files before upload can help avoid hitting the limit, especially for video.

You can use the following prop on the Channel component to compress the file before upload:

Best Practices

  • Compress only when needed; avoid re-encoding already small files.
  • Preserve original MIME type and filename so downstream clients render correctly.
  • Validate uri, name, and type before compression to avoid runtime failures.
  • Handle failures gracefully and fall back to the uncompressed upload when possible.
  • Apply the same compression policy in MessageComposer and Channel to avoid inconsistency.

The function expects a FileReference and returns a Promise<MinimumUploadRequestResult>.

FileReference extends the web File type and is defined as:

export type FileReference = Pick<File, "name" | "size" | "type"> & {
  uri: string;
  height?: number;
  width?: number;
  duration?: number;
  waveform_data?: number[];
  thumb_url?: string;
};

where the type is the MIME type of the file.

You must specify the uri, name and type and possibly the size of the file in the FileReference object.

Example: compress a video before upload using react-native-compressor.

import { FileReference } from "stream-chat";
import { Channel, ChannelProps } from "stream-chat-react-native";
import { Video as VideoCompressor } from "react-native-compressor";

const customDoFileUploadRequest: NonNullable<
  ChannelProps["doFileUploadRequest"]
> = async (file: FileReference) => {
  if (!file.uri) {
    throw new Error("Invalid file provided. The `uri` is required.");
  }
  // check if it is a video file using the MIME type
  if (file.type?.startsWith("video/")) {
    const result = await VideoCompressor.compress(file.uri, {
      compressionMethod: "auto",
    });
    // set the local file uri to the compressed file
    file.uri = result;
  }

  // send the file
  return channel.sendFile(file.uri, file.name, file.type);
};

<Channel channel={channel} doFileUploadRequest={customDoFileUploadRequest}>
  {/** ... */}
</Channel>;

You can also set this globally via MessageComposer using attachments.doUploadRequest. See configuration setup.