Hot Reloading - Live UI Updates for Anchor Program Changes
Overview
Section titled “Overview”Hot Reloading keeps your testing UI synchronized with your Solana program code in real-time. When you make changes and rebuild your program with anchor build, Testship automatically detects the IDL updates via WebSocket and refreshes the interface - no manual restarts, no page refreshes, no setup required.
How It Works
Section titled “How It Works”WebSocket-Based File Watching
Section titled “WebSocket-Based File Watching”Testship uses a sophisticated setup for instant updates:
Server Side (Node.js)
chokidarwatches your IDL file (target/idl/*.json)- Ignores initial file state (no false triggers on startup)
- Detects actual file changes in real-time
- WebSocket Server broadcasts
IDL_UPDATEDmessage to all connected clients
Client Side (React)
- WebSocket client connects on page load
- Listens for
IDL_UPDATEDmessages - Automatically refetches IDL from server
- Updates React state triggering UI re-render
When you run anchor build, here’s what happens:
- ✅ IDL file changes (e.g.,
target/idl/my_program.json) - ✅ Chokidar detects the change instantly
- ✅ Server sends WebSocket message:
"IDL_UPDATED" - ✅ Client receives message
- ✅ Client re-fetches IDL via HTTP
- ✅ React state updates
- ✅ UI re-renders with new instructions/accounts
- ✅ Total time: ~500ms ⚡
Seamless Updates
Section titled “Seamless Updates”The hot reload process is buttery smooth:
- ✅ No page refresh - Pure React state update
- ✅ Form data preserved - localStorage keeps your inputs
- ✅ Account history intact - Saved accounts remain available
- ✅ Transaction history maintained - Past transactions still visible
- ✅ WebSocket reconnection - Auto-reconnects if connection drops
- ✅ Debounced reloads - Waits 500ms to batch multiple changes
Development Workflow
Section titled “Development Workflow”Traditional Workflow (Without Testship)
Section titled “Traditional Workflow (Without Testship)”- Make code changes to your program
- Run
anchor build(30-60s) - Stop your test script
- Restart test environment
- Reconfigure test accounts
- Re-enter test parameters
- Execute test
- Repeat…
- ⏱️ 3-5 minutes per iteration
With Testship Hot Reloading
Section titled “With Testship Hot Reloading”- Make code changes to your program
- Run
anchor build(30-60s) - UI updates automatically ✨
- Continue testing immediately
- ⏱️ ~1 minute per iteration
Real Example
Section titled “Real Example”Let’s say you’re adding a new instruction:
// Add this to your programpub fn new_feature(ctx: Context<NewFeature>, amount: u64) -> Result<()> { // implementation Ok(())}With Testship:
- Add code
anchor build- Wait ~30-60s for build
- Boom! New instruction appears in UI automatically
- Fill form, test immediately
- Total time: ~1 minute
Without Testship (traditional):
- Add code
anchor build- Stop test script
- Modify test file
- Add accounts
- Add test parameters
- Run test
- Total time: 3-5 minutes
That’s a 3-5x speed improvement per iteration! 🚀
What Gets Updated
Section titled “What Gets Updated”Intelligent UI Updates
Section titled “Intelligent UI Updates”Testship smartly handles different types of changes:
✅ New Instructions
- Appear in search dropdown automatically
- Form generated instantly when selected
- Ready to test immediately
- No page refresh needed
✅ Modified Instructions
- Updated parameter fields appear
- Changed account requirements reflected
- Previous form data preserved if compatible
- Automatic type conversion where possible
✅ Removed Instructions
- Disappear from search
- If currently selected, shows “instruction not found”
- No crashes or errors
✅ Type Changes
- Input validation updates automatically
- Number ranges adjust (u8 → u64, etc.)
- Account requirements update (signer badges, etc.)
State Preservation
Section titled “State Preservation”During hot reload, Testship automatically preserves:
- ✅ Connected wallet - No need to reconnect
- ✅ Selected cluster - Stays on devnet/mainnet/local
- ✅ Form data - Your inputs remain (via localStorage)
- ✅ Account suggestions - Saved addresses persist
- ✅ Transaction history - Past transactions remain visible
- ✅ UI preferences - Dark mode, panel sizes, etc.
No Notifications
Section titled “No Notifications”Hot reloading is silent by design:
- Updates happen seamlessly in the background
- No intrusive popups or toasts
- Console log shows “IDL updated, refreshing…” for debugging
- You’ll notice changes when you interact with the UI
Technical Details
Section titled “Technical Details”WebSocket Connection
Section titled “WebSocket Connection”Server (Node.js + ws)
const wss = new WebSocketServer({ server: httpServer });const clients = new Set();
wss.on("connection", (ws) => { clients.add(ws); ws.on("close", () => clients.delete(ws));});
// On IDL changewatcher.on("change", () => { clients.forEach((client) => { if (client.readyState === WebSocket.OPEN) { client.send("IDL_UPDATED"); } });});Client (React + Custom Hook)
useWebSocket({ url: "ws://localhost:3000", onMessage: (message) => { if (message === "IDL_UPDATED") { debouncedRefresh(); // Fetches new IDL after 500ms } }, onClose: () => { // Auto-reconnects with exponential backoff },});Debouncing Strategy
Section titled “Debouncing Strategy”To avoid excessive reloads during rapid changes:
- 500ms debounce timer - Multiple changes batched
- Only IDL changes trigger reload - Not every file save
- Ignores initial file state - No false reload on startup
- Waits for build completion - No partial IDL reads
Reconnection & Error Handling
Section titled “Reconnection & Error Handling”Automatic Reconnection
Section titled “Automatic Reconnection”If WebSocket connection drops:
- Exponential backoff - Waits longer between retries
- Max 5 attempts - Avoids infinite reconnect loops
- 3-second delay - Base reconnection interval
- Console logs - Shows connection status for debugging
Error Recovery
Section titled “Error Recovery”If IDL reload fails:
- Silent failure - Doesn’t crash the UI
- Console error - Logs the error for debugging
- Manual refresh - User can press Ctrl+R
- Retry button - “Refresh IDL” button in UI (if available)
Connection Status
Section titled “Connection Status”Check WebSocket status:
- Open browser console
- Look for: “WebSocket connected” or “Attempting to reconnect…”
- Connection count updates show active clients
Troubleshooting
Section titled “Troubleshooting”Hot Reload Not Working?
Section titled “Hot Reload Not Working?”1. Check WebSocket Connection
Open browser console → Look for:✅ "WebSocket connected"❌ "WebSocket error" or "Attempting to reconnect..."2. Verify IDL File Exists
ls target/idl/*.json # Should show your program's IDL3. Check Server Logs
Terminal running testship start should show:"IDL file changed: /path/to/target/idl/program.json"4. Manual Refresh
- Press Ctrl+R (Cmd+R on Mac) to manually reload
- Or restart Testship:
testship start
5. Clear Browser Cache
- Hard refresh: Ctrl+Shift+R (Cmd+Shift+R on Mac)
- Clear localStorage: Console →
localStorage.clear()
Real-World Use Cases
Section titled “Real-World Use Cases”1. Rapid Prototyping
Section titled “1. Rapid Prototyping”Add instruction → anchor build → Test immediately → IteratePerfect for experimenting with program design without the overhead of test scripts.
2. Bug Fixing
Section titled “2. Bug Fixing”Find bug → Fix code → anchor build → Verify fix → DoneFastest way to validate fixes - see results in seconds, not minutes.
3. Feature Development
Section titled “3. Feature Development”Build feature → anchor build → UI appears → Test with wallet → Ship itSmooth development flow that keeps you in the zone.
4. Learning Solana
Section titled “4. Learning Solana”Tweak parameters → anchor build → See effects → Understand betterBest way to learn how Solana programs work - instant visual feedback.
Performance Metrics
Section titled “Performance Metrics”Based on actual usage:
- File Watch Latency: < 50ms (chokidar is fast!)
- WebSocket Message: < 10ms
- IDL Fetch: 50-100ms
- React Re-render: 100-200ms
- Total Reload Time: ~200-400ms ⚡
Why So Fast?
Section titled “Why So Fast?”- No full page reload - Only React state updates
- Optimized WebSocket - Binary protocol, minimal overhead
- Smart debouncing - Batches multiple changes
- Local file watching - No network latency
Best Practices
Section titled “Best Practices”✅ Do This
Section titled “✅ Do This”- Keep Testship running - It’s lightweight, leave it open
- Build frequently - Small iterations catch errors early
- Watch console - Useful for debugging connection issues
- Use keyboard shortcuts - Ctrl+K for quick instruction search
❌ Avoid This
Section titled “❌ Avoid This”- Don’t manually refresh - Hot reload handles it automatically
- Don’t restart Testship - Unless you need to change ports
- Don’t clear localStorage unnecessarily - You’ll lose form data
Next Steps
Section titled “Next Steps”Learn how to share your testing sessions in Session Sharing.