| title | Set up Angular Native |
|---|---|
| description | Inspect an Angular Native app from a simulator, an emulator or a device, step by step. |
This guide adds the devtools to an Angular Native app. The app renders through React Native's Fabric renderer and has no DOM, so a separate overlay walks Angular Native's node tree through *Angular's debug API and reports to the standalone devtools server. For what each tab shows and the overlay options, see Angular Native.
The component tree, the signal graph, the injector tree and the pipes in use. Live@ngrx/signals and @ngrx/store state and the change log, when your app uses NgRx.
Hovering a component in the panel outlines its view on the simulator or device.
/__mcp on the devtools server. The source scanners read the app's src/.
Add @pangular-inspector/devtools and devframe. A bare React Native app also needs a URL polyfill.
Call initAngularNativeOverlay() in src/main.ts, after mount(), with the root node it returns.
Start pangular dev --no-auth in the app's folder.
Open the Angular Native apps URL the server prints. The live tabs fill once the app connects.
npm install @pangular-inspector/devtools devframepnpm add @pangular-inspector/devtools devframeyarn add @pangular-inspector/devtools devframebun add @pangular-inspector/devtools devframeThe overlay needs a WebSocket global and a standards-compliant URL. React Native provides WebSocket, and Expo provides URL, so an Expo app needs nothing more.
React Native's own URL is read-only, and the client sets the protocol of the socket URL. In a bare React Native app, add a polyfill such as react-native-url-polyfill and import it first in src/main.ts.
Start the overlay after mount() from @ng-native/platform, and pass the root node of the mounted app:
// src/main.ts
import {AppRegistry, Image, Platform, processColor} from 'react-native';
import {mount} from '@ng-native/platform';
import {getFabricUIManager, registerPlatformComponents} from '@ng-native/fabric';
import {initAngularNativeOverlay} from '@pangular-inspector/devtools/overlay-angular-native';
import {App} from './app/app.ts';
registerPlatformComponents(Platform.OS);
AppRegistry.registerRunnable('main', ({rootTag}) => {
const app = mount(Number(rootTag), App, getFabricUIManager(), {
processColor,
resolveAssetSource: (value) => Image.resolveAssetSource(value as never),
});
if (__DEV__) initAngularNativeOverlay({root: app.engine.root});
});The __DEV__ check keeps the overlay out of release builds, which have no ng debug global to read. initAngularNativeOverlay() returns a function that stops the overlay and tells the server to forget the app. See Options for baseURL, intervalMs and retryMs.
The overlay connects to http://localhost:9999/ unless you pass baseURL.
| Where the app runs | What to do |
|---|---|
| iOS simulator | Nothing. The simulator shares your machine's localhost. |
| Android emulator or USB Android device | Run adb reverse tcp:9999 tcp:9999, the same forwarding Metro uses for its own port. |
| Physical device over Wi-Fi | Pass your machine's LAN address as baseURL, such as {baseURL: 'http://192.168.1.20:9999/'}. |
A device that reaches the server over plain HTTP may need a cleartext exception for that address in Info.plist or the Android network security config.
Run the server in the app's folder, so the source scanners read its src/:
cd my-angular-native-app
npx @pangular-inspector/devtools dev --no-authThe server listens on localhost only, which the iOS simulator reaches directly and an Android emulator reaches through adb reverse. --no-auth is needed because the app cannot enter the one-time code the panel asks for. Without it, the overlay logs a warning in the Metro log that names the flag and keeps retrying.
When it is ready, the server prints the Angular Native view on its own line:
pangular v0.0.7
Panel: http://localhost:9999/
Angular Native apps: http://localhost:9999/?view=angular-native
MCP: http://localhost:9999/__mcp
A physical device over Wi-Fi reaches your machine over the network, so the server has to listen on an interface the device can reach:
npx @pangular-inspector/devtools dev --host 192.168.1.20 --no-auth--host and --no-auth, every host that can reach that address can call the devtools RPC and MCP endpoints without a code. Use it on a trusted network only, and bind to the one interface the device uses rather than 0.0.0.0.
See Standalone CLI for the other server options and Security for what --no-auth turns off.
Open http://localhost:9999/?view=angular-native on your machine. The Angular Native view shows the tabs an app on a device fills: Components, Signals, Injectors, Store and Pipes. With no app connected, it says No Angular Native app is connected.
When the app connects, the Metro log shows [pangular] Connected to the devtools server at http://localhost:9999/ and the tabs fill. Hover a component in the tree to outline its view on the device.
If the app reports to a hub (Express or the Vite plugin) instead, pick the Angular Native dock in the side rail. See Where it shows in the panel.
examples/angular-native is an Expo app wired up this way, with a root service, an @ngrx/signals store and components with signals to inspect. It is outside the pnpm workspace and installs with npm, using a tarball of the devtools package built from this repository:
cd examples/angular-native
npm run devtools:pack
npm install
npm run devtoolsnpm run devtools starts the devtools server with --no-auth on http://localhost:9999/, scanning the demo's src. In a second terminal, build and start the app:
npm run iosOn Android, forward the devtools port first:
adb reverse tcp:9999 tcp:9999
npm run androidAfter a change in packages/devtools, run npm run devtools:pack and then npm install ./pangular-inspector-devtools.tgz, since a plain npm install keeps the tarball its lockfile pins. See Angular Native demo for what each file covers.