Blockchain DevelopmentSolana10 min readUpdated

How to Create an SPL Token on Solana

By Mudassir Khan — Agentic AI Consultant & AI Systems Architect, Islamabad, Pakistan

Cover illustration for: How to Create an SPL Token on Solana

Section 01 · The model

What actually happens when you create a token on Solana?

Solana does not give every token its own contract. One program, the SPL Token Program, manages every fungible token and NFT on the network, and creating a token means asking that program to set up a new mint account on your behalf.

Quick answer

In one sentence: You create an SPL token on Solana by initializing a mint account through the SPL Token Program, either with the spl token CLI or the spl token library, then creating associated token accounts and minting supply into them.

If you have worked with Ethereum, this is the first mental shift. An ERC20 token is a deployed contract with its own address and its own copy of transfer logic. A Solana token is a row of state inside a shared program. The program address never changes. What changes is the data in the accounts you create.

Three account types matter here. The mint account stores the token's global properties: total supply, decimals, and the two authorities that control it. The token account holds a balance for one wallet. The associated token account, or ATA, is a token account whose address is derived deterministically from the owner's wallet and the mint, so wallets and programs never have to guess or store an extra mapping.

This design is why Solana token operations feel fast and cheap compared to deploying a new contract per asset. You are not shipping new code. You are writing to existing programs with well understood behavior, which is also why security audits for basic token creation are rarely the bottleneck compared to the custom logic layered on top.

Token Program versus Token 2022

Most of this guide uses the original SPL Token Program, sometimes called Tokenkeg after its program ID prefix. A newer standard, Token 2022, adds optional extensions like transfer fees and confidential transfers. Use the original program unless you specifically need one of those extensions, since tooling and wallet support are more mature there.

Section 02 · The CLI path

Creating a token with the spl token command line tool

The fastest way to understand the moving parts is to create a token by hand on devnet using the command line, before you ever touch application code.

Install the Solana CLI and the spl token CLI, then point your configuration at devnet so nothing here touches real funds.

bash
solana config set --url https://api.devnet.solana.com
solana-keygen new --outfile ~/.config/solana/id.json
solana airdrop 2

The airdrop gives your local wallet devnet SOL to pay for account rent and transaction fees. Mainnet has no equivalent, which is one reason to finish your entire token flow on devnet before you spend a cent of real SOL.

Creating the mint is one command.

bash
spl-token create-token --decimals 6

This prints a new mint address. Behind that single command, the CLI builds and sends a transaction that creates an account sized for mint data, assigns it to the Token Program, and initializes it with your wallet as both the mint authority and, unless you pass a flag to disable it, the freeze authority. Six decimals mirrors USDC and most utility tokens, giving you a million units per whole token, which is granular enough for pricing without overflowing common integer types.

Next, create an associated token account and mint some supply into it.

bash
spl-token create-account <MINT_ADDRESS>
spl-token mint <MINT_ADDRESS> 1000000

The create account step derives your ATA for that mint and initializes it. The mint step increases total supply and credits your ATA, and only your wallet can run it, because your wallet holds the mint authority. Check your balance with spl-token balance <MINT_ADDRESS> to confirm the mint worked.

Section 03 · The programmatic path

Creating a token from code with the spl token library

The CLI is fine for one off tokens, but any real product needs to create or manage tokens from inside an application, which means using the spl token library directly.

The library exposes helper functions that build the same instructions the CLI sends, but you compose them yourself, which matters once token creation is triggered by a user action rather than a terminal command.

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

const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
const payer = Keypair.generate();
const mintAuthority = payer;
const freezeAuthority = null;

const mint = await createMint(
  connection,
  payer,
  mintAuthority.publicKey,
  freezeAuthority,
  6
);

const tokenAccount = await getOrCreateAssociatedTokenAccount(
  connection,
  payer,
  mint,
  payer.publicKey
);

await mintTo(
  connection,
  payer,
  mint,
  tokenAccount.address,
  mintAuthority,
  1_000_000_000
);

createMint bundles the account creation and initialization into one call, and it needs a payer to cover rent, a mint authority public key, an optional freeze authority, and a decimals value. Passing null for the freeze authority is a deliberate choice: it permanently rules out freezing any holder's balance later, which is what most utility and governance tokens should do.

getOrCreateAssociatedTokenAccount is idiomatic because it checks whether the ATA already exists before trying to create it, which matters once you are minting to accounts you do not fully control, like a user's connected wallet. mintTo is the programmatic version of the CLI mint command, and note the amount is in the smallest unit, not whole tokens, so 1,000,000,000 with 6 decimals equals 1,000 whole tokens.

Section 04 · Authorities

How should you handle mint authority and freeze authority?

These two settings decide how much control you keep over a token after launch, and getting them wrong is the single most common mistake in Solana token projects.

Mint authority is the account allowed to create new supply. As long as it exists, holders and integrators cannot be certain the supply is fixed, no matter what your documentation says. Revoking it is irreversible and is the standard way to prove a hard cap.

bash
spl-token authorize <MINT_ADDRESS> mint --disable

Programmatically, this is setAuthority from the same library, called with AuthorityType.MintTokens and a null new authority. Do this once you are certain total supply is final, since there is no undo.

Freeze authority is different and more often unnecessary. It lets the holder revoke a specific account's ability to transfer, which is a real requirement for regulated assets like a stablecoin that needs to freeze a sanctioned wallet, but it is a liability for most other tokens because it means you can, in principle, lock any holder out of their own balance. The safe default for a general purpose or governance token is to pass null for freeze authority at creation and never revisit it.

SituationMint authorityFreeze authority
Fixed supply utility tokenRevoke after initial mintNever set (null)
Ongoing rewards or emissions tokenKeep, ideally behind a program or multisigNever set (null)
Regulated stablecoin style assetKeep behind a controlled processSet, with clear public policy
Test or devnet tokenLeave as isLeave as is

Section 05 · Associated token accounts

Why do you need an associated token account for every holder?

A mint only tracks total supply and metadata. Every wallet that holds the token needs its own account, and the associated token account standard makes finding that account deterministic instead of guesswork.

Without the ATA standard, a wallet or program that wanted to check a balance would need some separate registry mapping owners to token accounts, since a user could otherwise create multiple token accounts for the same mint. The ATA program derives one canonical address from the owner and the mint, so any client can compute where a balance should live without asking anyone.

This is why almost every transfer flow you will write starts with getOrCreateAssociatedTokenAccount for both sender and recipient. If the recipient has never touched your token before, their ATA does not exist yet, and someone, usually the sender or a relayer, has to pay the rent to create it. Budgeting for that extra cost is one of the more common gaps in a first Solana integration.

Section 06 · Devnet versus mainnet

What changes when you move from devnet to mainnet?

The instructions are identical. What changes is that mistakes now cost real money and, because supply and authority changes are often irreversible, real reputation.

On devnet, SOL is free through the faucet and rent is a rounding error. On mainnet, every account you create costs real SOL in rent, refundable only if you close the account, and every mint or authority change is a real transaction fee. Before you deploy to mainnet, run the entire flow end to end on devnet at least once with the exact decimals, exact authority settings, and exact initial supply you intend to ship, since changing decimals after the fact is not possible and changing authorities after revocation is not either.

Two more differences matter in practice. RPC rate limits are tighter on the public mainnet endpoint than on devnet, so any production application creating tokens or accounts on demand needs a dedicated RPC provider rather than the default public endpoint. And block explorers, wallets, and price aggregators pick up mainnet tokens automatically once they exist, which means a mistake in decimals or a forgotten freeze authority becomes visible to real users immediately rather than staying inside a test environment.

If any of this account and authority model feels unfamiliar, the earlier guide on Anchor accounts in Solana covers the same account ownership and initialization patterns from the program development side, which is the same foundation the Token Program itself is built on.

If you are about to wire this token creation flow into an actual product, the companion guide on integrating an SPL token with a Next.js application picks up exactly where this leaves off, including wallet connection, reading balances, and building a transfer UI.

FAQ

Frequently asked questions

How do I create an SPL token on Solana?

Create a mint account through the SPL Token Program using either the spl token command line tool, with a single create token command, or the spl token library's createMint function inside your application. Then create an associated token account for each holder and mint supply into it.

What is the difference between the spl token CLI and the spl token library?

The CLI is a command line tool best for testing, one off token creation, and quick devnet experiments. The spl token library is a TypeScript package you call from inside an application when token creation or management needs to happen as part of a product flow, such as a user triggered mint.

What are decimals in an SPL token and can I change them later?

Decimals set how divisible your token is, similar to cents in a dollar. Six is a common default matching USDC. Decimals are fixed permanently at mint creation and cannot be changed afterward, so choose carefully based on the smallest meaningful unit for your use case.

Why would I revoke mint authority on a token?

Revoking mint authority permanently removes the ability to create new supply, which is the standard way to prove to holders and integrators that a token has a fixed cap. It is a one way action, so only revoke it once your initial supply and distribution are final.

Do I need to set a freeze authority on my token?

Most tokens should not set a freeze authority, since it gives the authority holder the power to block any account from transferring. It is genuinely useful only for regulated assets like stablecoins that need to freeze sanctioned wallets under legal requirements.

Should I test my token on devnet before deploying to mainnet?

Yes. Devnet SOL is free and mistakes cost nothing, while mainnet requires real SOL for rent and fees and many settings, including decimals and revoked authorities, cannot be changed after the fact. Run your full creation and minting flow on devnet first.

If you are building a token that needs to plug into a product rather than sit in a wallet, the blockchain development service covers exactly this kind of Solana engineering, from token design through the application layer that surrounds it.

Written by Mudassir Khan

Agentic AI consultant and AI systems architect based in Islamabad, Pakistan. CEO of Cube A Cloud. 38+ agentic AI launches delivered for global founders and CTOs.

View Blockchain Development serviceSee ChainTrust blockchain compliance case study

Related service

Blockchain Development

See scope & pricing →

More on this topic

Need an AI systems architect?

Book a 30-minute architecture call. I will sketch the high-level design for your use case and give you an honest view of the trade-offs.

Book a strategy call →