Using program plugins

Add typed program APIs to your client

Program plugins are how Kit clients gain typed access to a specific Solana program. They install a typed namespace under the client — client.system, client.token, and so on — and expose the program's accounts and instructions through it. This guide walks through adding program plugins to a client and using them, alongside the standalone helpers that the same packages also expose.

Installation

Most popular Solana programs ship a Codama-generated package that doubles as a Kit program plugin. Install one for each program you want to interact with.

npm install @solana-program/system @solana-program/token

The Available plugins page lists the program plugins available today. Once installed, apply each plugin with .use(...) after your signer and bundle plugins, and the client gains a new typed namespace named after the program.

import { ,  } from '@solana/kit';
import {  } from '@solana/kit-plugin-rpc';
import { ,  } from '@solana/kit-plugin-signer';
import {  } from '@solana-program/system';
import {  } from '@solana-program/token';
 
const  = await ()
    .(())
    .(())
    .(((10_000_000_000n)))
    .(())
    .(());

client.system and client.token now expose accounts and instructions namespaces typed against the System and Token programs. Multiple program plugins compose freely — installing more of them simply adds more namespaces to the client.

What is a program plugin?

A program plugin is a function from a Codama-generated package that adds a typed namespace for one program's accounts and instructions to a Kit client. The same package also exports standalone helpers — getXInstruction, fetchX, decodeX, and so on, where X is the instruction or account name — for cases where you do not want a client.

import {  } from '@solana-program/system';
import {  } from '@solana-program/token';

You can think of a program plugin as a typed adapter on top of these standalone helpers. The plugin handles the wiring — passing the client's RPC and payer where needed — so your code can focus on what the program does. This is great for developer experience and program discoverability, but the tradeoff is tree-shakability: pulling an entire program namespace into your client tends to produce a larger bundle than importing only the standalone helpers you actually use.

Fetch typed accounts

Each accounts namespace exposes one entry per account type defined by the program, with fetch, fetchMaybe, fetchAll, and fetchAllMaybe methods that already know the codec to use.

import {  } from '@solana/kit';
const  = await ....(
    ('So11111111111111111111111111111111111111112'),
);
..; // typed as `number`

Because the account namespace is generated from the program's IDL, every field on mint.data is fully typed — autocompletion and refactors flow through naturally. See Fetching accounts for raw account fetching that doesn't depend on a program plugin.

Create typed instructions

The matching instructions namespace exposes one builder per instruction the program defines. The builders accept a typed input and return an instruction ready to be sent.

import { ,  } from '@solana/kit';
const  = ...({
    : .,
    : ,
    : (500_000n),
});

Use the .sendTransaction() shortcut

Each typed instruction returned by a program plugin also exposes a .sendTransaction() method that wraps client.sendTransaction([instruction]). This is the most concise way to send a one-off transaction.

import { ,  } from '@solana/kit';
const  = await ..
    .({
        : .,
        : ,
        : (500_000n),
    })
    .();

The same returned object also exposes .sendTransactions(), .planTransaction(), and .planTransactions() shortcuts that wrap the matching client methods. The shortcut shines for single-instruction operations where the rest of the transaction would just be ceremony. When you want to combine several instructions into one transaction or compose larger operations, client.sendTransaction([...]) is the more flexible primitive.

Use instruction plans from program plugins

Some operations naturally span more than one instruction — creating and initializing a token mint is a classic example. Program plugins expose these as instruction plans rather than raw instructions, which means they can also be combined into larger plans.

import {  } from '@solana/kit';
const  = await ();
const  = ...({
    ,
    : 9,
    : ..,
});

The returned plan can be sent on its own with .sendTransaction() or .sendTransactions(), fed into client.sendTransaction([...]) alongside other work, or combined with sequentialInstructionPlan(...) and parallelInstructionPlan(...) helpers when building larger operations.

Use program libraries without a client

Every program package also exports standalone helpers that work on a plain Rpc object or with raw Instructions. This is useful for libraries that should not assume a Kit client, or when you want maximum tree-shaking.

import { , , ,  } from '@solana/kit';
import {  } from '@solana-program/token';
import {  } from '@solana-program/system';
 
const  = ('https://api.devnet.solana.com');
 
const  = await (, ('So11111111111111111111111111111111111111112'));
 
const  = await ();
const  = ({
    ,
    : ('Ay1zdJ3VDbhrAtkRiqBUJgKLHYbgFZN5BXk7svtMowif'),
    : (500_000n),
});

Because the standalone helpers and the plugin-based namespaces are generated from the same IDL, the input shapes match exactly. You can move from one style to the other without rewriting the data your application passes around.

Generate plugins for your own programs

Any program with a Codama IDL can be turned into a Kit-compatible package, with both standalone helpers and a program plugin, using the Codama JS renderer. The renderer reads the IDL, emits TypeScript bindings, and wires them up through the same @solana/program-client-core primitives the @solana-program/* packages use.

If your program is built with Anchor, you can convert its Anchor IDL to a Codama IDL first, which means program plugin generation works for Anchor programs as well. See Generating program plugins for a step-by-step walkthrough.

Next steps

On this page