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 guide, 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
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 Irys (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:
Mint Account: The NFT's unique identifier (like a token address)
Token Account: Holds the actual token, owned by a wallet
Metadata Account: Stores name, symbol, URI, and creator info
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:
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 page.
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 Faucet.
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 devnetmplCore(): Adds Metaplex Core program support to UmigenerateSigner(): Creates a new keypair for your NFT's addresscreate(): The Core program instruction that creates an NFTbase58.deserialize(): Converts the signature to a readable stringfetchAssetV1(): Reads NFT data back from the blockchain
2. Understanding the Transaction
When you call create(), Metaplex builds a transaction that:
Creates the asset account : A new account on Solana holding the NFT data
Sets the owner: Your wallet becomes the NFT owner
Stores on-chain data: Name and URI are written to the account
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 marketplacesPermanentFreezeDelegate: Freeze transfers permanently (useful for soulbound tokens)FreezeDelegate: Allow an authority to freeze/unfreeze transfersTransferDelegate: Allow another account to transfer the NFTBurnDelegate: Allow another account to burn the NFTAttributes: 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 NFTsymbol: Short identifier (like a ticker)description: Full description shown on marketplacesimage: Primary image URL (typically Arweave on Solana)attributes: Traits for filtering and rarity calculationproperties.files: All associated media filesproperties.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-iryspackagePay 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 interface:
Connect your Solana wallet
Fund your account with SOL
Upload files directly
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 confirmedThe
fetchAssetWithRetryhelper 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
Open Phantom and ensure you're on Devnet (Settings → Developer Settings → Change Network)
Navigate to the Collectibles tab
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:
npm run upload→ Createsuploaded-uris.jsonnpm run create-collection→ Reads URIs, createscollection.jsonnpm 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 Faucet.
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
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

