DEXArea
DEXArea
solana

How to Create and Mint a Mintable SPL Token on Solana (CLI)

A practical guide to creating a mintable SPL token: CLI quick start, common decimals pitfalls, verification steps, plus a runnable TypeScript example and authority controls.

December 16, 2025
How to Create and Mint a Mintable SPL Token on Solana (CLI)

How to Create and Mint a Mintable SPL Token on Solana (CLI)

A "mintable" SPL token is just a normal fungible token whose Mint Authority is still active — meaning new supply can be minted later (for emissions, rewards, vesting unlocks, etc.). Solana makes this powerful… and dangerously easy to mess up if you don't understand the account model. If you prefer a no-code approach, you can use our Solana Token Creator tool.

This guide covers:

  • The mental model (Mint Account vs Token Account / ATA)
  • Method 1: CLI (spl-token) end-to-end
  • Method 2: TypeScript / SDK (and how Anchor usually does it)
  • How to mint tokens after creation, transfer/burn, and revoke mint authority (fixed supply)

Introduction: What are mintable SPL tokens?

SPL tokens are Solana's standard for fungible tokens. On Solana, tokens are represented by on-chain accounts controlled by a token program (there are two main token programs: the original Token Program and Token-2022 / Token Extensions).

Mintable means: you didn't permanently disable minting. The token's Mint Authority can sign a mint_to instruction later and increase total supply.

Fixed supply means: you revoke Mint Authority after minting the final supply (no one can ever mint again).

Tested & Verified

Last verified: December 16, 2025
Solana CLI version: 3.0.13
spl-token CLI version: 5.4.0
Network tested: Devnet
Note: Commands may differ slightly by version. If your CLI version differs, run spl-token --help or spl-token initialize-metadata --help to see available flags for your version.
Solana CLI version check showing solana-cli 3.0.13 and spl-token-cli 5.4.0 commands

Quick Start: Create + Mint in 5 Minutes (CLI)

If you just need to get a token created quickly, here's the minimal flow:

  1. Set Devnet and fund wallet:

    solana config set --url https://api.devnet.solana.com
    solana airdrop 2
    
  2. Create mint (9 decimals):

    spl-token create-token --decimals 9
    # Save the mint address printed (e.g., ABC123...)
    
  3. Create token account (ATA):

    spl-token create-account <MINT_ADDRESS>
    
  4. Mint 100 tokens (base units!):

    # With 9 decimals: 100 tokens = 100 * 10^9 = 100000000000 base units
    spl-token mint <MINT_ADDRESS> 100000000000
    
  5. Verify:

    spl-token balance <MINT_ADDRESS>
    spl-token supply <MINT_ADDRESS>
    

For detailed explanations, decimals handling, Token-2022 options, and programmatic approaches, see the full sections below.


Section 1: Core concepts & prerequisites

The Solana token model (why EVM devs get whiplash)

Solana splits "code" and "state": your token logic lives in the Token Program, while your token data lives in accounts owned by that program.

Mint Account (global token state)

A Mint Account represents the token itself and stores global properties like supply, decimals, and authorities.

Example mental model: USDC is a mint; your wallet does not "hold USDC" directly — it owns a token account that holds a balance for the USDC mint.

Token Account + ATA (your balance lives here)

A Token Account holds a specific owner's balance for a specific mint. An Associated Token Account (ATA) is the standard deterministic token account address most wallets use.

This is the classic "cultural shock": one user + one mint = one token account (ATA). That design helps parallel execution and performance.

Mint Authority (the "god key" for supply)

The Mint Authority is the signer (wallet, multisig, or program/PDA) allowed to mint more tokens. Many projects mint initial supply, then revoke mint authority for trust.

Decimals (divisibility — and you can't change it later)

Decimals are Immutable

Choose decimals carefully (commonly 6 or 9). After the mint is created, decimals are effectively immutable — if you mess it up, you usually need a new mint.

What you need before starting

  • A Solana wallet with SOL for fees and rent-exempt accounts (Devnet SOL via airdrop; Mainnet SOL is real money).
  • solana CLI + spl-token CLI installed.
  • A target cluster: Devnet first, always.

Section 2: Method 1 — Create a mintable token via CLI (spl-token)

Below commands are shown for Devnet. Always test Devnet before Mainnet.

1) Point your CLI to Devnet and check your wallet

solana config set --url https://api.devnet.solana.com
solana address
solana balance

Fund on Devnet:

solana airdrop 2

2) Create the Mint (choose decimals)

Create a standard SPL mint
Token Program
:
spl-token create-token --decimals 9

The CLI will print the new mint address. Save it — you'll need it for subsequent steps.

Optional: create under Token-2022 (Token Extensions)
Token-2022

Token-2022 program id: TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb

You can target it like:

spl-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb create-token --decimals 9

Token-2022 is the path if you want native "extensions" (including modern metadata patterns).

3) Create your token account (ATA) to hold the balance

spl-token create-account <MINT_ADDRESS>

This creates an ATA by default.

4) Initialize metadata (name, symbol, URI)

Wallets display tokens better when metadata is present.

Important: Token-2022 supports storing metadata via token extensions / metadata interface patterns, but the mint must be created under the Token-2022 program (see step 2 above). Classic Token Program mints use external metadata (Metaplex, etc.).

For Token-2022 mints:

If you created your mint under Token-2022, you can initialize metadata using the initialize-metadata command:
spl-token initialize-metadata --program-2022 <MINT_ADDRESS> "My Token" "MTK" https://example.com/metadata.json
The --program-2022 flag tells the CLI to use the Token-2022 program. You can also use -p TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb instead.

Optional flags:

  • --update-authority <ADDRESS> - Set the update authority (defaults to your keypair)
  • --mint-authority <KEYPAIR> - Specify mint authority if different from fee payer

For Classic Token Program mints:

Classic Token Program mints don't support native metadata extensions. Use external metadata solutions like Metaplex, or create a Token-2022 mint instead. You can also use our Update Metadata tool to manage token metadata.

Check available flags:

To see all options for your version:

spl-token initialize-metadata --help

Option B: Programmatic metadata (TypeScript)

For Token-2022 mints, you can initialize metadata programmatically using @solana/spl-token helpers. See the TypeScript section below for a complete example.

Verification step:

After initializing metadata, verify it exists:

  1. Via CLI:

    spl-token account-info <MINT_ADDRESS>
    
  2. Via explorer:

    • Visit https://solscan.io/token/<MINT_ADDRESS>?cluster=devnet (replace <MINT_ADDRESS> with your mint)
    • Or use Solana Explorer: https://explorer.solana.com/address/<MINT_ADDRESS>?cluster=devnet
    • Check that name, symbol, and URI appear correctly

5) Verify mint authority

You can inspect mint info:

spl-token account-info <MINT_ADDRESS>
# or
spl-token supply <MINT_ADDRESS>

6) Mint tokens (the decimals trap)

The Decimals Trap

Minting uses base units. If decimals = 9:

  • 1 token = 1,000,000,000 base units
So if you "mint 100 tokens", many tools require passing 100 * 10^9. This is the #1 reason people mint and see a weird tiny balance.

CLI:

spl-token mint <MINT_ADDRESS> <AMOUNT_IN_BASE_UNITS>

Example: To mint 100 tokens with 9 decimals:

spl-token mint <MINT_ADDRESS> 100000000000

Check balance:

spl-token balance <MINT_ADDRESS>

Verify It Worked

After creating and minting via CLI, verify:

  • ✅ Cluster is correct (solana config get)
  • ✅ Mint address exists (spl-token account-info <MINT_ADDRESS>)
  • ✅ Token program ID matches (Token Program or Token-2022)
  • ✅ Mint authority is set (check account-info output)
  • ✅ ATA exists (spl-token accounts)
  • ✅ Supply increased (spl-token supply <MINT_ADDRESS>)
  • ✅ Balance shows correctly (spl-token balance <MINT_ADDRESS>)

Section 3: Method 2 — Create a mintable token programmatically (TypeScript / SDK)
TypeScript

What actually happens on-chain (two instructions)

Creating a mint account requires:

  1. System Program: create the account + allocate space + fund rent
  2. Token Program: initialize mint (decimals + authorities)

TypeScript example (fully runnable on Devnet)

Below is a complete, runnable example: create mint → create ATA → mint to ATA.

Prerequisites:

  • Node.js installed
  • npm install @solana/web3.js @solana/spl-token
  • Devnet SOL (via airdrop in the script)

Complete script:

import {
  Connection,
  Keypair,
  clusterApiUrl,
  LAMPORTS_PER_SOL,
} from "@solana/web3.js";
import {
  createMint,
  getOrCreateAssociatedTokenAccount,
  mintTo,
  TOKEN_PROGRAM_ID,
} from "@solana/spl-token";

async function main() {
  try {
    // 1) Connect to Devnet
    const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
    console.log("Connected to Devnet");

    // 2) Generate keypair (or load from file for production)
    const payer = Keypair.generate();
    console.log("Payer address:", payer.publicKey.toBase58());

    // 3) Request airdrop for Devnet SOL
    console.log("Requesting airdrop...");
    const airdropSignature = await connection.requestAirdrop(
      payer.publicKey,
      2 * LAMPORTS_PER_SOL
    );
    await connection.confirmTransaction(airdropSignature, "confirmed");
    console.log("Airdrop confirmed");

    // 4) Set mint authority (same as payer for simplicity)
    const mintAuthority = payer;
    const decimals = 9;

    // 5) Create the mint (mintable because mintAuthority exists)
    console.log("Creating mint...");
    const mint = await createMint(
      connection,
      payer,
      mintAuthority.publicKey,
      null, // freeze authority optional
      decimals,
      undefined, // keypair (auto-generated)
      undefined, // confirmOptions
      TOKEN_PROGRAM_ID // Use Token-2022 program ID here if needed
    );
    console.log("Mint created:", mint.toBase58());

    // 6) Create recipient ATA (here: payer's ATA)
    console.log("Creating ATA...");
    const ata = await getOrCreateAssociatedTokenAccount(
      connection,
      payer,
      mint,
      payer.publicKey
    );
    console.log("ATA address:", ata.address.toBase58());

    // 7) Mint tokens to ATA (base units!)
    const uiAmount = 100;
    const baseUnits = BigInt(uiAmount) * 10n ** BigInt(decimals);
    console.log(`Minting ${uiAmount} tokens (${baseUnits} base units)...`);

    await mintTo(
      connection,
      payer,
      mint,
      ata.address,
      mintAuthority,
      baseUnits
    );
    console.log("Minting confirmed");

    // 8) Verify
    const supply = await connection.getTokenSupply(mint);
    console.log("Token supply:", supply.value.uiAmount, supply.value.uiAmountString);

    console.log("\n✅ Success!");
    console.log("Mint:", mint.toBase58());
    console.log("ATA:", ata.address.toBase58());
    console.log("Mint Authority:", mintAuthority.publicKey.toBase58());
  } catch (error) {
    console.error("Error:", error);
    process.exit(1);
  }
}

main();

To run:

  1. Save as create-token.ts
  2. Run: npx ts-node create-token.ts (or compile with tsc and run with node)

For production:

  • Replace Keypair.generate() with secure keypair loading (wallet adapter, file-based keypair with proper permissions, etc.)
  • Use mainnet connection and real SOL
  • Add proper error handling and retries
  • Consider using a multisig or governance program for mint authority

Verify It Worked

After running the TypeScript script, verify:

  • ✅ Cluster is Devnet (check connection URL)
  • ✅ Mint address was printed and exists on-chain
  • ✅ Token program ID matches (TOKEN_PROGRAM_ID or TOKEN_2022_PROGRAM_ID)
  • ✅ Mint authority matches your payer keypair
  • ✅ ATA address was created
  • ✅ Supply shows the correct amount (100 tokens in the example)
  • ✅ Check on explorer: https://solscan.io/token/<MINT_ADDRESS>?cluster=devnet

Solana Kit style (getCreateAccountInstruction / getInitializeMintInstruction)

Some newer tooling uses helpers like getCreateAccountInstruction and getInitializeMintInstruction to assemble the same two-instruction flow. This gives more control over transaction construction.

Anchor / Rust mental model

Anchor typically abstracts mint creation with init and sets authority either to:
  • a user wallet (EOA) or
  • a PDA (program-controlled minting, common for emissions)
Minting uses the SPL Token mint_to instruction and requires the mint authority signer (wallet or PDA via CPI).

Section 4: Executing mint operations (post-creation)

1) Ensure the recipient has an ATA

Before minting to someone else, they need a token account for that mint. You can create it for yourself:

spl-token create-account <MINT_ADDRESS>
(Or you can fund the recipient's ATA creation during transfers with --fund-recipient in some flows.)

2) Mint to a destination

spl-token mint <MINT_ADDRESS> <AMOUNT_IN_BASE_UNITS> <RECIPIENT_TOKEN_ACCOUNT>

(If you omit destination, CLI often mints to your default token account.)

3) Transfer tokens (and optionally fund recipient ATA)

spl-token transfer <MINT_ADDRESS> <AMOUNT_IN_BASE_UNITS> <RECIPIENT_WALLET> --fund-recipient
--fund-recipient creates the recipient ATA if missing (sender pays).

4) Burn tokens (reduce supply)

spl-token burn <TOKEN_ACCOUNT> <AMOUNT_IN_BASE_UNITS>
You can also use our Burn Tokens tool for a no-code burning experience.

5) Authority management: transfer or revoke mint authority

Transfer mint authority (e.g., to a multisig or governance program) is often safer than keeping it on a hot wallet. Conceptually, Solana's "Set Authority" is how this works.

Revoke mint authority (make fixed supply):

spl-token authorize --authority <CURRENT_AUTHORITY_KEYPAIR> mint <MINT_ADDRESS> --disable
You can also use our Revoke Mint Authority tool to disable minting without CLI.
This pattern is widely used; if you're not signing with the correct current authority you'll hit OwnerMismatch.

Conclusion: mintable tokens are flexible — but trust is earned

Mintable supply enables emissions, rewards, and staged growth. But it also introduces trust questions: Who holds the mint authority? Is minting transparent? Will you revoke it later?
Good ops = clear tokenomics + predictable authority management. Use our Token Creator for easy token creation, Mint Tokens for supply management, and Revoke Mint when you're ready to lock supply.

Alternative: No-code option

If you prefer a UI-based approach without writing CLI commands or code, you can use no-code tools. However, understanding the underlying concepts (decimals, mint authority, ATAs) remains important regardless of the tool you choose.

What no-code tools provide:

  • Visual interface for token creation
  • Metadata configuration forms
  • Authority management UI
  • Minting interface

What you still need to understand:

  • Decimals and base units (for minting amounts)
  • Mint authority (who can mint, when to revoke)
  • Token program choice (Token Program vs Token-2022)
  • Security best practices

No-code tools are non-custodial (your wallet signs transactions), so the on-chain behavior and authority rules are identical to CLI/SDK methods.

No-Code Tools

FAQs


Troubleshooting: Common Issues

Authority mismatch errors

OwnerMismatch Error

If you see OwnerMismatch or similar authority errors:
  • Verify you're signing with the correct mint authority keypair
  • Check that the mint authority hasn't been revoked already
  • Ensure you're using the correct program ID (Token Program vs Token-2022)

Wrong cluster / network

Network Mismatch

Common mistake: testing on Devnet but deploying to Mainnet (or vice versa). Always verify:

solana config get

Missing ATA (Associated Token Account)

ATA Required

Before minting or transferring to a recipient, ensure their ATA exists:

spl-token accounts --owner <RECIPIENT_ADDRESS>

If missing, create it:

spl-token create-account <MINT_ADDRESS> --owner <RECIPIENT_ADDRESS>

Decimals confusion

Base Units Conversion

Remember: minting uses base units. If decimals = 9:

  • 1 token = 1,000,000,000 base units
  • 100 tokens = 100,000,000,000 base units
Always multiply UI amounts by 10^decimals when minting programmatically.

Insufficient SOL for rent

Rent-Exempt SOL Required

Token accounts and mint accounts require rent-exempt SOL. If creation fails:

  • Check your SOL balance: solana balance
  • Airdrop more SOL on Devnet: solana airdrop 2
  • On Mainnet, ensure you have sufficient SOL for fees and rent

References

DEXArea Knowledge Team - Blockchain documentation experts
DEXArea Knowledge TeamOur team has hands-on experience building Solana tooling, Web3 infrastructure, and DeFi applications. We create accurate, structured documentation based on official sources and real-world testing. Trusted by thousands of token creators since 2024. Learn more about our expertise
Last updated: Dec 16, 2025

Related Posts

View all