Back to Blog
·13 min

NFT Marketplace Development: Launch Your Own Platform

The NFT ecosystem has evolved far beyond profile pictures. In 2026, NFTs power gaming assets, real estate tokens, intellectual property rights, membership passes, and financial instruments. Building an NFT marketplace requires careful consideration of smart contract standards, metadata management, royalty enforcement, and user experience.

NFT Standards and When to Use Them

Before building your marketplace, understand the token standards:

  • ERC-721: The original NFT standard. Best for unique assets like art, collectibles, and real estate.
  • ERC-1155: Multi-token standard. Efficient for gaming items, where multiple copies of the same asset exist.
  • ERC-4906: Metadata update standard. Allows creators to update NFT metadata after minting.
  • ERC-2981: Royalty standard. Enforces creator royalties on secondary sales.

Marketplace Architecture

A production NFT marketplace built with the NFT Marketplace Pro template includes:

git clone https://github.com/breafio/nft-marketplace-pro.git my-marketplace
cd my-marketplace
pnpm install
cp .env.example .env.local

Smart Contract Architecture

The marketplace contract handles listings, offers, and settlements:

// contracts/Marketplace.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

contract Marketplace is Ownable, ReentrancyGuard {
    uint256 public listingFee = 0.025 ether;
    uint256 public royaltyFee = 250; // 2.5%

    struct Listing {
        address seller;
        address nftContract;
        uint256 tokenId;
        uint256 price;
        address paymentToken;
        bool isActive;
        uint256 tokenType; // 721 or 1155
    }

    mapping(uint256 => Listing) public listings;
    uint256 public listingCount;

    event ItemListed(
        uint256 indexed listingId,
        address indexed seller,
        address indexed nftContract,
        uint256 tokenId,
        uint256 price
    );

    event ItemSold(
        uint256 indexed listingId,
        address indexed buyer,
        address indexed seller,
        uint256 price
    );

    function listItem(
        address nftContract,
        uint256 tokenId,
        uint256 price,
        address paymentToken,
        uint256 tokenType
    ) external payable {
        require(price > 0, "Price must be greater than zero");
        require(msg.value == listingFee, "Listing fee required");

        listings[listingCount] = Listing({
            seller: msg.sender,
            nftContract: nftContract,
            tokenId: tokenId,
            price: price,
            paymentToken: paymentToken,
            isActive: true,
            tokenType: tokenType
        });

        if (tokenType == 721) {
            IERC721(nftContract).transferFrom(msg.sender, address(this), tokenId);
        } else if (tokenType == 1155) {
            IERC1155(nftContract).safeTransferFrom(
                msg.sender, address(this), tokenId, 1, ""
            );
        }

        emit ItemListed(listingCount, msg.sender, nftContract, tokenId, price);
        listingCount++;
    }
}

Minting with Reveal Mechanics

Generative NFT collections often use reveal mechanics to maintain fairness:

// lib/nft/mint.ts
import { createWalletClient, custom } from 'viem'
import { mainnet } from 'viem/chains'

export async function mintNFT(
  contractAddress: string,
  quantity: number,
  merkleProof?: string[]
) {
  const [account] = await window.ethereum.request({
    method: 'eth_requestAccounts'
  })

  const client = createWalletClient({
    account,
    chain: mainnet,
    transport: custom(window.ethereum)
  })

  const hash = await client.writeContract({
    address: contractAddress as string,
    abi: nftAbi,
    functionName: merkleProof ? 'allowlistMint' : 'publicMint',
    args: merkleProof ? [account, quantity, merkleProof] : [account, quantity],
    value: parseEther((0.08 * quantity).toString()),
  })

  return hash
}

Metadata Management

NFT metadata should be stored on IPFS for permanence:

// lib/nft/metadata.ts
import { NFTStorage, File } from 'nft.storage'

const client = new NFTStorage({
  token: process.env.NFT_STORAGE_API_KEY!,
})

interface NFTMetadata {
  name: string
  description: string
  image: File
  attributes: { trait_type: string; value: string }[]
}

export async function uploadMetadata(metadata: NFTMetadata): Promise<string> {
  const cid = await client.store({
    name: metadata.name,
    description: metadata.description,
    image: metadata.image,
    properties: { attributes: metadata.attributes },
  })
  return `ipfs://${cid}/metadata.json`
}

Auction System

Dutch auctions and English auctions attract different buyer behaviors:

'use client'

import { useState, useEffect } from 'react'
import { useWriteContract } from 'wagmi'

interface DutchAuctionProps {
  startPrice: bigint
  endPrice: bigint
  duration: number
  startTime: number
}

export function DutchAuction({ startPrice, endPrice, duration, startTime }: DutchAuctionProps) {
  const [currentPrice, setCurrentPrice] = useState(startPrice)
  const { writeContract } = useWriteContract()

  useEffect(() => {
    const interval = setInterval(() => {
      const elapsed = (Date.now() / 1000) - startTime
      const progress = Math.min(elapsed / duration, 1)
      const price = startPrice - ((startPrice - endPrice) * BigInt(Math.floor(progress * 100))) / 100n
      setCurrentPrice(price)
    }, 1000)
    return () => clearInterval(interval)
  }, [startPrice, endPrice, duration, startTime])

  return (
    <div className="rounded-xl border p-6">
      <h3 className="font-semibold">Dutch Auction</h3>
      <p className="mt-2 text-3xl font-bold">
        {formatEther(currentPrice)} ETH
      </p>
      <button
        onClick={() => writeContract({
          address: process.env.NEXT_PUBLIC_MARKETPLACE as string,
          abi: marketplaceAbi,
          functionName: 'buyWithDutchAuction',
          value: currentPrice,
        })}
        className="mt-4 rounded-xl bg-brand-600 px-6 py-2 font-semibold text-white"
      >
        Buy Now
      </button>
    </div>
  )
}

The Bottom Line

Launching an NFT marketplace requires expertise across smart contracts, IPFS storage, wallet integration, and auction mechanics. The NFT Marketplace Pro template provides all of this out of the box, along with royalty enforcement, collection browsing, and a seamless minting experience.

Ready to Build?

Get started with our production-ready starter kits and ship your project faster.

Browse Starter Kits