How to create a Solana token with the Solana Program Library and JavaScript

In this guide, we are going to learn how to create your own token on the Solana blockchain using the Solana Program Library (SPL) and JavaScript.

In this guide, we are going to learn how to create your own token on the Solana blockchain using the Solana Program Library (SPL) and JavaScript.

As opposed to the Ethereum blockchain, you don't need to code your own smart contract (called custom programs in Solana) to create a token on Solana.

To create a token, or a non-fungible token (NFT), you can use the Solana Program Library which is a library that the Solana team built that defines the implementations for you.

To create a token using SPL, you can either use the CLI or the JavaScript library they provide. I'm going to cover the JavaScript method here.

If you prefer to use the CLI, check out this guide:

How to create a Solana token with the Solana Program Library CLI
In this guide, we are going to learn how to create your own token on the Solana blockchain using the Solana Program Library (SPL) and the CLI.

How to install the Solana Program Library in JavaScript

To install the SPL-token library you can either use yarn or npm:

With NPM:

npm install @solana/spl-token

With Yarn:

yarn add @solana/spl-token

You will also need the Solana Web3.js library to do everything in this tutorial. To install it, run this command:

npm install @solana/web3.js

Note that you can also install it with yarn.

Creating a token on Solana using the Solana Program Library (SPL) in JavaScript

Before any code example, I imported the Solana Web3 JS library that way:

const web3 = require('@solana/web3.js');

Environments

You can switch from the dev environment (meaning your commands will be run on Solana Devnet) to the mainnet (the real Solana network). On the devnet, it's not real money, it's just for development and the mainnet is where there is the real money and SOL tokens.

Basically like dev and production environments.

Before using the SPL-token library, you need to create a new connection:

const connection = new web3.Connection(web3.clusterApiUrl('devnet'), 'confirmed');

You can either pass "devnet" to use the devnet or "mainnet-beta" for the mainnet.

Creating a wallet

First, we need a wallet to send the transactions from. This wallet should have some SOL to pay for gas fees (1 SOL will be more than enough).

This wallet is going to be the owner of the token's smart contract.

To create a new wallet, you can use the Keypair object:

const wallet = solanaWeb3.Keypair.generate();

Now, to see your public and private key, you'll need additional steps:

First, install the bs58 library by running:

// with npm
npm install bs58

// OR

// with yarn
yarn add bs58

Then you can get the public key (often called the address as well) and the private key:

const bs58 = require('bs58');

const pubKey = wallet.publicKey.toBase58();
const privateKey = bs58.encode(wallet.secretKey);

You can print those values to always have them and store them somewhere so you don't loose your wallet.

It's very important you store that private key in a secure place so you can recover your wallet in a browser wallet like Phantom. Never share that to anyone otherwise they can send transactions on your behalf.

Fund your new wallet

Now, you need to fund your wallet and add Solana tokens to your wallet to pay for gas fees.

If you're on the mainnet, you'll have to buy SOL from an exchange and transfer it to the address you just generated (pubkey).

If you're on the devnet, you can airdrop SOL to your wallet (since it's not real money) using the following code:

const airdropSignature = await connection.requestAirdrop(
  wallet.publicKey,
  web3.LAMPORTS_PER_SOL,
);

await connection.confirmTransaction(airdropSignature);

In the code above, LAMPORTS_PER_SOL equals 1 SOL. Lamports are the sub-unit of Solana that is used in the code when interacting with blockchains to quantify token amounts.

If you have some knowledge of the Ethereum blockchain, it's like the Wei in Ethereum.

So the code above will send 1 SOL on the devnet to the wallet you just created.

Creating your token

The simplest way to create a token using the SPL-token library is to run this code:

const { createMint } = require('@solana/spl-token');

const token = await createMint(
  connection,
  wallet, // the fee payer
  wallet.publicKey, // the mint authority
  wallet.publicKey, // the freeze authority
  9 // the decimals used, we use 9 because it's the default and recommended value
);

console.log(token.toBase58());
// Outputs the address of your token

In the code above, we create a very basic token that we can configure later (change the supply, name, mint...).

Here we set the fee payer, the mint authority and the freeze authority to be our wallet so our wallet is the one that fully controls the token.

Then, we print the pubkey (or address) of our token because we need that to be able to interact with it.

We set the number of decimals to 9 because it's the default value and the recommended one in the docs. Some tokens use 6, you'll need to look at the number of decimals of the token in the blockchain explorer or using code.

Creating an account in your wallet for your token

An account is a place in your Solana wallet (the one you generated previously or another one) where you can store a custom tokens so we're going to need one.

To create the account for the token in our wallet:

const { getOrCreateAssociatedTokenAccount } = require('@solana/spl-token');

const tokenAccount = await getOrCreateAssociatedTokenAccount(
  connection,
  wallet, // the wallet where you create the account
  token, // the token to create an account for
  wallet.publicKey // the wallet that pays the gas fees
)

console.log(tokenAccount.address.toBase58());
// Outputs the address of the account

That code will create the account for the token and the wallet passed in parameters and print the pubkey of the account.

Checking the token balances of your wallet

To check how much tokens an account has, use this code and pass the token you want to check the balance for and the account:

const { getAccount } = require('@solana/spl-token');

const tokenAccountInfo = await getAccount(
  connection,
  tokenAccount.address
)

console.log(tokenAccountInfo.amount); // outputs the balance

This returns 0 when you run it with the token address you created because we didn't mint any tokens yet.

If you want to check the token balances of other accounts, check out this tutorial we made:

How to get the token balance of a Solana address with JS
In this tutorial, we are going to learn how to get the balance of a Solana address for any token using JavaScript and the @solana/web3.js library.

Minting tokens

Minting tokens is the act of actually generating the tokens. Just like governments print money to generate new dollars and put them in circulation, you need to mint tokens to actually generate them and put them in circulation.

Here is the code to mint new tokens:

const { mintTo } = require('@solana/spl-token');

await mintTo(
  connection,
  wallet,
  mint,
  tokenAccount.address,
  mintAuthority,
  100 * web3.LAMPORTS_PER_SOL // because decimals are set to 9
)

Using that code, you mint the amount of tokens you pass and the account that you pass will receive these new tokens.

Since we set the tokens decimals to 9, we need to pass an amount of tokens with 9 decimals. The easiest way to do so is just to multiply the amount you want by LAMPORTS_PER_SOL.

Floaters can generate precision errors when you do operations between floaters. For that reason, blockchains only use integers. So to represent fractions of SOL, they set 1 SOL to equal 1000000000 in the blockchain and they called that unit lamports.

Your tokens needs to use that same logic, it's a convention and a good practice otherwise nobody will interact correctly with your token. Again, some tokens use 6 decimals so be careful when using someone else's tokens.

That means in the code above, we minted 100 tokens to our account.

Now that you have tokens in your wallet account, you can do whatever you want with these tokens, you can transfer them, add them to a pool so people can purchase them, burn them and many more things!

Transferring the tokens to another wallet

You might not want to keep all the tokens in your own wallet so to transfer the tokens you can use the transfer function:

const { getOrCreateAssociatedTokenAccount, transfer } = require('@solana/spl-token');
const bs58 = require('bs58');

// get the wallet to send the transaction from
// use the wallet created above or create a new variable here from the private key as a string:
const fromWallet = web3.Keypair.fromSecretKey(bs58.decode(privateKey));

// get the pubkey of the recipient from its pubkey as a string 
const toPublicKey = new web3.PublicKey(toAddress);

// get mint pubkey from the pubkey as a string
const mint = new web3.PublicKey(tokenAddress);


// Create associated token accounts for token if they don't exist yet

 const fromTokenAccount = await getOrCreateAssociatedTokenAccount(
    connection,
    fromWallet,
    mint,
    fromWallet.publicKey
);

const toTokenAccount = await getOrCreateAssociatedTokenAccount(
    connection,
    fromWallet,
    mint,
    toPublicKey
);

const signature = await splToken.transfer(
    connection,
    fromWallet,
    fromTokenAccount.address,
    toTokenAccount.address,
    fromWallet.publicKey,
    100 * web3.LAMPORTS_PER_SOL // we need to add the correct number of decimals to the amount here
);

console.log(signature) // the signature is the unique identifier of the transactions, you can paste it in a blockchain explorer to see details about the transaction and its state

To transfer tokens, you'll need to get or create token accounts for the wallets involved in the transaction.

Once you have these accounts, you can use the transfer function to send the amount you want from the account of the wallet you have control over to the wallet you want to send it to.

In the example above we send 100 tokens but you can send the amount you want.

The signature that is returned is the unique identifier of the transaction. It allows you to get information about it. You can use it to search for your transaction and get information on the Solana blockchain explorer or from JavaScript code.

To learn how to get information about Solana transaction, check out this tutorial:

How to get the state of a transaction Solana with JavaScript
In this tutorial, we are going to learn how to get information about the state of a Solana transaction using JavaScript.

And this one to learn more about how to transfer tokens in Solana:

How to transfer tokens on the Solana blockchain JavaScript
In this tutorial, we are going to learn how to transfer SPL tokens on the Solana blockchain using JavaScript and the @solana/web3.js library.

Limiting the supply and disabling mint

As you may know, most tokens can't be minted indefinitely. Setting a total supply available creates rarity and a real value on the token.

By default, you can't set the limit supply of a token but you can disable the mint at any time on your SPL token:

const { AuthorityType, setAuthority } = require('@solana/spl-token');
const bs58 = require('bs58');

// get mint pubkey from the pubkey as a string
const mint = new web3.PublicKey(tokenAddress);

// get the wallet to send the transaction from
// use the wallet created above or create a new variable here from the private key as a string:
const fromWallet = web3.Keypair.fromSecretKey(bs58.decode(privateKey));

const connection = new Connection
await setAuthority(
    connection,
    fromWallet,
    mint,
    fromWallet,
    AuthorityType.MintTokens,
    null, // this sets the mint authority to null so nobody can mint
);

This will disable the so it's now impossible to mint, unless you re-enable it by resetting the mint authority to your wallet.

Burning tokens

Burning tokens means "deleting" tokens completely from the supply. This is used to increase the rarity of a token which will increase its value.

To burn tokens, you need to run this command and pass in the address of your token account and the amount of tokens you want to burn:

const { burn } = require('@solana/spl-token');

// get mint pubkey from the pubkey as a string
const mint = new web3.PublicKey(tokenAddress);

// wallet is the wallet we generated in the sections above. You can also re-create it from its private key, see the example in the section above

const signature = await burn(
    connection,
    wallet,
    tokenAccount,
    mint,
    wallet.pubKey,
    100 * web3.LAMPORTS_PER_SOL,
)

console.log(signature)

In the example above, we create a burn transaction that will burn 100 tokens that are on the token account that we created above and that we pass here.

Naming your token and registering your token

Right now, your token is created and you can see it in the Solana blockchain explorer.

But it's not registered in Solana's token list! So it doesn't have a name or a logo.

To do that, in the past, you needed to create a pull request on Solana's token list Github repository. Now, this repository is archived but gives you 2 websites to register your token. You can find the repository with instructions here.

All you have to do now is register the token in one of these 2 websites (at the time of writing this):

  1. Strata Protocol Token Launchpad
  2. Token Creator Demo

When you read this, it might have changed and maybe there are new ways to do that.
I recommend using the second website at the moment.

First, you need to have a Phantom wallet (or another Solana browser wallet) where you're going to transfer some of your tokens and some SOL. If you are on the devnet want to airdrop your wallet from the browser, you can go to this website. Otherwise you can use this command in your terminal:

solana airdrop 1 <address-to-airdrop>

Then, you need to create a JSON file that will contain your token metadata. Your metadata file should look like this:

{
  "name": "TOKEN NAME",
  "symbol": "TOKEN SYMBOL (A FEW LETTERS)",
  "description": "DESCRIPTION OF THE TOKEN",
  "image": "URI OF THE LOGO IMAGE"
}

To generate the JSON file, open a text editor like VS Code and create a new JSON file. Then add the metadata you want inside and save it.

Next, go to the second website and go to the "Upload Metadata" section. From there, choose the network you want and connect your wallet. Then upload a logo for your token (it costs 1 SOL) and copy the URL they give you.

Otherwise, you can also deploy it yourself somewhere and paste the URL there.

Put the logo image URL in the metadata in the image property. Save the JSON file and upload it on the website. It will give you a URL that you need to copy because you'll need that later.

Same here, it costs 1 SOL. If you don't want to pay, you can deploy it somewhere else and paste the URL there.

Lastly, go to the "Update metadata" section, fill in all the fields and paste your metadata URL in the "Metadata URL" input field.

Then you can submit the form and your token is created! Now in your Phantom wallet, you should see the logo and name of your token.

And that's it 🎉

Thank you for reading this article, if you want to get better at blockchain development, leave your email below and you'll get:

  • access to the private Discord of a community of Web3 builders
  • access to free guides that will teach you Blockchain Development