ump-native
v0.0.1
Published
Native components + platform glue for [UMP](https://git.n.xiaomi.com/zhoujianlin/ump). The `react-native` peer in UMP's `react` + `react-native` split.
Readme
ump-native
Native components + platform glue for UMP.
The react-native peer in UMP's react + react-native split.
Renders to a shared C++ Skia pipeline on Android, iOS, and HarmonyOS.
The browser peer lives at ump-h5-native.
Install
npm install ump-native ump-coreump-core ships the JSX runtime and hooks. With the automatic JSX
runtime (jsx: "react-jsx" + jsxImportSource: "ump-core" in
tsconfig.json), <View> and <></> resolve via
ump-core/jsx-runtime without per-file createElement/Fragment
imports. Hooks (useState, useEffect, …) are imported directly:
import { useState } from 'ump-core'.
Surface
- Layout / primitives:
View,Text,Image,ScrollView,FlatList,VirtualizedList,IndexedStack,SafeAreaView,KeyboardAvoidingView. - Inputs:
Pressable,TouchableOpacity,TextInput,Switch,RefreshControl. - Surfaces:
Modal,Dialog,BottomSheet,StatusBar,SystemBars,ActivityIndicator,Toast,Alert. - Media / canvas:
Canvas,CustomPainter,Image,MaskedView,Hero.HTMLVideoElement/HTMLMediaElement/MediaErrorstay here as the runtime backbone forump-plugin-video; audio element runtime lives inump-plugin-audio. - Text spacing:
Text,TextInput, and Canvas 2D text supportletterSpacing/wordSpacingon native and H5. Native currently treatswordSpacingas ASCII-space-only and does not fully match browser shaping for complex grapheme clusters. - Animation:
Animated,Easing,useAnimatedValue,LayoutAnimation. - Gesture:
Gesture(pan, press, scale, pinch, rotate). - Native-plugin author primitive:
createNativeViewComponent(used byump-plugin-video/ump-plugin-webviewetc.). - Platform info:
Platform,Dimensions,PixelRatio,Appearance,DeviceInfo,I18nManager,AppState,BackHandler,Keyboard,Linking. - Web standards installed onto
globalThis:fetch,Headers,Request,Response,AbortController,URL,URLSearchParams,TextEncoder,TextDecoder,EventTarget,requestAnimationFrame,setTimeout,setInterval,Blob,File,FormData,FileReader,WritableStream,TransformStream,MessageChannel,matchMedia,visualViewport,history,structuredClone,queueMicrotask,crypto.randomUUID,crypto.getRandomValues,localStorage,sessionStorage,MutationObserver,navigator.{share, clipboard, connection, geolocation, vibrate, userAgent, language, onLine}. - Moved to plugins (install separately on native):
Slider/Picker/DatePicker/ProgressBar/WebView/Video/Audio/Worker/SectionList/Reanimated/Matrix4/WebSocket/BroadcastChannel/EventSource/Notification/IntersectionObserver/ResizeObserver/PerformanceObserver/performance/indexedDB/RTCPeerConnectionfamily. Seepackages/ump-plugins/for the full list. - Optional
Intlpolyfill (installIntlPolyfill) — opt-in via the@formatjs/intl-*peer deps when running on a host without native Intl. - Build identity:
VERSION,BUILD_HASH,BUILD_CHANNEL, and a combinedversionString()helper. The values are baked in at build time byump-dev-server's esbuild config; outside the bundler (tsx --test, plain Node) the typeof-guards fall through to'0.0.0'/''/'unknown'. Useful for crash reports, "About" panels, and the RedBox header.
Usage
import { AppRegistry, View, Text, StyleSheet } from 'ump-native';
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', alignItems: 'center' },
});
function App() {
return (
<View style={styles.container}>
<Text>UMP works.</Text>
</View>
);
}
AppRegistry.registerComponent('MyApp', () => App);
AppRegistry.runApplication('MyApp');See the main README for the full component matrix and platform support.
Error reporting
globalThis.addEventListener('error' | 'unhandledrejection', cb) works on
all platforms (web standard shape). Use it to forward uncaught errors to
your own reporter — UMP doesn't ship Sentry/Bugsnag bindings; you wire
whatever you want.
globalThis.addEventListener('error', (e) => {
// e: ErrorEvent { error, message, filename, lineno, colno }
fetch('/log/error', {
method: 'POST',
body: JSON.stringify({
message: e.message,
stack: e.error && (e.error as Error).stack,
file: e.filename, line: e.lineno, col: e.colno,
}),
});
});
globalThis.addEventListener('unhandledrejection', (e) => {
// e: PromiseRejectionEvent { reason, promise }
const reason = e.reason as any;
fetch('/log/rejection', {
method: 'POST',
body: JSON.stringify({
message: reason?.message ?? String(reason),
stack: reason?.stack,
}),
});
});Sources covered:
- Synchronous
throwoutside any try/catch →'error' - Promise rejection with no
.catch→'unhandledrejection' - Render-phase throw caught by
<ErrorBoundary>→ also'error'(so a single listener sees boundary catches too)
You can also dispatch from app code if you want:
import { dispatchError } from 'ump-native';
try { riskyThing(); } catch (e) { dispatchError(e); }License
MIT — see LICENSE.
