IPFS is a peer-to-peer network for storing and sharing data in a distributed file system. There are various ways for uploading files. Among all using existing websites is the easiest option to try out, but if you want to upload programmatically you have to use APIs. Today I will be explaining two major services that are actively used for IPFS storage.
- Web3 Storage Web3 storage is one of the best services to store data however it has limitations in the free plan as we can only upload up to 5 GiB of files. You can upload files vising the account tab. If you want to upload media using their API, then hover over to the account or visit this link to generate an API key which you can use later
- NFT Storage NFT storage provides free storage for NFTs on IPFS and Filecoin. You can upload files in the Files table after creating an account. Also, we can generate an API key by visiting the API Keys tab which we will be using in the following section.
Using Web3 Storage
- Create a project directory:
mkdir ipfsupload 2. Initialize the project and link it to npm
cd ipfsupload
npm init -y3. Install express and set up basic routes for file upload.
npm i express express-fileupload web3.storage dotenv nodemonAdd "type":"module" in package.json so that we can use module imports
Folder structure:
- server
- controllers
- routes
- temp
- index.js
- .env
- package.json
4. Roll up routes and express server
The final files look like this:
server/index.js
import express from 'express';
import routes from './routes/index.js';
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('IPFS upload server is up and running!');
});
// Mount endpoints
app.use('/api/v1', routes)
app.listen(port, () => console.log('Server ready at: http://localhost:%s', port))server/controllers/upload.controller.js
import dotenv from 'dotenv';
dotenv.config();
import fs from 'fs'
import { Web3Storage, File } from 'web3.storage';
const web3StorageAPIKey = process.env.WEB3_STORAGE_API_KEY;
function makeStorageClient() {
return new Web3Storage({ token: web3StorageAPIKey });
}
async function makeFileObjects(name, description, image) {
const obj = { name, description, image };
const buffer = Buffer.from(JSON.stringify(obj))
const files = [
new File(['contents-of-file-1'], 'plain-utf8.txt'),
new File([buffer], 'metadata.json')
]
return files
}
async function storeFiles(files) {
const client = makeStorageClient()
const cid = await client.put(files)
return cid
}
const fileFromPath = async (image, fileName) => {
const filePath = image.tempFilePath;
const mimeType = image.mimetype;
const content = await fs.promises.readFile(filePath)
const files = [
new File(['contents-of-file-1'], mimeType),
new File([content], fileName)
]
return files
}
const web3StorageUpload = async (req, res) => {
const { name, description } = req.body;
const { image } = req?.files ?? {};
console.log(`Uploading image: [${name}] to ipfs.`);
try {
if (!image && !name && !description || name === undefined) {
return res.status(200).send({ message: 'invalid input' });
}
const imageName = `${new Date().getTime()}_${image.name.replaceAll(' ', '')}`;
const file = await fileFromPath(image, imageName);
const imageCid = await storeFiles(file);
const files = await makeFileObjects(name, description, `https://${imageCid}.ipfs.w3s.link/${imageName}`);
const metaDataCid = await storeFiles(files);
await fs.promises.unlink(image.tempFilePath);
const metadataUrl = `https://${metaDataCid}.ipfs.w3s.link/metadata.json`;
const ipfsTierInfo = {
name,
description,
ipfsUrl: metadataUrl,
};
// TODO: store metadata to db
return res.send(ipfsTierInfo);
} catch (error) {
console.log(`Problem while uploading image to ipfs: ${error}`);
return res.status(500).send({
message: 'Problem while uploading image to ipfs'
})
}
}
export default {
web3StorageUpload,
}server/routes/updalod.route.js
import express from 'express';
import fileUpload from 'express-fileupload';
import controller from '../controllers/upload.controller.js';
const router = express.Router();
router.use(fileUpload({useTempFiles: true}));
router.route('/web3storage')
.post(controller.web3StorageUpload);
export default router;server/routes/index.js
import express from 'express';
import uploadRoute from './upload.route.js';
const router = express.Router();
// Mount upload endpoints
router.use('/upload', uploadRoute);
export default router;.env
WEB3_STORAGE_API_KEY=<your_web3_storage_key>5. Now you should be able to start the server and test the file upload from any rest clients.
npm run startI am using postman and after successful upload API will respond following message.

GitHub Repository: IPFS Upload in NodeJs