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

  1. Install dependencies: npm install @metaplex-foundation/mpl-core @metaplex-foundation/umi-bundle-defaults
  2. Create Umi instance with mplCore() plugin
  3. Generate or load a signer for transactions
  4. 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:

Terminal
npm install @metaplex-foundation/mpl-core @metaplex-foundation/umi-bundle-defaults

For metadata uploads, add an uploader plugin:

Terminal
npm install @metaplex-foundation/umi-uploader-irys

Umi Setup

Create and configure an Umi instance with the Core plugin:

setup-umi.ts
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

PluginType StringPurpose
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:

fetch-by-owner.ts
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)

fetch-by-collection.ts
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:

upload-metadata.ts
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:

send-confirm.ts
const result = await create(umi, { asset, name, uri }).sendAndConfirm(umi)
console.log('Signature:', result.signature)

Custom Confirmation Options

custom-confirm.ts
const result = await create(umi, { asset, name, uri }).sendAndConfirm(umi, {
confirm: { commitment: 'finalized' },
})

Build Transaction Without Sending

build-only.ts
const tx = create(umi, { asset, name, uri })
const builtTx = await tx.buildAndSign(umi)
// Send later with: await umi.rpc.sendTransaction(builtTx)

Combine Multiple Instructions

combine-instructions.ts
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 asset parameter in create() 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

package.json
{
"dependencies": {
"@metaplex-foundation/mpl-core": "^1.0.0",
"@metaplex-foundation/umi": "^0.9.0",
"@metaplex-foundation/umi-bundle-defaults": "^0.9.0"
}
}

Core Functions

FunctionPurpose
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

NetworkAddress
MainnetCoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d
DevnetCoREENxT6tW1HoK8ypY1SxRMZTcVPm7R94rH4PZNhX7d

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

TermDefinition
UmiMetaplex's framework for building Solana applications with wallet and RPC management
AssetA Core on-chain account representing an NFT with ownership, metadata, and plugins
CollectionA Core account that groups related Assets and can apply collection-wide plugins
SignerA keypair that can sign transactions (required for creating new accounts)
PluginA modular extension that adds behavior to Assets or Collections
URIThe off-chain metadata URL pointing to a JSON file with name, image, and attributes
DASDigital Asset Standard - API for querying indexed NFT data from RPC providers
Transaction BuilderAn immutable object that constructs transactions before sending
IdentityThe wallet/keypair configured as the transaction signer in Umi
CommitmentSolana confirmation level (processed, confirmed, finalized)
Previous
FAQ