For years, the answer to "Can I build a mobile app with Angular?" came in two flavors. Wrap your web app in a WebView (Ionic with Capacitor), or use NativeScript for native UI. Anything else meant switching to React Native.
A new open-source project, Angular Native (ng-native), proposes a third route: keep Angular's programming model, render through React Native's Fabric renderer, and ship with Expo. This article covers what it is, how it works internally, what does not work yet, and a framework for deciding whether to adopt it.
A quick disclaimer up front: it is independent, it is labeled alpha, and it is not affiliated with Google, the Angular team or Expo.
Angular Native renders Angular components as real
UIViews and AndroidViews via React Native's Fabric renderer. React is not in the render path.You write standalone components, signals, Signal Forms and
@angular/router, and build, run and ship with Expo.Requirements: Angular 22, Expo SDK 57, React Native 0.86 (New Architecture) and Node 22.18+.
It is alpha. Real gaps exist: no DOM, no
@angular/animations, partial i18n, anHttpClientgotcha.Good for prototypes and Angular-heavy teams exploring native. For a store-bound production app today, React Native with Expo remains the lower-risk choice.
The basics
What is it? A renderer and toolchain that lets Angular components draw native iOS and Android views. Expo handles project creation, hot reload, native builds and store submission.
Who made it? It lives under the ng-native organization on GitHub. The README lists a few contributors (erKam, Chau Tran and Stavros Thalassinos), but I could not identify a named founder or sponsoring company. Treat it as a small community project and evaluate the bus factor accordingly.
Is it official? No. The project says so explicitly.
How do I try it?
bash
npx create-expo-app@latest my-app --template @ng-native/template
cd my-app && npx expo startScan the QR code with Expo Go, or press i for the iOS simulator or a for Android. Edit the root component and it hot reloads.
A component looks like regular Angular with native elements instead of HTML:
ts
@Component({
selector: 'app-root',
imports: [Pressable, Text],
template: `
<pressable (press)="count.set(count() + 1)">
<text>Tapped {{ count() }} times</text>
</pressable>
`,
})
export class App {
count = signal(0);
}How it works
Angular components never manipulate the DOM directly. They go through Renderer2, and @angular/platform-browser is simply one implementation of that interface. Angular Native supplies another.
Angular components
↓ Renderer2 calls
Retained tree (@ng-native/fabric)
↓ one commit per change-detection pass
Fabric (C++ diff, off the JS thread)
↓
UIView / android.view.ViewThree design decisions matter for senior engineers evaluating it.
1. Incremental commits. The engine records individual renderer calls (create, set prop, move) and commits at most once per change-detection pass. Unchanged subtrees return to Fabric by reference, so large lists are not rebuilt on every update. Fabric then diffs the new root against the screen in C++.
2. Zoneless by design. The bootstrap always enables zoneless change detection. There is no option to add zone.js. Because Angular 21 made zoneless the default for web, this fits the direction of the framework, but it also means non-signal mutations that zone.js would have caught can silently stop updating.
3. A CSS engine built for native. Native has no CSS engine, and Angular's styles are normally consumed by platform-browser. Angular Native compiles component stylesheets at build time with lightningcss and resolves matching, specificity and inheritance at runtime. It also emulates text-property inheritance that React Native lacks. The scope rule is explicit: if React Native can express it, CSS gets a spelling for it, and if not, the build drops it and warns. ::before, ::after, grid, table layout, position: fixed and position: sticky are permanently unsupported.
Routing builds on @angular/router with native stack outlets backed by react-native-screens, giving native transitions, back gestures, guards, resolvers, lazy routes and deep links. Screens lower in the stack stay mounted, so scroll position and text input state survive navigation.
The repo is split into focused packages: platform (renderer and bootstrap), components (native elements), router, device, expo (Expo modules as injectable services), icons, metro, tailwind, testing and web, plus Angular CLI and Nx generators. A @ng-native/web package renders the same components to the DOM, and the testing package runs components in Node against a fake Fabric, with no simulator.
The Expo side
Expo supplies the native tooling, and its current state shapes what you can do.
Expo SDK 57 was released on June 30, 2026. It is a deliberately small release that brings React Native 0.86 to Expo, with React staying at 19.2.
New Architecture only. Since React Native 0.82, the New Architecture is always enabled and cannot be turned off, which is what Fabric-based renderers like this one depend on.
Hermes V1 regression. The initial SDK 57 releases inherited a memory regression affecting apps that import Reanimated or worklets. Fixes landed in later 57.x patch releases, so pin to a recent patch version.
Native APIs reach Angular through @ng-native/expo, which wraps Expo modules (camera, location, notifications, secure storage, file system, SQLite, biometrics, maps, haptics and more) as injectable services. Any Expo native view can be registered as an element with registerExpoView.
Shipping
Expo Go covers most day-to-day development.
Development builds with
expo-dev-clientare needed once you add your own native code.The
ios/andandroid/folders are generated fromapp.jsonviaexpo prebuild. Builds run locally (expo run:ios,expo run:android) or in the cloud with EAS Build.Release builds minify the bundle and strip Angular's dev-mode assertions. Submission uses
eas submit.
It is the standard Expo pipeline, which is a large part of the appeal.
How it compares
OptionRenderingLanguage / ecosystemBest fitAngular NativeNative views via FabricAngular + Expo modulesAngular teams exploring nativeReact Native + ExpoNative views via FabricReact, largest ecosystemProduction apps, React teamsNativeScriptNative views, direct API bindingsAngular supported, smaller ecosystemDirect access to unwrapped native SDKsIonic + CapacitorWebView (DOM)Angular first-class, matureWeb apps that need installationFlutterOwn pixels (Impeller)DartPixel-identical UI across platforms
Two notes. First, NativeScript's Angular integration is actively maintained and, according to ng-native's own comparison page, tracks Angular 22. Verify this on npm before committing. Second, the ng-native docs carry no benchmarks or speed claims, and neither should you assume any.
Known limitations
The project documents its gaps honestly. The ones most likely to affect you:
No DOM.
document,window,DomSanitizerandNgOptimizedImageare unavailable. Use native elements and@ng-native/devicefor capabilities browsers expose onwindow.No
@angular/animations. Useanimate.enterandanimate.leave, or Reanimated worklets for gesture-driven motion.The
HttpClienttrap. PlainprovideHttpClient()silently returns null bodies on a device, because React Native'sfetchhas no readableresponse.bodystream. You must useprovideNativeHttpClient().Partial i18n. ICU plurals and selects fail in the template compiler,
i18n-attributes lose their source text, and switching language requires an app reload.No SSR or hydration, and Angular DevTools cannot attach.
Toolchain bugs. Two
@oxc-angular/viteissues affect templates and decorator metadata (method shorthand, and arrow functions that read their own parameter). The project catches both at build time and documents workarounds.Hot reload needs a full reload for some component
.tschanges.
The project also distinguishes implemented from verified. Many platform wrappers have unit tests and type checks but no hardware verification, and release builds have been run on the iOS simulator and Android emulator. The docs describe the current state as a working prototype. At the time of writing the repository had only a few dozen stars.
A decision framework
Choose Angular Native when:
You have an Angular team that wants native views without learning React.
You are building a prototype, internal tool or proof of concept.
You want to reuse Angular patterns (DI, signals, router) and accept alpha risk.
Choose React Native + Expo when:
The app is headed to the stores with real users and support obligations.
You need the broadest plugin ecosystem and the most battle-tested tooling.
Choose NativeScript when you want to stay in Angular for production and need direct access to native SDKs without wrappers.
Choose Ionic + Capacitor when you already have an Angular web app and want installability with minimal rework.
If you evaluate it, test these first
Your three most critical native modules, on a real device, not just a simulator.
Network layer behavior with
provideNativeHttpClient()and your interceptors.Long-list scroll performance and memory on a mid-range Android device.
Your animation requirements against the Reanimated path.
i18n needs, especially plurals.
Upgrade path: the project pins to Angular 22 and Expo SDK 57, so budget for tracking both.
Final thoughts
Angular Native does not replace anything today. What it demonstrates is that Angular's renderer abstraction is flexible enough to drive a native UI with no DOM and no WebView. That is the same architectural instinct behind Angular's move toward a Rust-based compiler: the framework's core ideas are portable, and the tooling around them is changing fast.
Watch it, prototype with it, and let real-device results, not README promises, decide whether it earns a place in production.
Sources
Angular Native repository: github.com/ng-native/ng-native
Angular Native documentation: ng-native.com (Architecture, Deployment, Known limitations, Angular Native compared)
Expo SDK 57 changelog: expo.dev/changelog/sdk-57
React Native's New Architecture (Expo docs): docs.expo.dev/guides/new-architecture
Angular release information: angular.dev and blog.angular.dev
NativeScript: nativescript.org
Ionic and Capacitor: ionic.io/blog
