This comprehensive guide shows you how to integrate and use Solana App Kit in your React Native applications. From installation to advanced customization, learn how to leverage the full power of the kit for your Solana mobile app development.
Integration Steps
Follow these steps to integrate Solana App Kit into your existing React Native or Expo application:
Installation
Install the library in your React Native or Expo application:
Configuration
Set up the authentication provider and configuration
Component Integration
Start using pre-built screens and components
Customization
Apply custom themes and styling
Service Integration
Utilize blockchain services and operations
State Management
Integrate with Redux store and state management
Configuration Setup
Basic Configuration Advanced Configuration Configure the authentication provider in your application:
// In your app's configuration
import { CustomizationProvider } from 'solana-app-kit' ;
const myConfig = {
auth: {
provider: 'privy' , // or 'dynamic', 'turnkey'
apiKey: process . env . PRIVY_APP_ID ,
clientId: process . env . PRIVY_CLIENT_ID ,
},
wallet: {
autoConnect: true ,
enabledProviders: [ 'privy' , 'dynamic' , 'mwa' ]
},
theme: {
mode: 'dark' ,
accentColor: '#9945FF'
}
};
// In your App.tsx or equivalent
function App () {
return (
< CustomizationProvider config = { myConfig } >
< NavigationContainer >
{ /* Your app components */ }
</ NavigationContainer >
</ CustomizationProvider >
);
}
Configure the authentication provider in your application:
// In your app's configuration
import { CustomizationProvider } from 'solana-app-kit' ;
const myConfig = {
auth: {
provider: 'privy' , // or 'dynamic', 'turnkey'
apiKey: process . env . PRIVY_APP_ID ,
clientId: process . env . PRIVY_CLIENT_ID ,
},
wallet: {
autoConnect: true ,
enabledProviders: [ 'privy' , 'dynamic' , 'mwa' ]
},
theme: {
mode: 'dark' ,
accentColor: '#9945FF'
}
};
// In your App.tsx or equivalent
function App () {
return (
< CustomizationProvider config = { myConfig } >
< NavigationContainer >
{ /* Your app components */ }
</ NavigationContainer >
</ CustomizationProvider >
);
}
For more complex setups with multiple providers:
import { CustomizationProvider } from 'solana-app-kit' ;
const advancedConfig = {
auth: {
providers: {
privy: {
appId: process . env . PRIVY_APP_ID ,
clientId: process . env . PRIVY_CLIENT_ID ,
loginMethods: [ 'email' , 'google' , 'apple' ],
appearance: {
theme: 'dark' ,
accentColor: '#9945FF'
}
},
dynamic: {
environmentId: process . env . DYNAMIC_ENVIRONMENT_ID ,
walletConnectors: [ 'solana' ]
},
turnkey: {
organizationId: process . env . TURNKEY_ORGANIZATION_ID ,
rpId: process . env . TURNKEY_RP_ID
}
}
},
modules: {
swap: {
defaultProvider: 'jupiter' ,
slippageTolerance: 0.5
},
nft: {
enableTensorIntegration: true
},
ai: {
openaiApiKey: process . env . OPENAI_API_KEY
}
}
};
function App () {
return (
< CustomizationProvider config = { advancedConfig } >
< YourAppContent />
</ CustomizationProvider >
);
}
Component Usage
Pre-built Screens
Use complete, ready-to-deploy screens for common Solana operations:
Social Feed
Token Trading
NFT Marketplace
AI Assistant
import { Thread } from 'solana-app-kit' ;
function MyFeedScreen () {
const currentUser = useSelector ( state => state . auth . user );
const posts = useSelector ( state => state . thread . posts );
return (
< Thread
rootPosts = { posts }
currentUser = { currentUser }
onPostCreate = { handlePostCreate }
onLike = { handleLike }
onComment = { handleComment }
/>
);
}
Individual Components
Use specific components for granular integration:
import { SwapCard , TokenSelector } from 'solana-app-kit' ;
function CustomSwapInterface () {
const [ inputToken , setInputToken ] = useState ( 'SOL' );
const [ outputToken , setOutputToken ] = useState ( 'USDC' );
return (
< View style = { styles . container } >
< TokenSelector
selectedToken = { inputToken }
onTokenSelect = { setInputToken }
label = "From"
/>
< SwapCard
inputToken = { inputToken }
outputToken = { outputToken }
onSwapComplete = { handleSwapComplete }
/>
</ View >
);
}
import { WalletButton , WalletInfo } from 'solana-app-kit' ;
function WalletSection () {
const { connected , wallet } = useWallet ();
return (
< View >
{ connected ? (
< WalletInfo
wallet = { wallet }
showBalance = { true }
showDisconnect = { true }
/>
) : (
< WalletButton
onConnect = { handleConnect }
providers = { [ 'privy' , 'dynamic' ] }
/>
) }
</ View >
);
}
import { NFTCard , NFTGrid } from 'solana-app-kit' ;
function NFTGallery () {
const { nfts , loading } = useFetchNFTs ( walletAddress );
return (
< NFTGrid
nfts = { nfts }
loading = { loading }
onNFTSelect = { handleNFTSelect }
renderItem = { ( nft ) => (
< NFTCard
nft = { nft }
onTrade = { handleTrade }
onView = { handleView }
/>
) }
/>
);
}
Theme Customization
Basic Theming Advanced Theming Override default theming with your brand colors:
import { Thread } from 'solana-app-kit' ;
function MyCustomizedFeed () {
const themeOverrides = {
colors: {
primary: '#3498db' ,
secondary: '#e74c3c' ,
background: '#f5f5f5' ,
surface: '#ffffff' ,
text: '#2c3e50' ,
accent: '#9b59b6'
},
spacing: {
xs: 4 ,
sm: 8 ,
md: 16 ,
lg: 24 ,
xl: 32
},
borderRadius: {
small: 4 ,
medium: 8 ,
large: 16
}
};
return (
< Thread
rootPosts = { myPosts }
currentUser = { currentUser }
themeOverrides = { themeOverrides }
/>
);
}
Override default theming with your brand colors:
import { Thread } from 'solana-app-kit' ;
function MyCustomizedFeed () {
const themeOverrides = {
colors: {
primary: '#3498db' ,
secondary: '#e74c3c' ,
background: '#f5f5f5' ,
surface: '#ffffff' ,
text: '#2c3e50' ,
accent: '#9b59b6'
},
spacing: {
xs: 4 ,
sm: 8 ,
md: 16 ,
lg: 24 ,
xl: 32
},
borderRadius: {
small: 4 ,
medium: 8 ,
large: 16
}
};
return (
< Thread
rootPosts = { myPosts }
currentUser = { currentUser }
themeOverrides = { themeOverrides }
/>
);
}
Create comprehensive theme systems:
const customTheme = {
colors: {
// Brand colors
primary: '#9945FF' ,
primaryLight: '#B47EFF' ,
primaryDark: '#7D2CFF' ,
// Semantic colors
success: '#00D4AA' ,
warning: '#FFB800' ,
error: '#FF4444' ,
info: '#4A90E2' ,
// Surface colors
background: '#0E0E0E' ,
surface: '#1A1A1A' ,
card: '#2D2D2D' ,
// Text colors
textPrimary: '#FFFFFF' ,
textSecondary: '#B0B0B0' ,
textMuted: '#6B6B6B'
},
typography: {
fontFamily: {
regular: 'Inter-Regular' ,
medium: 'Inter-Medium' ,
bold: 'Inter-Bold'
},
fontSize: {
xs: 12 ,
sm: 14 ,
md: 16 ,
lg: 18 ,
xl: 20 ,
xxl: 24
}
},
shadows: {
small: {
shadowColor: '#000' ,
shadowOffset: { width: 0 , height: 2 },
shadowOpacity: 0.1 ,
shadowRadius: 4 ,
elevation: 2
},
medium: {
shadowColor: '#000' ,
shadowOffset: { width: 0 , height: 4 },
shadowOpacity: 0.15 ,
shadowRadius: 8 ,
elevation: 4
}
}
};
function ThemedApp () {
return (
< CustomizationProvider
config = { { theme: customTheme } }
>
< AppContent />
</ CustomizationProvider >
);
}
Service Utilization
Direct Service Usage
Use blockchain services directly for custom implementations:
Token Operations
NFT Operations
AI Integration
import { pumpfunService , swapService } from 'solana-app-kit' ;
// Token creation and trading
async function createAndBuyToken () {
try {
// Create a new meme token
const tokenResult = await pumpfunService . createAndBuyTokenViaPumpfun ({
name: 'My Meme Token' ,
symbol: 'MMT' ,
description: 'The next big meme!' ,
image: imageFile ,
initialBuy: 0.1 // SOL
});
console . log ( 'Token created:' , tokenResult . mint );
// Execute a swap
const swapResult = await swapService . executeSwap (
'SOL' ,
tokenResult . mint ,
1.0 , // 1 SOL
wallet . publicKey ,
sendTransaction
);
console . log ( 'Swap completed:' , swapResult . signature );
} catch ( error ) {
console . error ( 'Operation failed:' , error );
}
}
Pre-built Screen Integration
Or use complete pre-built screens for faster development:
import {
PumpfunScreen ,
NftScreen ,
TokenMillScreen ,
RaydiumScreen
} from 'solana-app-kit' ;
function MainAppNavigator () {
return (
< Tab.Navigator
screenOptions = { {
headerShown: false ,
tabBarStyle: { backgroundColor: '#1A1A1A' }
} }
>
< Tab.Screen
name = "Trading"
component = { PumpfunScreen }
options = { {
tabBarIcon : ({ color , size }) => (
< Icon name = "trending-up" size = { size } color = { color } />
)
} }
/>
< Tab.Screen
name = "NFTs"
component = { NftScreen }
options = { {
tabBarIcon : ({ color , size }) => (
< Icon name = "image" size = { size } color = { color } />
)
} }
/>
< Tab.Screen
name = "Launch"
component = { TokenMillScreen }
options = { {
tabBarIcon : ({ color , size }) => (
< Icon name = "rocket" size = { size } color = { color } />
)
} }
/>
< Tab.Screen
name = "Professional"
component = { RaydiumScreen }
options = { {
tabBarIcon : ({ color , size }) => (
< Icon name = "briefcase" size = { size } color = { color } />
)
} }
/>
</ Tab.Navigator >
);
}
State Management Integration
Redux Store Setup Authentication Management Transaction State Extend your Redux store with pre-built slices:
import { combineReducers , configureStore } from '@reduxjs/toolkit' ;
import {
authReducer ,
threadReducer ,
transactionReducer ,
chatReducer ,
profileReducer
} from 'solana-app-kit' ;
// Combine with existing reducers
const rootReducer = combineReducers ({
// Solana App Kit reducers
auth: authReducer ,
thread: threadReducer ,
transaction: transactionReducer ,
chat: chatReducer ,
profile: profileReducer ,
// Your custom reducers
myCustomFeature: myCustomReducer ,
anotherFeature: anotherReducer ,
});
// Create store with combined reducers
const store = configureStore ({
reducer: rootReducer ,
middleware : ( getDefaultMiddleware ) =>
getDefaultMiddleware ({
serializableCheck: {
ignoredActions: [ 'persist/PERSIST' ]
}
})
});
export type RootState = ReturnType < typeof store . getState >;
export type AppDispatch = typeof store . dispatch ;
export default store ;
Extend your Redux store with pre-built slices:
import { combineReducers , configureStore } from '@reduxjs/toolkit' ;
import {
authReducer ,
threadReducer ,
transactionReducer ,
chatReducer ,
profileReducer
} from 'solana-app-kit' ;
// Combine with existing reducers
const rootReducer = combineReducers ({
// Solana App Kit reducers
auth: authReducer ,
thread: threadReducer ,
transaction: transactionReducer ,
chat: chatReducer ,
profile: profileReducer ,
// Your custom reducers
myCustomFeature: myCustomReducer ,
anotherFeature: anotherReducer ,
});
// Create store with combined reducers
const store = configureStore ({
reducer: rootReducer ,
middleware : ( getDefaultMiddleware ) =>
getDefaultMiddleware ({
serializableCheck: {
ignoredActions: [ 'persist/PERSIST' ]
}
})
});
export type RootState = ReturnType < typeof store . getState >;
export type AppDispatch = typeof store . dispatch ;
export default store ;
Use authentication actions and selectors:
import {
loginSuccess ,
logoutSuccess ,
updateUsername ,
updateProfilePic ,
fetchUserProfile
} from 'solana-app-kit' ;
import { useAppDispatch , useAppSelector } from './hooks' ;
function UserProfile () {
const dispatch = useAppDispatch ();
const { user , isAuthenticated , loading } = useAppSelector ( state => state . auth );
const handleLogin = async ( userData ) => {
dispatch ( loginSuccess ( userData ));
};
const handleUpdateProfile = async ( updates ) => {
if ( updates . username ) {
dispatch ( updateUsername ({
userId: user . id ,
newUsername: updates . username
}));
}
if ( updates . profilePic ) {
dispatch ( updateProfilePic ( updates . profilePic ));
}
};
const handleLogout = () => {
dispatch ( logoutSuccess ());
};
return (
< View >
{ isAuthenticated ? (
< UserProfileView
user = { user }
onUpdate = { handleUpdateProfile }
onLogout = { handleLogout }
/>
) : (
< LoginComponent onLogin = { handleLogin } />
) }
</ View >
);
}
Manage transaction state and priority fees:
import {
setSelectedFeeTier ,
setTransactionMode ,
selectFeeTier ,
selectTransactionMode
} from 'solana-app-kit' ;
function TransactionSettings () {
const dispatch = useAppDispatch ();
const feeTier = useAppSelector ( selectFeeTier );
const transactionMode = useAppSelector ( selectTransactionMode );
const handleFeeTierChange = ( tier ) => {
dispatch ( setSelectedFeeTier ( tier ));
};
const handleModeChange = ( mode ) => {
dispatch ( setTransactionMode ( mode ));
};
return (
< View >
< FeeSelector
selectedTier = { feeTier }
onTierChange = { handleFeeTierChange }
/>
< ModeSelector
selectedMode = { transactionMode }
onModeChange = { handleModeChange }
/>
</ View >
);
}
Advanced Integration Patterns
Custom Hook Integration
Create custom hooks that leverage Solana App Kit functionality:
import { useWallet , useSwap , useFetchTokens } from 'solana-app-kit' ;
import { useState , useEffect } from 'react' ;
function usePortfolioManagement () {
const { wallet , connected } = useWallet ();
const { executeSwap } = useSwap ();
const { tokens , loading , refetch } = useFetchTokens ( wallet ?. address );
const [ totalValue , setTotalValue ] = useState ( 0 );
useEffect (() => {
if ( tokens . length > 0 ) {
const value = tokens . reduce (( sum , token ) => sum + ( token . value || 0 ), 0 );
setTotalValue ( value );
}
}, [ tokens ]);
const rebalancePortfolio = async ( targetAllocations ) => {
const results = [];
for ( const allocation of targetAllocations ) {
try {
const result = await executeSwap (
allocation . from ,
allocation . to ,
allocation . amount
);
results . push ( result );
} catch ( error ) {
console . error ( 'Rebalance failed for' , allocation , error );
}
}
await refetch (); // Refresh portfolio
return results ;
};
return {
tokens ,
totalValue ,
loading ,
connected ,
rebalancePortfolio ,
refetch
};
}
// Usage in component
function PortfolioScreen () {
const {
tokens ,
totalValue ,
loading ,
rebalancePortfolio
} = usePortfolioManagement ();
return (
< View >
< Text > Portfolio Value: $ { totalValue . toFixed ( 2 ) } </ Text >
< TokenList tokens = { tokens } loading = { loading } />
< RebalanceButton onRebalance = { rebalancePortfolio } />
</ View >
);
}
Context Provider Pattern
Wrap your app with multiple providers for enhanced functionality:
import React from 'react' ;
import {
CustomizationProvider ,
WalletProvider ,
NotificationProvider
} from 'solana-app-kit' ;
function AppProviders ({ children }) {
return (
< CustomizationProvider config = { appConfig } >
< WalletProvider autoConnect = { true } >
< NotificationProvider >
< Provider store = { store } >
{ children }
</ Provider >
</ NotificationProvider >
</ WalletProvider >
</ CustomizationProvider >
);
}
function App () {
return (
< AppProviders >
< NavigationContainer >
< MainNavigator />
</ NavigationContainer >
</ AppProviders >
);
}
Best Practices
Performance Optimize rendering by using React.memo for expensive components and implementing proper key props for lists
Error Handling Implement error boundaries around kit components and handle network failures gracefully
State Management Use selectors efficiently and avoid unnecessary re-renders by selecting only needed state slices
Security Validate transactions before execution and implement proper user confirmation flows
Next Steps