
Expo Kit Anchor example
MobileA template for building a Solana mobile app with Expo, React Native, Solana Kit, Anchor, and Uniwind.
Get started
npx solana-mobile create --template gh:solana-mobile/templates/mobile/expo-kit-anchorexpo-kit-anchor
This is an Expo project pre-configured with an Anchor program, Uniwind for styling, and Solana libraries.
Technologies
- Anchor (Solana program framework)
- Expo
- Uniwind (Tailwind CSS for React Native)
- @solana/kit
- @wallet-ui/react-native-kit
Get started
Install dependencies
npm installStart the app
This steps builds the dependencies for the development client.
npm run android
In the output, you'll find options to open the app in a:
- development build
- Android emulator
- iOS simulator
- Expo Go, a limited sandbox for trying out app development with Expo
You can start developing by editing the files inside the app directory. This project uses file-based routing.
The Anchor program
The anchor directory contains a Solana program called hello_world, scaffolded with the Anchor CLI. It's a small counter where every wallet gets its own counter account, derived from the wallet address (seeds = [b"counter", wallet]) — use it as the starting point for your own program: search for hello_world (and HelloWorld/helloWorld) to find everything to rename.
Working on the program requires the Rust, Solana, and Anchor toolchains.
Generate a program keypair and sync the program ID
The program ID in the source is a placeholder. This generates your own keypair, syncs it into
Anchor.tomlanddeclare_id!, rebuilds the program so the IDL carries the new address, and regenerates the TypeScript client from it:npm run anchor:setupBuild and test the program
npm run anchor:testThis builds the program, spins up a local validator, deploys, and runs the Vitest tests in
anchor/tests.
The generated TypeScript client
The app talks to the program through a fully typed client generated by Codama from the program's IDL. It lives in anchor/src/client/js/generated and only depends on @solana/kit. Import it anywhere in the app via the @project/anchor alias:
import { fetchCounter, getIncrementInstructionAsync, HELLO_WORLD_PROGRAM_ADDRESS } from '@project/anchor'
After changing the program, rebuild the IDL and regenerate the client:
npm run anchor:build
npm run codama:js
Add hand-written wrappers around the generated code in anchor/src/client/js/index.ts — the generated directory is overwritten on every run.
Using the program from the app
The home screen includes a counter feature (src/features/counter) that talks to the program through the generated client and Mobile Wallet Adapter. Each connected wallet initializes and increments its own counter. The app connects to devnet, so deploy the program there before using it:
npm run anchor:deploy:devnet
Your deploy wallet needs devnet SOL — get some from faucet.solana.com. The wallet in the app needs a small amount of devnet SOL too, to pay for the counter account and transaction fees.
Develop against localnet
For a faster loop you can run everything against a local validator, forwarded to your device over adb:
- Start the localnet and keep it running:
npx solana-mobile localnet - Deploy the program to it:
npm run anchor:deploy:localnet - Switch the network to Localnet with the selector in the app
- Connect your wallet and tap Request Airdrop to fund it
Two things to know: localnet needs a debug build — npm run android makes one, and Android debug builds allow the cleartext http://localhost endpoint while release builds only talk HTTPS. And the regular Seeker wallet only signs for public clusters, so signing on localnet requires a localnet-capable wallet such as fakewallet.
Learn more
To learn more about developing your project with Expo, look at the following resources:
- Expo documentation: Learn fundamentals, or go into advanced topics with our guides.
- Uniwind documentation: Learn how to style your app with Tailwind CSS.
- Anchor documentation: Learn how to build Solana programs with Anchor.
- Solana documentation: Learn how to build on Solana.