A React Native application demonstrating communication with a local Go HTTP server using JSI and JSON-RPC 2.0.
This project showcases how to build a fast mobile application where:
- React Native handles the UI with the New Architecture (Fabric + TurboModules)
- Go runs as an embedded HTTP server providing JSON-RPC APIs
- Native modules manage the Go server lifecycle
- Business logic is handled via JSON-RPC calls over HTTP
- Node.js 18+
- Go 1.24+
- gomobile:
go install golang.org/x/mobile/cmd/gomobile@latest
- iOS: Xcode 15+, CocoaPods
- Android: Android Studio, JDK 17+
First time setup (installs gomobile and required dependencies):
cd backend
make setup
iOS:
cd backend
make ios
Android:
cd backend
make android
You can also run make help
in the backend directory to see all available targets.
iOS:
cd mobile-app
npm install
npx pod-install
npx expo run:ios
Android:
cd mobile-app
npm install
npx expo run:android
react-native-go/
├── backend/
│ ├── mobile_api.go # Mobile API for server lifecycle
│ ├── http_server.go # JSON-RPC HTTP server
│ └── Makefile
└── mobile-app/
├── src/
│ ├── NativeGoServerBridge.ts # TurboModule spec
│ ├── GoServerBridgeJSI.ts # JSI wrapper
│ └── JsonRpcClient.ts # JSON-RPC client
├── android/ # Android native code
└── ios/ # iOS native code
The native modules expose 3 synchronous methods via JSI:
interface Spec extends TurboModule {
readonly startServer: () => number;
readonly stopServer: () => boolean;
readonly getServerPort: () => number;
}
The Go backend provides a mobile API for lifecycle management:
type MobileAPI struct{}
func (m *MobileAPI) StartServer() int {
return StartHTTPServer()
}
func (m *MobileAPI) StopServer() {
StopHTTPServer()
}
func (m *MobileAPI) GetServerPort() int {
return GetHTTPServerPort()
}
And handles business logic via JSON-RPC:
func (s *HTTPServer) handleRequest(req JSONRPCRequest) JSONRPCResponse {
switch req.Method {
case "getGreeting":
case "getCurrentTime":
}
}
Start the server and make JSON-RPC calls:
import GoBridge from './GoServerBridgeJSI';
const port = GoBridge.startServer();
const client = new JsonRpcClient(`http://localhost:${port}`);
const result = await client.call('getGreeting', { name: 'World' });
To add a new endpoint, modify only the Go backend:
case "myNewMethod":
params, ok := req.Params.(map[string]interface{})
if !ok {
return s.errorResponse(req.ID, -32602, "Invalid params")
}
result := doSomething(params)
return JSONRPCResponse{JSONRPC: "2.0", Result: result, ID: req.ID}
Use from React Native:
const result = await jsonRpcClient.call('myNewMethod', { param: 'value' });
No native code changes required.
export PATH=$PATH:$(go env GOPATH)/bin
gomobile init
cd backend
make ios
cd backend
make android
- Edit backend/*.go files
- Rebuild:
cd backend && make ios
ormake android
- Rebuild app:
cd mobile-app && npx expo run:ios
ornpx expo run:android
This project is licensed under the MIT License - see the LICENSE file for details.
If this project helped you, please give it a star! ⭐
- Issues: GitHub Issues
- React Native - Learn once, write anywhere
- Expo - Platform for universal React applications
- go-mobile - Go bindings for mobile
- status-mobile - Real-world Clojure/Go integration