Build Your First Solana NFT Collection with Metaplex Core

Want to understand how Mad Lads, Okay Bears, or DeGods actually work? Build your own NFT collection on Solana.

In the next 90-120 minutes, you'll deploy a complete NFT collection to Solana's devnet. A real collection that appears in Phantom wallet, can be listed on Magic Eden, and follows the same Metaplex standard powering billions in Solana NFT trading volume. More importantly, you'll learn why Solana NFTs cost fractions of a cent to mint, how the account model differs from Ethereum's contract model, and what makes Metaplex the backbone of Solana's NFT ecosystem.

Note: If you've completed the ERC-721 guidearrow-up-right, you'll notice some conceptual similarities--but Solana's architecture works differently from the ground up. No smart contracts here. Instead, you'll interact with pre-deployed programs and create accounts that hold your NFT data.

What You'll Learn

You'll understand the architecture behind every successful Solana NFT project:

  • Why Solana NFTs cost less than $0.01 to mint: Solana's account model and rent system mean you're paying for storage space, not computation. A single NFT mint costs roughly 0.01 SOL (~$0.01-0.02), compared to $50-150+ on Ethereum (and $500+ during network congestion).

  • How Metaplex became the NFT standard: Unlike Ethereum where every project deploys its own contract, Solana projects share the same Metaplex programs. This creates instant ecosystem compatibility because every wallet and marketplace speaks the same language.

  • Why there are no "smart contracts" to write: Solana uses pre-deployed programs. You don't write Solidity-like code; instead, you call existing programs with the right account structures. Metaplex handles the complexity.

  • Where your NFT data actually lives: Token accounts, metadata accounts, master edition accounts. Understanding this architecture is critical to grasping how Solana NFTs work.

What You Need

Requirement
Why It Matters
Get It Here

Node.js & npm

Runs the TypeScript tooling and manages dependencies

Solana CLI

Creates wallets, airdrops test SOL, and configures your local environment

Phantom wallet

Browser wallet for viewing your NFTs and interacting with Solana dApps

Devnet SOL

Free test tokens for development (we'll airdrop these via CLI)

Built into Solana CLI

Arweave storage

Hosts your NFT images and metadata permanently--the Solana ecosystem standard

Via Irysarrow-up-right (built into Metaplex)

Understanding What You're Building

Let's start with why Solana NFTs work so differently from Ethereum.

The Account Model vs. Contract State

On Ethereum, you deploy a smart contract that stores all NFT ownership in its internal state. The contract is the source of truth. When you call ownerOf(tokenId), the contract looks up its mapping and returns the owner.

Solana flips this model. Instead of one contract holding everything, each NFT creates multiple accounts on the blockchain:

  1. Mint Account: The NFT's unique identifier (like a token address)

  2. Token Account: Holds the actual token, owned by a wallet

  3. Metadata Account: Stores name, symbol, URI, and creator info

  4. Master Edition Account: Proves this is a 1-of-1 NFT (not a fungible token)

These accounts are created by calling the Metaplex Token Metadata Program--a pre-deployed, audited program that every Solana NFT uses. You don't write the program. You call it with the right parameters.

Why Pre-Deployed Programs?

Imagine if every ERC-721 project on Ethereum used the exact same contract code, deployed once and shared by everyone. That's exactly how Solana works.

Benefits:

  • Instant compatibility: Wallets, marketplaces, and tools integrate once with Metaplex, not with thousands of individual contracts

  • Security through auditing: One codebase to audit, not thousands of variations

  • Lower costs: No contract deployment fees. You only pay for account creation

Trade-offs:

  • Less customization: You can't add arbitrary logic like Ethereum contracts

  • Standardized behavior: The program defines what's possible. Extensions require new programs

Metaplex Standards: Which One to Use?

Metaplex offers three NFT standards. Here's when to use each:

Standard
Best For
Cost per NFT
Key Feature

Core (Recommended)

New projects, modern apps

~0.0029 SOL

85% cheaper, plugin system

Token Metadata

Ecosystem compatibility

~0.016 SOL

Widest marketplace support

Bubblegum (cNFT)

Mass airdrops, gaming

~0.00001 SOL

Compressed, Merkle tree storage

For this guide, we'll use Metaplex Core, the newest standard and the recommended choice for all new projects. It's dramatically cheaper and includes a flexible plugin system for royalties, freezing, and custom behaviors.

Project Setup

We'll create a TypeScript project using Metaplex's Umi framework--the modern, type-safe way to interact with Solana programs.

1. Install the Solana CLI

First, install Solana's command-line tools. This gives you wallet management and devnet access.

macOS/Linux:


Windows:

Download and run the installer from Solana's releases pagearrow-up-right.

After installation, add Solana to your PATH and verify:


You should see something like solana-cli 2.x.x.

2. Configure Solana for Devnet

Set your CLI to use Solana's devnet (test network):


Verify your configuration:


You should see RPC URL: https://api.devnet.solana.com.

3. Create a Development Wallet

Generate a new keypair for development:


You'll be prompted to create a passphrase (optional for devnet). Save the seed phrase shown, though for devnet testing, it's not critical.

Set this wallet as your default:


Check your wallet address:


Save this address. It's your public key on Solana.

4. Fund Your Wallet with Test SOL

Airdrop free devnet SOL to your wallet:


Verify the balance:


You should see 2 SOL. If the airdrop fails (rate limits), try again in a minute or use the Solana Faucetarrow-up-right.

5. Initialize Your NFT Project

Create a new directory and initialize a TypeScript project:


Install the required Metaplex packages:


Install TypeScript and development dependencies:


Create a TypeScript configuration file:


Update tsconfig.json with these settings:


Create the source directory:


What each package provides:

  • @metaplex-foundation/mpl-core : The Core NFT standard programs and instructions

  • @metaplex-foundation/umi : Metaplex's framework for building Solana transactions

  • @metaplex-foundation/umi-bundle-defaults : Pre-configured Umi setup with standard plugins

  • @metaplex-foundation/umi-uploader-irys : Upload files to Arweave via Irys (formerly Bundlr)

  • @solana/web3.js : Low-level Solana JavaScript SDK

Creating Your First NFT

We'll create a single NFT to understand the core concepts, then expand to collections.

1. Setup Script Structure

Create src/createNft.ts:


Key concepts:

  • createUmi() : Initializes the Umi client connected to devnet

  • mplCore() : Adds Metaplex Core program support to Umi

  • generateSigner() : Creates a new keypair for your NFT's address

  • create() : The Core program instruction that creates an NFT

  • base58.deserialize() : Converts the signature to a readable string

  • fetchAssetV1() : Reads NFT data back from the blockchain

2. Understanding the Transaction

When you call create(), Metaplex builds a transaction that:

  1. Creates the asset account : A new account on Solana holding the NFT data

  2. Sets the owner: Your wallet becomes the NFT owner

  3. Stores on-chain data: Name and URI are written to the account

  4. Pays rent: Solana charges ~0.003 SOL for account storage

The uri field points to off-chain metadata (JSON file) containing the full description, image link, and attributes. We'll create this next.

3. Add Plugins for Extended Functionality

Metaplex Core uses a plugin system to add behaviors to your NFTs. You can add plugins during creation:


Plugin types available:

  • Royalties : Secondary sale fees enforced by marketplaces

  • PermanentFreezeDelegate : Freeze transfers permanently (useful for soulbound tokens)

  • FreezeDelegate : Allow an authority to freeze/unfreeze transfers

  • TransferDelegate : Allow another account to transfer the NFT

  • BurnDelegate : Allow another account to burn the NFT

  • Attributes : On-chain key-value attributes (for games, dynamic NFTs)

  • AppData : Store custom application data on-chain

Preparing NFT Metadata

Your NFT's visual identity--name, image, description, traits--lives in a JSON metadata file stored off-chain. Solana's account stores only a URI pointing to this file.

Understanding Metadata Structure

Metaplex follows a metadata standard compatible with marketplaces like Magic Eden and Tensor:


Field breakdown:

  • name : Display name for the NFT

  • symbol : Short identifier (like a ticker)

  • description : Full description shown on marketplaces

  • image : Primary image URL (typically Arweave on Solana)

  • attributes : Traits for filtering and rarity calculation

  • properties.files : All associated media files

  • properties.creators : Wallet addresses receiving royalties

Uploading to Arweave via Irys

Arweave is the standard storage layer for Solana NFTs. Unlike IPFS (common on Ethereum), where you need a pinning service with recurring monthly fees to keep files available, Arweave uses a pay-once model--a single upfront payment stores your files permanently. Metaplex has built-in Irys integration.

Why Arweave for Solana?

  • Ecosystem standard: Magic Eden, Tensor, and other marketplaces expect Arweave URIs

  • Permanent storage: Pay once, no monthly pinning fees (IPFS requires ongoing payments to pinning services)

  • Native Metaplex support: Built-in umi-uploader-irys package

  • Pay with SOL: No need for separate tokens or accounts

1. Create Your Asset Folders


2. Add Your Images

For this tutorial, we'll create a small 5-NFT collection. You'll need:

Images: Create or download 5 images (PNG or JPG format, ideally 1000x1000px or larger). Name them 1.png, 2.png, 3.png, 4.png, 5.png and place them in nft-assets/images/.

3. Upload to Arweave Programmatically

Create src/uploadAssets.ts:


Run the upload script:


The URIs are automatically saved to nft-assets/uploaded-uris.json for the next scripts to use.

4. Understanding Arweave URIs

After upload, your URIs look like:


These are permanent, immutable links served via Irys gateway. The data is stored on Arweave and can never change.

Alternative: Manual Upload via Irys Web

For quick testing without code, use the Irys web interfacearrow-up-right:

  1. Connect your Solana wallet

  2. Fund your account with SOL

  3. Upload files directly

  4. Copy the returned Arweave URIs

Creating an NFT Collection

Individual NFTs are useful, but most projects organize NFTs into collections. Metaplex Core has built-in collection support.

1. Create the Collection

Create src/createCollection.ts:


Collection metadata (collection.json) follows the same format as individual NFTs:


2. Mint NFTs into the Collection

Create src/mintToCollection.ts:


Key difference from standalone NFTs: The collection parameter links the NFT to your collection, enabling:

  • Collection-level filtering on marketplaces

  • Verified collection badges

  • Shared royalty settings (via collection-level plugins)

Writing Tests

Testing Solana programs differs from testing Ethereum contracts. You're not testing program logic--Metaplex handles that. You're testing that your transactions are built correctly and achieve the expected outcomes.

Unit Tests with Vitest

Install testing dependencies:


Add to package.json scripts:


Create src/tests/nft.test.ts:


Run tests:


Important notes about devnet testing:

  • Tests use commitment: "finalized" to ensure transactions are fully confirmed

  • The fetchAssetWithRetry helper handles RPC indexing delays (devnet can be slow)

  • Sleep delays between operations give the RPC time to index new accounts

  • Timeouts are set to 60-90 seconds to accommodate network latency

For faster, more reliable tests in production, use a local validator:


Then change the RPC URL to http://localhost:8899.

Running Your Scripts

Time to mint your collection.

1. Add Script Commands

Update package.json:


2. The Complete Workflow

Here's the correct order of operations:


Important: Each script saves its output to nft-assets/*.json files that subsequent scripts read automatically.

3. Upload Assets to Arweave

First, ensure your images are in nft-assets/images/ (named 1.png, 2.png, etc.), then:


This uploads:

  • All images to Arweave

  • NFT metadata for each image

  • Collection metadata

Output is saved to nft-assets/uploaded-uris.json.

4. Create Your Collection


The script reads collectionUri from the uploaded URIs file automatically. Output is saved to nft-assets/collection.json.

Note: You may see a warning about "RPC indexing delay"--this is normal on devnet. The collection was created successfully, but the fetch happened before the RPC node indexed the new account.

5. Mint NFTs to Collection


The script reads both the collection address and metadata URIs from the saved files. Each NFT is minted with 5% royalties.

Output is saved to nft-assets/minted-assets.json.

Viewing Your NFTs

On Solana Explorers

View your NFT on Solscan (devnet):


Or Solana Explorer:


The explorer shows:

  • Token name and symbol

  • Current owner

  • Metadata URI

  • Transaction history

In Phantom Wallet

  1. Open Phantom and ensure you're on Devnet (Settings → Developer Settings → Change Network)

  2. Navigate to the Collectibles tab

  3. Your NFTs should appear automatically

If they don't show immediately:

  • Click the refresh icon

  • Wait a few minutes for indexing

  • Verify the NFT owner matches your Phantom address

On Magic Eden (Devnet)

Magic Eden has limited devnet support, but you can check:


For mainnet NFTs, they appear automatically once indexed.

Troubleshooting: Common Issues

AccountNotFoundError after creating NFT/Collection


This is normal on devnet. The NFT/collection was created successfully, but the RPC node hasn't indexed it yet when the script tries to fetch details. The transaction succeeded--check the explorer link to verify.

Solution: Our scripts include a 2-second delay and try/catch handling. If you still see this, the asset was created--just wait and check the explorer.

"Run 'npm run upload' first" error

The scripts chain together. You must run them in order:

  1. npm run upload → Creates uploaded-uris.json

  2. npm run create-collection → Reads URIs, creates collection.json

  3. npm run mint → Reads both files, mints NFTs

Insufficient SOL

Upload and minting require SOL. For devnet:


If you hit rate limits, wait a minute or use the Solana Faucetarrow-up-right.

Wallet not found

The scripts look for ~/.config/solana/id.json by default. If your wallet is elsewhere:


Then update the walletPath in the scripts.

Transferring and Managing NFTs

Transfer an NFT

Create src/transfer.ts:


Burn an NFT

Create src/burn.ts:


Note: Burning returns the account rent to your wallet. After transaction fees, you'll receive approximately ~0.0015 SOL back.

Update NFT Metadata

Create src/update.ts:


Conclusion

You now have a working NFT collection on Solana. Here's what you built:

  • Solana dev environment: CLI, wallet, devnet SOL

  • Metaplex Core NFTs: the cheapest standard, with royalty plugins

  • Arweave metadata: permanent storage via Irys

  • Collection structure: organized NFTs with verified badges

  • Tests: verify operations before mainnet

  • Management scripts: transfers, burns, updates

Solana vs. Ethereum: What You've Learned

Aspect
Ethereum (ERC-721)
Solana (Metaplex)

Mint cost

$50-150+

~$0.01-0.02

Custom logic

Write Solidity contracts

Use existing programs

Data storage

Contract state

Separate accounts

Ecosystem integration

Varies by contract

Universal via Metaplex

Development time

Longer (contract dev)

Shorter (call programs)

What's Missing?

Production projects typically add:

  • Candy Machine: Metaplex's tool for large-scale mints with reveal mechanics, phases, and guard rails

  • Frontend dApp: A minting website using React/Next.js with wallet adapters

  • Compressed NFTs (cNFTs): For massive collections (100k+) at fractions of a cent per mint

  • On-chain attributes: Using the Attributes plugin for game items or evolving NFTs

  • Staking/Utility: Custom programs that interact with your NFTs

Next Steps

Build a minting dApp: Use @solana/wallet-adapter with React to create a frontend where users connect their wallets and mint NFTs.

Explore Candy Machine: For large collections with public sales, phases, and allowlists, Metaplex's Candy Machine handles the complexity.

Try compressed NFTs: For gaming or mass distribution, Bubblegum's cNFTs let you mint millions of NFTs for dollars, not thousands.

Study successful projects: Read the on-chain data of Mad Lads, Tensorians, or DeGods using Solscan. You'll recognize the Metaplex structures you just learned.

Deploy to mainnet: When ready, change your RPC URL to mainnet-beta and ensure your wallet has real SOL. The code is identical--just the network changes.

Last updated