NFT Metadata (2025): JSON, IPFS & Best Practices
Structure nft metadata correctly for ERC-721/1155, host it reliably, prevent rug-pulls, and keep creator privacy. This guide covers JSON fields, traits, on-chain vs off-chain storage, pinning, and CLI automation.
Start removing metadata right now — local, instant, and private.
Go to MetaRemover.ComReliability
Immutable URIs
Privacy
Image EXIF
Compatibility
Marketplaces
What is NFT metadata?
NFT metadata is a JSON file referenced by tokenURI. It contains human-readable fields (name, description), media links (image, animation_url) and attributes used for traits and filters on marketplaces.
{
"name": "Wave #1",
"description": "Generative ocean pattern",
"image": "ipfs://bafy.../wave1.png",
"animation_url": "ipfs://bafy.../wave1.mp4",
"attributes": [
{ "trait_type": "Palette", "value": "Teal" },
{ "trait_type": "Rarity", "value": "Epic" }
]
}ipfs:// or Arweave URIs in metadata. HTTP links can change or disappear.JSON schema for ERC-721 & ERC-1155
Common fields
Used by most marketplaces
name,description,external_urlimage(PNG/JPEG/GIF/SVG),animation_url(video/HTML)attributesarray for traits (strings or numbers)background_color(hex),youtube_url(optional)
Hosting options: IPFS vs Arweave vs HTTP
| Option | Pros | Cons | Best for |
|---|---|---|---|
| IPFS (+ pinning) | Content-addressed, cheap, decentralized gateways | Needs pinning/redundancy | Most collections |
| Arweave | Permanent storage, TX-anchored | Upfront cost, larger files pricey | Long-term archives |
| HTTP/S3 | Simple, fast CDN | Mutable, central point of failure | Internal previews, staging |
On-chain vs Off-chain metadata
On-chain
Max permanence
- Store JSON or data URI directly in the contract
- Great for tiny SVG/JSON, generative art
- Higher gas, update-unfriendly
Off-chain
Flexible & cheap
- Host on IPFS/Arweave, set
tokenURIto the CID - Pin across multiple providers
- Use content hashes for verification
Traits & rarity
Use attributes for filterable traits. Stick to consistent naming and value types. Numeric traits should be numbers, not strings. Avoid leaking private data in attributes (e.g., GPS).
"attributes": [
{ "trait_type": "Background", "value": "Ocean" },
{ "trait_type": "Glow", "display_type": "boost_percentage", "value": 25 },
{ "trait_type": "Level", "display_type": "number", "value": 7 }
]Tools & generators
Common steps
End-to-end
- Generate artwork & export to lossless formats
- Scrub image EXIF (see privacy tip below)
- Create JSON metadata programmatically
- Upload media → get CID → reference in JSON
- Upload JSON → set
tokenURI→ pin
CLI automation
Generate JSON
Node.js script (example)
// generate.js
const fs = require('fs');
const items = [
{ id: 1, name: 'Wave #1', imageCid: 'bafy...1', palette: 'Teal' },
{ id: 2, name: 'Wave #2', imageCid: 'bafy...2', palette: 'Purple' }
];
for (const it of items) {
const meta = {
name: it.name,
description: 'Generative ocean pattern',
image: 'ipfs://' + it.imageCid,
attributes: [{ trait_type: 'Palette', value: it.palette }]
};
fs.writeFileSync(`./metadata/${it.id}.json`, JSON.stringify(meta, null, 2));
}Pin & verify
API or CLI
# ipfs-cli examples ipfs add --cid-version=1 --pin ./images/* ipfs add --cid-version=1 --pin ./metadata/* # Verify that each tokenURI CID exists # and that image CIDs referenced by JSON resolve via a gateway.
Image privacy: remove EXIF before minting
Photos often include hidden EXIF/GPS, camera serials, and authoring software tags. Once minted and replicated to IPFS, that data can spread forever. Always sanitize images before you upload.
FAQ
Ship trustworthy NFTs — and protect creator privacy
Use immutable URIs, pin your CIDs, validate JSON, and scrub image EXIF before minting. Fewer surprises after launch.