Skip to main content

Upload to IPFS

You can upload arbitrary files and JSON data to IPFS using from both frontend and backend applications using our SDKs, or you can easily upload from your machine using our CLI.


You can easily upload any file or directory from your machine to IPFS using the CLI.

You can upload any file to IPFS by passing the file path to upload to the CLI with the following command:

npx thirdweb upload ./path/to/file.jpg

Alternatively, you can upload an entire directory to IPFS, which will upload any files within the specified directory into a single IPFS directory (all files will have the same base hash) - note that folders inside the specified folder won't be recursively uploaded - this works with the following command.

npx thirdweb upload ./path/to/folder


You can also upload files to IPFS from your React frontend applications using our React SDK, which you can install with the following command:

npm install @thirdweb-dev/react

Once you have the SDK installed, you can upload files from your application with the following setup:

import { useStorageUpload } from "@thirdweb-dev/react";

export default function Component() {
const { mutateAsync: upload } = useStorageUpload();

async function uploadData() {
// Get any data that you want to upload
const dataToUpload = [...];

// And upload the data with the upload function
const uris = await upload({ data: dataToUpload });


It's also easy to plug the useStorageUpload hook into common React upload libraries like react-dropzone to create an input component to upload selected user files to IPFS:

import { useStorageUpload } from "@thirdweb-dev/react";

export default function Component() {
const { mutateAsync: upload } = useStorageUpload();
const onDrop = useCallback(
async (acceptedFiles: File[]) => {
const uris = await upload({ data: acceptedFiles });
const { getRootProps, getInputProps } = useDropzone({ onDrop });

return (
<div {...getRootProps()}>
<input {...getInputProps()} />
<p>Drop files here to upload them to IPFS</p>


Alternatively, you can upload files from backends or scripts using our Storage SDK, which you can install as follows:

npm install @thirdweb-dev/storage

We can easily upload files with the upload function from any backend or script using only a few lines of code:

import { readFileSync } from "fs";

// First we load a file from our local file system
const file = readFileSync("path/to/file.jpg");

// And now we can upload it to IPFS with a single line of code
const uri = await storage.upload(file);

We can also upload JSON metadata with the upload function, and the SDK will automatically handle parsing any recognized gateway URLs to proper decentralized URL schemes and will recursively upload files to IPFS and replace them with URL schemes.

For example, let's say that we want to upload the following JSON object:

// We define metadata for an NFT
const metadata = {
name: "NFT #1",
description: "This is my first NFT",
// Here we add a file into the image property of our metadata
image: readFileSync("path/to/file.jpg"),
properties: [
name: "coolness",
value: "very cool",

And now we can upload it to IPFS with the SDK with a single line of code:

// Here we get the IPFS URI of where our metadata has been uploaded
const uri = await storage.upload(metadata);
// This will log a URL like ipfs://QmWgbcjKWCXhaLzMz4gNBxQpAHktQK6MkLvBkKXbsoWEEy/0

If you navigate to the URL with the resolved scheme, you'll see that the data will look something like the following (you can see an example metadata upload in the browser here):


Notice that in addition to uploading the metadata for us, the SDK has also automatically detected the image file within the object, uploaded it to its own IPFS URL, and linked the URL back in our object as well - you can take look at the image uploaded in the above metadata here.

You can also bulk upload a group of files or a group JSON objects together and they will be uploaded to a single directory.

For example, we can upload several files together as follows:

const files = [

const uris = await storage.uploadBatch(files);

// And now we can get the URIs for each file