LUMOS + Anchor: The Perfect Combo for Solana Development
Source: Dev.to
Overview
LUMOS works alongside Anchor to streamline Solana development. It generates Anchor‑compatible Rust and TypeScript code directly from a single .lumos schema, keeping your types and IDL in sync automatically.
Comparison
| Without LUMOS | With LUMOS |
|---|---|
| Manually write Rust structs | Define once in a .lumos schema |
| Manually write TypeScript types | Auto‑generate TypeScript |
| Hope Rust ↔ TS stay in sync | Guaranteed sync (same source) |
| Calculate account space by hand | Auto‑calculated LEN constants |
| Write IDL manually or extract | Auto‑generate IDL from schema |
Example Schema (game.lumos)
#[solana]
#[account]
struct GameConfig {
authority: PublicKey,
max_players: u32,
entry_fee: u64,
prize_pool: u64,
}
#[solana]
#[account]
struct Player {
wallet: PublicKey,
game: PublicKey,
score: u64,
joined_at: i64,
}
#[solana]
enum GameInstruction {
Initialize { max_players: u32, entry_fee: u64 },
JoinGame,
UpdateScore { score: u64 },
ClaimPrize,
}
Generating Code
lumos anchor generate game.lumos \
--name game_program \
--typescript
The command produces a project layout like:
game_program/
├── programs/game_program/
│ ├── src/
│ │ ├── lib.rs # Program entry point
│ │ └── state.rs # Account structs
│ └── Cargo.toml
├── target/idl/
│ └── game_program.json # Anchor IDL
└── client/
└── game_program.ts # TypeScript client
CLI Options
lumos anchor generate [OPTIONS]
| Option | Description |
|---|---|
-o, --output | Output directory |
-n, --name | Program name |
-V, --version | Program version (default: 0.1.0) |
-a, --address | Program address |
--typescript | Generate TypeScript client |
--dry-run | Preview without writing |
Example with Additional Flags
lumos anchor generate game.lumos \
--name my_game \
--version 1.0.0 \
--address "Game111111111111111111111111111111111111111" \
--typescript
Other useful commands:
lumos anchor idl game.lumos --pretty -o target/idl/game.json
lumos anchor space game.lumos --format rust
Generated Rust Code (state.rs)
use anchor_lang::prelude::*;
#[account]
pub struct GameConfig {
pub authority: Pubkey,
pub max_players: u32,
pub entry_fee: u64,
pub prize_pool: u64,
}
impl GameConfig {
pub const LEN: usize = 8 + 32 + 4 + 8 + 8; // 60 bytes
}
#[account]
pub struct Player {
pub wallet: Pubkey,
pub game: Pubkey,
pub score: u64,
pub joined_at: i64,
}
impl Player {
pub const LEN: usize = 8 + 32 + 32 + 8 + 8; // 88 bytes
}
Generated TypeScript Client (game_program.ts)
import { PublicKey } from '@solana/web3.js';
import * as borsh from '@coral-xyz/borsh';
export interface GameConfig {
authority: PublicKey;
maxPlayers: number;
entryFee: number;
prizePool: number;
}
export const GameConfigSchema = borsh.struct([
borsh.publicKey('authority'),
borsh.u32('maxPlayers'),
borsh.u64('entryFee'),
borsh.u64('prizePool'),
]);
Use Cases & Recommendations
| Scenario | Recommendation |
|---|---|
| Starting a new Anchor project | ✅ Use LUMOS |
| Existing project, need type sync | ✅ Use LUMOS |
| Simple program with few account types | ⚠️ Either works |
| Complex program with many shared types | ✅ Use LUMOS |
| Team with mixed Rust/TS developers | ✅ Use LUMOS |
Bottom Line
If you write TypeScript clients for your Anchor programs, LUMOS eliminates the need to maintain duplicate type definitions, keeping Rust and TS in perfect sync.
Installation
cargo install lumos-cli
lumos anchor generate schema.lumos --typescript
References
- Documentation:
- GitHub: