> ## Documentation Index
> Fetch the complete documentation index at: https://luminouslabs-cc5545c6-docs-main-reorder.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Legacy Compressed Tokens

> Compressed tokens are the most efficient way to distribute SPL tokens (eg rewards, airdrops). For other token purposes use Light Token.

export const TokenAccountCompressedVsSpl = () => {
  const [numAccounts, setNumAccounts] = useState(100000);
  const [showCustomAccounts, setShowCustomAccounts] = useState(false);
  const ACCOUNT_STORAGE_OVERHEAD = 128;
  const LAMPORTS_PER_BYTE = 6960;
  const DATA_LEN = 165;
  const COMPRESSED_COST_PER_ACCOUNT = 10300;
  const LAMPORTS_PER_SOL = 1_000_000_000;
  const ACCOUNTS_MAX = 1000000;
  const solanaCost = numAccounts * (ACCOUNT_STORAGE_OVERHEAD + DATA_LEN) * LAMPORTS_PER_BYTE;
  const compressedCost = numAccounts * COMPRESSED_COST_PER_ACCOUNT;
  const savings = solanaCost - compressedCost;
  const savingsPercent = (savings / solanaCost * 100).toFixed(1);
  const handleAccountsChange = value => {
    const num = Math.max(1, Math.min(1000000, Number.parseInt(value) || 1));
    setNumAccounts(num);
  };
  const formatSOL = lamports => {
    const sol = lamports / LAMPORTS_PER_SOL;
    if (sol >= 1000) {
      return sol.toLocaleString(undefined, {
        maximumFractionDigits: 2
      });
    } else if (sol >= 1) {
      return sol.toFixed(4);
    }
    return sol.toFixed(6);
  };
  const accountsPresets = [10000, 100000, 500000];
  const SliderMarkers = ({max, step}) => {
    const marks = [];
    for (let i = step; i < max; i += step) {
      const percent = i / max * 100;
      marks.push(<div key={i} className="absolute top-1/2 -translate-y-1/2 w-px h-2 bg-zinc-300 dark:bg-white/30" style={{
        left: `${percent}%`
      }} />);
    }
    return <>{marks}</>;
  };
  return <div className="p-5 rounded-3xl not-prose mt-4 dark:bg-white/5 backdrop-blur-xl border border-black/[0.04] dark:border-white/10 shadow-lg" style={{
    fontFamily: "Inter, sans-serif"
  }}>
      <div className="space-y-5">
        {}
        <div className="space-y-2 px-3">
          <div className="flex justify-between items-center">
            <span className="text-sm text-zinc-700 dark:text-white/80">
              Number of Token Accounts
            </span>
            <div className="flex items-center gap-1.5">
              {accountsPresets.map(a => <button key={a} onClick={() => {
    setNumAccounts(a);
    setShowCustomAccounts(false);
  }} className={`px-2.5 py-1 text-xs font-medium rounded-lg border backdrop-blur-sm transition-all ${numAccounts === a && !showCustomAccounts ? "bg-blue-500/20 border-blue-500/50 text-blue-600 dark:text-blue-400" : "bg-black/[0.015] dark:bg-white/5 border-black/[0.04] dark:border-white/20 text-zinc-600 dark:text-white/70 hover:bg-black/[0.03]"}`}>
                  {a.toLocaleString()}
                </button>)}
              {showCustomAccounts ? <input type="number" min="1" max="1000000" value={numAccounts} onChange={e => handleAccountsChange(e.target.value)} className="w-24 px-2 py-1 text-right text-xs font-mono font-medium bg-blue-500/10 dark:bg-blue-500/20 border border-blue-500/50 rounded-lg backdrop-blur-sm focus:outline-none focus:ring-2 focus:ring-blue-500/50" autoFocus /> : <button onClick={() => setShowCustomAccounts(true)} className="px-2.5 py-1 text-xs font-medium rounded-lg border backdrop-blur-sm transition-all bg-black/[0.015] dark:bg-white/5 border-black/[0.04] dark:border-white/20 text-zinc-600 dark:text-white/70 hover:bg-black/[0.03]">
                  Custom
                </button>}
            </div>
          </div>
          <div className="flex items-center">
            <span className="w-1/3 text-xs text-zinc-500 dark:text-white/50 whitespace-nowrap">
              {numAccounts.toLocaleString()} accounts
            </span>
            <div className="w-2/3 relative">
              <SliderMarkers max={ACCOUNTS_MAX} step={200000} />
              <input type="range" min="5000" max={ACCOUNTS_MAX} step="5000" value={Math.min(numAccounts, ACCOUNTS_MAX)} onChange={e => {
    setNumAccounts(Number.parseInt(e.target.value));
    setShowCustomAccounts(false);
  }} className="relative w-full h-1.5 bg-black/[0.03] dark:bg-white/20 rounded-full appearance-none cursor-pointer backdrop-blur-sm z-10" />
            </div>
          </div>
        </div>

        {}
        <div className="grid grid-cols-3 gap-3">
          <div className="p-4 bg-black/[0.015] dark:bg-white/5 backdrop-blur-md rounded-2xl text-center border border-black/[0.04] dark:border-white/10 shadow-sm">
            <div className="text-xs text-zinc-500 dark:text-white/50 mb-1 uppercase tracking-wide">
              SPL Token
            </div>
            <div className="text-xl font-mono font-semibold text-zinc-900 dark:text-white">
              {formatSOL(solanaCost)}
            </div>
            <div className="text-xs text-zinc-400 dark:text-white/40">SOL</div>
          </div>

          <div className="p-4 bg-black/[0.015] dark:bg-white/5 backdrop-blur-md rounded-2xl text-center border border-black/[0.04] dark:border-white/10 shadow-sm">
            <div className="text-xs text-zinc-500 dark:text-white/50 mb-1 uppercase tracking-wide">
              Compressed
            </div>
            <div className="text-xl font-mono font-semibold text-zinc-900 dark:text-white">
              {formatSOL(compressedCost)}
            </div>
            <div className="text-xs text-zinc-400 dark:text-white/40">SOL</div>
          </div>

          <div className="p-4 bg-black/[0.015] dark:bg-white/5 backdrop-blur-md rounded-2xl text-center border border-black/[0.04] dark:border-white/10 shadow-sm">
            <div className="text-xs text-zinc-500 dark:text-white/50 mb-1 uppercase tracking-wide">
              Savings
            </div>
            <div className="text-xl font-mono font-semibold text-zinc-900 dark:text-white">
              {savingsPercent}%
            </div>
            <div className="text-xs text-zinc-400 dark:text-white/40">{formatSOL(savings)} SOL</div>
          </div>
        </div>
      </div>
    </div>;
};

<Accordion title="Agent skill">
  Use the [airdrop](https://github.com/Lightprotocol/skills/tree/main/skills/airdrop) agent skill for token distribution and airdrops:

  <Tabs>
    <Tab title="Claude Code">
      Add the marketplace and install:

      ```
      /plugin marketplace add Lightprotocol/skills
      /plugin install solana-rent-free-dev
      ```
    </Tab>

    <Tab title="Cursor">
      1. Open Settings (**Cmd+Shift+J** / **Ctrl+Shift+J**)
      2. Navigate to **Rules & Commands** → **Project Rules** → **Add Rule** → **Remote Rule (GitHub)**
      3. Enter: `https://github.com/Lightprotocol/skills.git`
    </Tab>

    <Tab title="Any Agent">
      ```
      npx skills add Lightprotocol/skills
      ```
    </Tab>
  </Tabs>

  For orchestration, install the [general skill](https://zkcompression.com/skill.md):

  ```bash theme={null}
  npx skills add https://zkcompression.com
  ```
</Accordion>

<Info>
  **Note: The new [Light Token Program Beta](/light-token/welcome)** is live on Solana Devnet with mainnet expected in Q1 2026.
  We recommend to use Light Token for most purposes except airdrops and other forms of token distribution.
  The SDK for compressed tokens can still be used once Light Token is on Solana Mainnet.
  For production use today, use Compressed Tokens, which are on Solana Mainnet.
</Info>

| Creation          | Solana               | Compressed         |
| :---------------- | :------------------- | :----------------- |
| **Token Account** | \~2,000,000 lamports | **5,000** lamports |

1. Compressed token accounts store token balance, owner, and other information of tokens like SPL and light-tokens.
2. Compressed token accounts are rent-free.
3. Any light-token or SPL token can be compressed/decompressed at will.

<Check>
  **Compressed Tokens are supported by leading Solana wallets such as Phantom and Backpack.**
</Check>

## Recommended Usage of Compressed Tokens

<Card title="Token Distribution">
  Distribute tokens without paying upfront rent per recipient.

  <Card title="Guide" icon="chevron-right" color="#0066ff" href="/compressed-tokens/airdrop" horizontal />
</Card>

<Card title="Store SPL-token accounts rent-free">
  Compress existing SPL-token accounts to save rent costs for your users.

  <Card title="Compress SPL Token Accounts" icon="chevron-right" color="#0066ff" href="https://github.com/Lightprotocol/examples-zk-compression/blob/main/compressed-token-cookbook/actions/compress.ts" horizontal />
</Card>

## RPC methods

The Photon API provides ZK Compression methods that extend the default Solana JSON RPC API.

<Card title="JSON RPC methods" icon="chevron-right" color="#0066ff" href="/api-reference/json-rpc-methods/overview" horizontal />

## Guides

The SDK for compressed tokens can be used but is not maintained.
Use [Light Token](/light-token/welcome) for other purposes than token distribution or storage of inactive tokens.

|                           |                                                                                                         |
| ------------------------- | ------------------------------------------------------------------------------------------------------- |
| Compressed token cookbook | [GitHub](https://github.com/Lightprotocol/examples-zk-compression/tree/main/compressed-token-cookbook)  |
| Token distribution        | [GitHub](https://github.com/Lightprotocol/examples-zk-compression/tree/main/example-token-distribution) |
| Web client                | [GitHub](https://github.com/Lightprotocol/examples-zk-compression/tree/main/example-web-client)         |

***

## Didn't find what you were looking for?

<Callout type="info">
  Reach out! [Telegram](https://t.me/swen_light) | [email](mailto:support@lightprotocol.com) | [Discord](https://discord.com/invite/7cJ8BhAXhu)
</Callout>
