SDK
JavaScript SDK
Last updated January 31, 2026
The Metaplex Core JavaScript SDK (@metaplex-foundation/mpl-core) provides a complete TypeScript/JavaScript interface for interacting with Core Assets and Collections on Solana. Built on the Umi framework, it offers type-safe methods for all Core operations.
What You'll Learn
This SDK reference covers:
- Setting up Umi with the Core plugin
- Creating, transferring, burning, and updating Assets
- Managing Collections and collection-level operations
- Adding, updating, and removing Plugins
- Fetching Assets and Collections with DAS
- Error handling and common patterns
Summary
The Core JavaScript SDK is the recommended way to interact with Metaplex Core from JavaScript/TypeScript applications. It wraps the Core program instructions in a type-safe API.
- Install:
npm install @metaplex-foundation/mpl-core @metaplex-foundation/umi - Requires Umi framework for wallet/RPC management
- All functions return transaction builders for flexible execution
- Supports both browser and Node.js environments
Out of Scope
Rust SDK usage (see Rust SDK), Token Metadata operations, Candy Machine integration, and low-level Solana transaction construction.
Quick Start
Jump to: Setup · Create · Transfer · Burn · Update · Collections · Plugins · Fetch · Errors · FAQ
- Install dependencies:
npm install @metaplex-foundation/mpl-core @metaplex-foundation/umi-bundle-defaults - Create Umi instance with
mplCore()plugin - Generate or load a signer for transactions
- Call SDK functions and confirm transactions
Prerequisites
- Node.js 18+ or modern browser with ES modules
- Umi framework configured with RPC and signer
- SOL for transaction fees (~0.003 SOL per asset)
API Reference
Full TypeDoc API documentation for the SDK.
NPM Package
Package on npmjs.com with version history.
Installation
Install the Core SDK and Umi framework:
npm install @metaplex-foundation/mpl-core @metaplex-foundation/umi-bundle-defaults
For metadata uploads, add an uploader plugin:
npm install @metaplex-foundation/umi-uploader-irys
Umi Setup
Create and configure an Umi instance with the Core plugin:
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
import { mplCore } from '@metaplex-foundation/mpl-core'
import { keypairIdentity } from '@metaplex-foundation/umi'
import { irysUploader } from '@metaplex-foundation/umi-uploader-irys'
// Create Umi with RPC endpoint
const umi = createUmi('https://api.devnet.solana.com')
.use(mplCore())
.use(keypairIdentity(yourKeypair))
.use(irysUploader()) // Optional: for metadata uploads
Assets
Create an Asset
Use create() to mint a new Core Asset:
1import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
2import { create } from '@metaplex-foundation/mpl-core'
3import { mplCore } from '@metaplex-foundation/mpl-core'
4
5// Initialize UMI
6const umi = createUmi('https://api.devnet.solana.com')
7 .use(mplCore())
8
9// Create a new NFT asset
10const asset = await create(umi, {
11 name: 'My NFT',
12 uri: 'https://example.com/metadata.json'
13}).sendAndConfirm(umi)
14
15console.log('Asset created:', asset.publicKey)
Transfer an Asset
Use transfer() to send an Asset to another wallet:
1import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
2import { transfer } from '@metaplex-foundation/mpl-core'
3import { mplCore } from '@metaplex-foundation/mpl-core'
4import { publicKey } from '@metaplex-foundation/umi'
5
6// Initialize UMI
7const umi = createUmi('https://api.devnet.solana.com')
8 .use(mplCore())
9
10// Transfer an existing NFT asset to a new owner
11const result = await transfer(umi, {
12 asset: publicKey('AssetAddressHere...'),
13 newOwner: publicKey('RecipientAddressHere...'),
14}).sendAndConfirm(umi)
15
16console.log('Asset transferred:', result.signature)
Burn an Asset
Use burn() to permanently destroy an Asset and reclaim rent:
1import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
2import { burn } from '@metaplex-foundation/mpl-core'
3import { mplCore } from '@metaplex-foundation/mpl-core'
4import { publicKey } from '@metaplex-foundation/umi'
5
6const umi = createUmi('https://api.devnet.solana.com').use(mplCore())
7const assetAddress = publicKey('AssetAddressHere...')
8
9// Permanently destroy/burn an NFT asset
10const result = await burn(umi, {
11 asset: assetAddress,
12}).sendAndConfirm(umi)
13
14console.log('Asset burned successfully')
Update an Asset
Use update() to modify Asset metadata:
1import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
2import { update } from '@metaplex-foundation/mpl-core'
3import { mplCore } from '@metaplex-foundation/mpl-core'
4import { publicKey } from '@metaplex-foundation/umi'
5
6const umi = createUmi('https://api.devnet.solana.com').use(mplCore())
7const assetAddress = publicKey('AssetAddressHere...')
8
9// Update an existing NFT asset's metadata
10const result = await update(umi, {
11 asset: assetAddress,
12 name: 'Updated NFT Name',
13 uri: 'https://updated-example.com/metadata.json',
14}).sendAndConfirm(umi)
15
16console.log('Asset updated successfully')
Collections
Create a Collection
Use createCollection() to create a Collection account:
1import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
2import { createCollection } from '@metaplex-foundation/mpl-core'
3import { mplCore } from '@metaplex-foundation/mpl-core'
4import { generateSigner } from '@metaplex-foundation/umi'
5
6// Initialize UMI
7const umi = createUmi('https://api.devnet.solana.com')
8 .use(mplCore())
9
10// Generate a new keypair for the collection
11const collectionSigner = generateSigner(umi)
12
13// Create a new Collection
14await createCollection(umi, {
15 collection: collectionSigner,
16 name: 'My Collection',
17 uri: 'https://example.com/collection.json',
18}).sendAndConfirm(umi)
19
20console.log('Collection created:', collectionSigner.publicKey)
Create Asset in Collection
Pass the collection parameter to create():
1import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
2import { create, fetchCollection } from '@metaplex-foundation/mpl-core'
3import { mplCore } from '@metaplex-foundation/mpl-core'
4import { generateSigner, publicKey } from '@metaplex-foundation/umi'
5
6// Initialize UMI
7const umi = createUmi('https://api.devnet.solana.com')
8 .use(mplCore())
9
10const collectionAddress = publicKey('YOUR_COLLECTION_ADDRESS')
11
12// Fetch the existing collection
13const collection = await fetchCollection(umi, collectionAddress)
14
15// Generate a new keypair for the asset
16const assetSigner = generateSigner(umi)
17
18// Create asset in the collection
19await create(umi, {
20 asset: assetSigner,
21 collection,
22 name: 'Collection Item #1',
23 uri: 'https://example.com/item1.json',
24}).sendAndConfirm(umi)
25
26console.log('Asset created in collection:', assetSigner.publicKey)
Plugins
Plugins add behavior to Assets and Collections. They can be added at creation time or afterwards.
Add Plugin at Creation
1import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
2import { create, ruleSet } from '@metaplex-foundation/mpl-core'
3import { mplCore } from '@metaplex-foundation/mpl-core'
4import { generateSigner, publicKey } from '@metaplex-foundation/umi'
5
6// Initialize UMI
7const umi = createUmi('https://api.devnet.solana.com')
8 .use(mplCore())
9
10const creator = publicKey('YOUR_CREATOR_ADDRESS')
11
12// Generate a new keypair for the asset
13const assetSigner = generateSigner(umi)
14
15// Create asset with Royalties plugin
16await create(umi, {
17 asset: assetSigner,
18 name: 'NFT with Royalties',
19 uri: 'https://example.com/metadata.json',
20 plugins: [
21 {
22 type: 'Royalties',
23 basisPoints: 500, // 5%
24 creators: [
25 { address: creator, percentage: 100 },
26 ],
27 ruleSet: ruleSet('None'),
28 },
29 ],
30}).sendAndConfirm(umi)
31
32console.log('Asset created with plugins:', assetSigner.publicKey)
Add Plugin to Existing Asset
1import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'
2import { addPlugin, fetchAsset, ruleSet } from '@metaplex-foundation/mpl-core'
3import { mplCore } from '@metaplex-foundation/mpl-core'
4import { publicKey } from '@metaplex-foundation/umi'
5
6// Initialize UMI
7const umi = createUmi('https://api.devnet.solana.com')
8 .use(mplCore())
9
10const assetAddress = publicKey('YOUR_ASSET_ADDRESS')
11
12// Fetch the existing asset
13const asset = await fetchAsset(umi, assetAddress)
14
15// Add a Royalties plugin to the asset
16await addPlugin(umi, {
17 asset,
18 plugin: {
19 type: 'Royalties',
20 basisPoints: 500, // 5%
21 creators: [
22 { address: umi.identity.publicKey, percentage: 100 },
23 ],
24 ruleSet: ruleSet('None'),
25 },
26}).sendAndConfirm(umi)
27
28console.log('Plugin added to asset:', assetAddress)
Common Plugin Types
| Plugin | Type String | Purpose |
|---|---|---|
| Royalties | 'Royalties' | Creator royalty enforcement |
| Freeze Delegate | 'FreezeDelegate' | Allow freezing/unfreezing |
| Burn Delegate | 'BurnDelegate' | Allow burning by delegate |
| Transfer Delegate | 'TransferDelegate' | Allow transfers by delegate |
| Update Delegate | 'UpdateDelegate' | Allow metadata updates |
| Attributes | 'Attributes' | On-chain key/value data |
| Permanent Freeze | 'PermanentFreezeDelegate' | Permanent freeze state |
| Permanent Transfer | 'PermanentTransferDelegate' | Permanent transfer delegate |
| Permanent Burn | 'PermanentBurnDelegate' | Permanent burn delegate |
| See Plugins Overview for detailed plugin documentation. |
Fetching Assets
Fetch Single Asset
1import { fetchAsset, fetchCollection, mplCore } from '@metaplex-foundation/mpl-core';
2import { publicKey } from '@metaplex-foundation/umi';
3import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
4
5// Initialize UMI
6const umi = createUmi('https://api.devnet.solana.com')
7 .use(mplCore())
8
9// Fetch a Core Asset
10const assetAddress = publicKey('AssetAddressHere...')
11const asset = await fetchAsset(umi, assetAddress)
12
13// Fetch a Core Collection
14const collectionAddress = publicKey('CollectionAddressHere...')
15const collection = await fetchCollection(umi, collectionAddress)
16
17console.log('Asset fetched:', asset)
18console.log('Name:', asset.name)
19console.log('Owner:', asset.owner)
20console.log('URI:', asset.uri)
21
22console.log('\nCollection fetched:', collection)
23console.log('Name:', collection.name)
24console.log('URI:', collection.uri)
Fetch Assets by Owner (DAS)
Use the DAS API to query indexed assets:
import { publicKey } from '@metaplex-foundation/umi'
import { dasApi } from '@metaplex-foundation/digital-asset-standard-api'
// Add DAS plugin to Umi
const umi = createUmi('https://api.devnet.solana.com')
.use(mplCore())
.use(dasApi())
const owner = publicKey('OwnerAddressHere...')
const assets = await umi.rpc.getAssetsByOwner({
owner,
limit: 100,
})
console.log('Assets owned:', assets.items.length)
Fetch Assets by Collection (DAS)
import { publicKey } from '@metaplex-foundation/umi'
const collectionAddress = publicKey('CollectionAddressHere...')
const assets = await umi.rpc.getAssetsByGroup({
groupKey: 'collection',
groupValue: collectionAddress,
limit: 100,
})
console.log('Collection assets:', assets.items.length)
Uploading Metadata
Use Umi's uploader plugins to store metadata JSON:
import { irysUploader } from '@metaplex-foundation/umi-uploader-irys'
const umi = createUmi('https://api.devnet.solana.com')
.use(mplCore())
.use(keypairIdentity(yourKeypair))
.use(irysUploader())
// Upload image first
const imageFile = await fs.promises.readFile('image.png')
const [imageUri] = await umi.uploader.upload([imageFile])
// Upload metadata JSON
const uri = await umi.uploader.uploadJson({
name: 'My NFT',
description: 'An awesome NFT',
image: imageUri,
attributes: [
{ trait_type: 'Background', value: 'Blue' },
{ trait_type: 'Rarity', value: 'Rare' },
],
})
console.log('Metadata URI:', uri)
Transaction Patterns
Send and Confirm
The standard pattern waits for confirmation:
const result = await create(umi, { asset, name, uri }).sendAndConfirm(umi)
console.log('Signature:', result.signature)
Custom Confirmation Options
const result = await create(umi, { asset, name, uri }).sendAndConfirm(umi, {
confirm: { commitment: 'finalized' },
})
Build Transaction Without Sending
const tx = create(umi, { asset, name, uri })
const builtTx = await tx.buildAndSign(umi)
// Send later with: await umi.rpc.sendTransaction(builtTx)
Combine Multiple Instructions
import { transactionBuilder } from '@metaplex-foundation/umi'
const tx = transactionBuilder()
.add(create(umi, { asset: asset1, name: 'NFT 1', uri: uri1 }))
.add(create(umi, { asset: asset2, name: 'NFT 2', uri: uri2 }))
await tx.sendAndConfirm(umi)
Common Errors
Account does not exist
The asset or collection address doesn't exist. Verify the address is correct:
const asset = await fetchAsset(umi, assetAddress).catch(() => null)
if (!asset) {
console.log('Asset not found')
}
Invalid authority
You're not authorized to perform this action. Check that:
- You own the asset (for transfers, burns)
- You're the update authority (for updates)
- You have the required delegate permission
Insufficient funds
Your wallet needs more SOL. Fund it with:
solana airdrop 1 <WALLET_ADDRESS> --url devnet
Asset already exists
The asset keypair was already used. Generate a new signer:
const assetSigner = generateSigner(umi) // Must be unique
Plugin not found
The plugin doesn't exist on this asset. Check installed plugins:
const asset = await fetchAsset(umi, assetAddress)
console.log('Plugins:', Object.keys(asset))
Notes
- Always use a new keypair for new assets - never reuse keypairs
- The
assetparameter increate()must be a signer, not just a public key - Collection-level plugins override asset-level plugins of the same type
- Use
commitment: 'finalized'when creating assets that you immediately fetch - Transaction builders are immutable - each method returns a new builder
Quick Reference
Minimum Dependencies
{
"dependencies": {
"@metaplex-foundation/mpl-core": "^1.0.0",
"@metaplex-foundation/umi": "^0.9.0",
"@metaplex-foundation/umi-bundle-defaults": "^0.9.0"
}
}
Core Functions
| Function | Purpose |
|---|---|
create() | Create a new Asset |
createCollection() | Create a new Collection |
transfer() | Transfer Asset ownership |
burn() | Destroy an Asset |
update() | Update Asset metadata |
updateCollection() | Update Collection metadata |
addPlugin() | Add plugin to Asset |
addCollectionPlugin() | Add plugin to Collection |
updatePlugin() | Update existing plugin |
removePlugin() | Remove plugin from Asset |
fetchAsset() | Fetch Asset by address |
fetchCollection() | Fetch Collection by address |
Program ID
| Network | Address |
|---|---|
| Mainnet | CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d |
| Devnet | CoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d |
FAQ
What is the Core JavaScript SDK?
The Core JavaScript SDK (@metaplex-foundation/mpl-core) is a TypeScript library for interacting with Metaplex Core NFTs on Solana. It provides type-safe functions for creating, transferring, burning, and managing Assets and Collections.
Do I need Umi to use this SDK?
Yes. The Core SDK is built on the Umi framework, which handles wallet connections, RPC communication, and transaction building. Install both @metaplex-foundation/mpl-core and @metaplex-foundation/umi-bundle-defaults.
How do I connect a browser wallet?
Use the @metaplex-foundation/umi-signer-wallet-adapters package with your wallet adapter:
import { walletAdapterIdentity } from '@metaplex-foundation/umi-signer-wallet-adapters'
umi.use(walletAdapterIdentity(wallet))
What's the difference between sendAndConfirm and send?
sendAndConfirm() waits for transaction confirmation before returning. send() returns immediately after broadcasting. Use sendAndConfirm() for most cases to ensure your transaction succeeded.
How do I batch multiple operations?
Use transactionBuilder() to combine instructions, but be aware of Solana's transaction size limits (~1232 bytes). For large batches, send multiple transactions.
Can I use this SDK in React/Next.js?
Yes. The SDK works in both browser and Node.js environments. For React, use wallet adapters from @solana/wallet-adapter-react with Umi's wallet adapter identity.
How do I handle errors?
Wrap SDK calls in try/catch blocks. The SDK throws typed errors that include program error codes:
try {
await transfer(umi, { asset, newOwner }).sendAndConfirm(umi)
} catch (error) {
console.error('Transfer failed:', error.message)
}
Where can I find the full API documentation?
See the TypeDoc API Reference for complete function signatures and types.
Glossary
| Term | Definition |
|---|---|
| Umi | Metaplex's framework for building Solana applications with wallet and RPC management |
| Asset | A Core on-chain account representing an NFT with ownership, metadata, and plugins |
| Collection | A Core account that groups related Assets and can apply collection-wide plugins |
| Signer | A keypair that can sign transactions (required for creating new accounts) |
| Plugin | A modular extension that adds behavior to Assets or Collections |
| URI | The off-chain metadata URL pointing to a JSON file with name, image, and attributes |
| DAS | Digital Asset Standard - API for querying indexed NFT data from RPC providers |
| Transaction Builder | An immutable object that constructs transactions before sending |
| Identity | The wallet/keypair configured as the transaction signer in Umi |
| Commitment | Solana confirmation level (processed, confirmed, finalized) |
