SDK
JavaScript SDK
Last updated September 3, 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 rent and fees (~0.003 SOL per base asset; rent varies with asset size)
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')
Withdraw Asset Signer balances first
Burning the Asset makes execute fail. SOL, tokens, or other assets still held by the Asset Signer PDA become stranded.
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
- Empty the Asset Signer PDA before
burn()— remaining balances cannot be moved afterward
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) |
