Expo Plugin
Build plugin for Expo projects. Bundles your Expo app using Expo's native export command.
Installation
npm install @hot-updater/expo --save-devConfiguration
interface ExpoPluginConfig {
outDir?: string; // Output directory (default: "dist")
sourcemap?: boolean; // Generate sourcemaps (default: false)
resetCache?: boolean; // Reset Metro cache before bundling (default: true)
}Usage
import { expo } from '@hot-updater/expo';
import { defineConfig } from 'hot-updater';
export default defineConfig({
build: expo({
sourcemap: false
}),
// ... other config
});Expo Configuration
Add the plugin to your app.json file as shown below:
{
"expo": {
"plugins": [
[
"@hot-updater/react-native",
{
"channel": "production"
}
]
]
}
}Run prebuild to apply the changes:
npx expo prebuildExpo DOM Components (use dom)
Note: This setup is only required for Expo SDK < 55. Expo SDK 55+ includes native
overrideUrisupport (PR #40397).
Expo DOM components are designed for EAS Update. Hot Updater uses overrideUri internally (via Babel plugin) to redirect DOM components to the correct bundle path.
Babel plugin
Add the Babel plugin only when you use Expo DOM components:
npx expo customize babel.config.jsmodule.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: [
'@hot-updater/expo/babel-plugin',
],
};Apply patch
Modify node_modules/expo/src/dom/dom.types.ts:
export interface DOMProps extends Omit<RNWebViewProps, 'source'> {
/**
* Whether to resize the native WebView size based on the DOM content size.
* @default false
*/
matchContents?: boolean;
/**
* Whether to use the `@expo/dom-webview` as the underlying WebView implementation.
* @default false
*/
useExpoDOMWebView?: boolean;
+
+ /**
+ * Allows dynamically redirecting a component to a different source, for example a prebuilt version.
+ * @internal
+ */
+ overrideUri?: string;
}Modify node_modules/expo/build/dom/dom.types.d.ts:
export interface DOMProps extends Omit<RNWebViewProps, 'source'> {
/**
* @default false
*/
matchContents?: boolean;
/**
* Whether to use the `@expo/dom-webview` as the underlying WebView implementation.
* @default false
*/
useExpoDOMWebView?: boolean;
+ /**
+ * Allows dynamically redirecting a component to a different source, for example a prebuilt version.
+ * @internal
+ */
+ overrideUri?: string;
}Modify node_modules/expo/src/dom/webview-wrapper.tsx:
const RawWebView = React.forwardRef<object, Props>((props, ref) => {
- const { children, dom, filePath, ref: _ref, ...marshalProps } = props as Props;
+ const { children, dom: domProps, filePath, ref: _ref, ...marshalProps } = props as Props;
+ const { overrideUri, ...dom } = domProps || {};
if (__DEV__) {
if (children !== undefined) {
throw new Error( const webView = resolveWebView(dom?.useExpoDOMWebView ?? false);
const webviewRef = React.useRef<WebViewRef>(null);
const domImperativeHandlePropsRef = React.useRef<string[]>([]);
- const source = { uri: `${getBaseURL()}/${filePath}` };
+ const source = { uri: overrideUri ?? `${getBaseURL()}/${filePath}` };
const [containerStyle, setContainerStyle] = React.useState<WebViewProps['containerStyle']>(null);Persist changes
Use patch-package, yarn patch, or pnpm patch to persist these changes across installs.
Using patch-package:
npm install patch-package --save-devnpx patch-package expoAdd postinstall script:
{
"scripts": {
"postinstall": "patch-package"
}
}Using pnpm patch:
pnpm patch expo
# Make the changes above, then:
pnpm patch-commit <path-shown-in-output>Using yarn patch:
yarn patch expo
# Make the changes above, then follow yarn's instructionsOnce configured, the Babel plugin automatically handles overrideUri for all DOM components. No additional code changes required.
Key Features
- Uses Expo's
expo export:embedcommand - Auto-detects Hermes from app.json configuration
- Supports both managed and bare Expo workflows
- Compatible with Expo prebuild for native builds
- Automatically configures bundler based on Expo settings