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 onceconst account = await program.account.counter.fetch(counterPda);// Subscribe via websocket to account changesprogram.account.counter.subscribe(counterPda).on("change", (account) => {console.log("Account changed:", account);});// Or use decoder to decode any account or instruction dataconnection.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 eventemit!(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 buildcat 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 adiscriminator
. - 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 andisMut
/isSigner
in accounts. You can convert legacy IDLs usinganchor 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 programdotnet tool install Solana.Unity.Anchor.Tool <- run oncedotnet 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.
- Keep IDLs updated → Always update the IDL when you make changes to your program.
- Upload IDLs on-chain → for transparency and tooling support.
- Document custom errors → improves UX for clients.
- 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
- Anchor Docs on IDLs → auto-generates IDLs and clients. (TypeScript, C#, Python)
- Codama → IDL tooling + client generators (Rust, JS/TS, Umi/Kit, etc.).
- Program Metadata Program → store IDLs and security.txt information on-chain.
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.