IDL - an easy to use Program Interface

IDL stands for Interface Definition Language.
On Solana, IDLs are JSON files that describe the interface of a program. They allow explorers and users to decode program instructions, account data and program errors and offer the possibility to generate clients in different program languages.


Why IDLs Matter

  • Standardization → A shared format for program interfaces.
  • Developer Experience → Generate client SDKs automatically.
  • Composability → Other developers can interact with your program without reading its source code.
  • Readability → Everyone can read program instructions and account data in explorers without reading the program’s source code.

What you can do with IDLs

Decoding Instruction and Account Data

All Explorers use program IDLs to decode instructions and account data. Here you can see a Anchor 0.30.1 and a Legacy IDL example in the Solana Explorer UI. In this transaction you can see the decoded instruction for a 2048 game, including pushInDirection and its direction.

You can decode instructions and account data in your typescript client by using the Solana JS helpers.

Parsing Anchor Events or Account changes

You can easily subscribe to account changes in your program by using the generated TypeScript types.

import { Connection } from "@solana/web3.js";
const connection = new Connection("https://api.devnet.solana.com");
// Fetch account once
const account = await program.account.counter.fetch(counterPda);
// Subscribe via websocket to account changes
program.account.counter.subscribe(counterPda).on("change", (account) => {
console.log("Account changed:", account);
});
// Or use decoder to decode any account or instruction data
connection.onAccountChange(counterPda, (accInfo) => {
console.log(
"Account changed:",
program.coder.accounts.decode("counterData", account.data)
);
});

You can for example emit Anchor events in your program and then log these events, write them in a database or use them to for example send a message into a telegram chat.

// Emit the purchase event
emit!(PurchaseMade {
buyer: *ctx.accounts.signer.key,
product_name: name,
price,
timestamp: Clock::get()?.unix_timestamp,
table_number,
receipt_id,
telegram_channel_id: ctx.accounts.receipts.telegram_channel_id.clone(),
store_name: ctx.accounts.receipts.store_name.clone(),
receipts_account: ctx.accounts.receipts.key(),
});

For that you can use the Solana JS helpers to parse the events. Here is an example implementation that uses anchor events to post messages into a telegram chat.

Decode Transactions

You can also decode transactions in your client by using the Solana JS helpers. This will give you a typed object of the whole transaction.

Build your own client

Using an IDL you can create your own client in many languages. You just find a program you want to interact with, download the IDL and then you can generate a client in your preferred language.

Here is an example of how to generate a client in TypeScript.

IDLs in Anchor

If you’re using the Anchor framework:

  • The IDL is auto-generated when you build your program.
  • It lives in target/idl/<program>.json.
  • TypeScript types are generated in target/types/<program>.ts.
  • The program address is stored in the IDL (idl.address).
anchor build
cat target/idl/counter.json

Anatomy of an IDL

Here’s a minimal example (Anchor v0.30+ spec):

{
"address": "6khKp4BeJpCjBY1Eh39ybiqbfRnrn2UzWeUARjQLXYRC",
"metadata": {
"name": "counter",
"version": "0.1.0",
"spec": "0.1.0"
},
"instructions": [
{
"name": "increment",
"discriminator": [11, 18, 104, 9, 104, 174, 59, 33],
"accounts": [{ "name": "counter", "writable": true }],
"args": []
}
],
"accounts": [
{
"name": "Counter",
"discriminator": [255, 176, 4, 245, 188, 253, 124, 25]
}
],
"types": [
{
"name": "Counter",
"type": {
"kind": "struct",
"fields": [{ "name": "count", "type": "u64" }]
}
}
]
}
  • address: the on-chain program ID.
  • metadata: { name, version, spec, ... } about the program/interface.
  • instructions: callable methods with accounts, args, and a discriminator.
  • accounts: account types exposed by the program (with discriminators).
  • types: struct/enum/type aliases referenced by instructions/accounts.
  • events / errors / constants: optional definitions for events, error codes, constants.

Note: Anchor v0.30 introduced a new IDL spec. Legacy IDLs (pre-0.30) used fields like name, version at top level and isMut/isSigner in accounts. You can convert legacy IDLs using anchor idl convert or rebuild with Anchor v0.30+. If you need to convert a legacy IDL to the new spec on the fly you can also use this conversion code. This is useful for example if you maintain a solana explorer and want to stay backwards compatible.


TypeScript Client

Anchor will also automatically generate a TypeScript client for you. You can find the generated client in the target/types folder.

Then in your client (TypeScript, v0.30+) you can call program instructions and fetch accounts as easy as this:

import { AnchorProvider, Program } from "@coral-xyz/anchor";
import idl from "./counter.json";
const provider = AnchorProvider.local();
const program = new Program(idl, provider);
await program.methods.increment().rpc();

C# Client

To generate a C# client you can use the following command:

cd program
dotnet tool install Solana.Unity.Anchor.Tool <- run once
dotnet anchorgen -i target/idl/counter.json -o target/idl/Counter.cs

You can read more about how to interact with a C# client from Unity in the Solana games preset or in the Games docs.

Python Client

For Python you can use the AnchorPy library.

More client generators will be available using Codama renderers in the future.


IDLs Without Anchor

Not all programs are built with Anchor.
For native Solana programs:

  • A tool called Codama is currently in development to generate IDLs from Rust via macros or by converting Anchor IDLs. Here is an in progress example of Codama Macros to generate a Codama IDL. Codama converts Anchor/Shank IDLs into a Codama IDL. To get an Anchor IDL, generate it with Anchor (or use anchor idl convert for legacy projects).
  • Until the codama macros are completely ready you can also use Metaplex Shank to generate a Shank IDL, then convert it to a Codama IDL.
  • You can also write the IDL by hand (Anchor or Codama formats) but this is not very reliable. AI tools like Cursor can help you to write the IDL but you should always verify the IDL with the program source code and the better way is to use Anchor, Codama or Metaplex Shank.

Storing IDLs On-Chain

There are two ways to upload IDLs on-chain. The most used and standard one is the Anchor IDL account. How Anchor allows you to upload your IDLs on-chain is by adding additional instructions to your program allow you to upload and update your IDLs on-chain. This adds some extra size to the program and this is why the program metadata program was created. In the program metadata program all the program IDLs and security.txt info like name, contact and icon are stored in PDAs of the program metadata program.

Anchor IDL Account

Anchor saves IDLs on-chain in a PDA of your program.

  • IDLs can be uploaded on-chain to the Anchor IDL account.
  • This allows explorers, wallets, and SDKs to fetch the IDL directly from Solana.

First time (initialize the IDL account):

anchor idl init <PROGRAM_ID> -f target/idl/counter.json --provider.cluster devnet

Upgrades (subsequent updates by the authority):

anchor idl upgrade <PROGRAM_ID> -f target/idl/counter.json --provider.cluster devnet

Useful related commands:

anchor idl fetch -o idl.json <PROGRAM_ID>
anchor idl authority <PROGRAM_ID>
anchor idl set-authority -p <PROGRAM_ID> -n <NEW_AUTHORITY>
anchor idl erase-authority -p <PROGRAM_ID>

Note that by default the Anchor IDL account generation is permissionless. So upload your IDL as soon as possible and then set an authority.

You can read more about the Anchor IDL account in the Anchor docs.

Program Metadata Program (PMP)

The program metadata program is a program that allows you to store the program IDLs and security.txt info like name, contact and icon on-chain. This will probably be the standard way to store IDLs on-chain in the future.

npx @solana-program/program-metadata write idl <program-id> ./idl.json

You can read more about the program metadata program in the program metadata program docs.

Note: As of the last update of the article the PMP is not supported by all explorers yet.


Best Practices

The best practise for program deploys is to use a Multisig like Squads and to make this process as easy as possible you use the Solana GitHub Actions workflows.

Like this the program will automatically be upgraded, IDL uploaded, the build verified and then there will be a transaction proposed for your multisig to sign and deploy the program.

  1. Keep IDLs updated → Always update the IDL when you make changes to your program.
  2. Upload IDLs on-chain → for transparency and tooling support.
  3. Document custom errors → improves UX for clients.
  4. Verify builds → ensure the IDL matches the deployed program.

Versioning IDLs

Currently with Anchor you can only have one version of the IDL on chain at a time. This means that if you want to make changes to your program you need to upload a new version of the IDL, preferably at the same time as you upgrade the program. This can lead to problems if the clients are not updated yet and is one reason why the program metadata program was written. With PMP, you will be able to have different seeds for your program and do versioning like that. The design for that is not completely final yet and open for discussion.


Further Reading


That’s the basics of IDLs on Solana. They’re the bridge between on-chain programs and off-chain clients, enabling the rich ecosystem of tools and SDKs you see today.