12 Nov 2026 · 6 min read

Expo android widgets: expo-widgets on SDK 58

expo-widgets on Android in SDK 58: enableAndroid, Jetpack Compose layouts, what stays iOS only, and react-native-android-widget as the alternative.

Expo's widgets library, expo-widgets, builds home-screen widgets for Android as well as iOS. The SDK 58 docs list both platforms for the package. The SDK 57 docs list iOS only, and the iOS guide follows them. This post covers the Android side: what Expo documents today, what is still iOS only, how to set up an Android widget, and the alternative if you cannot move to SDK 58 yet.

If you have not set up the iOS widget, start with Expo widgets on iOS: a working setup. Both platforms use the same config plugin and the same createWidget call. The layout language is different, and that is most of the work.

What runs where on AndroidYour app calls updateSnapshot with plain props. The widget bundle, which runs in its own Hermes runtime, renders a Jetpack Compose layout into the Android home screen widget. Below, Android supports updateSnapshot; timelines, configurable widgets and Live Activities are iOS only.Your app (JS)updateSnapshot(props)Widget bundleown Hermes runtimeHome screenAndroid widgetlayout: @expo/ui/jetpack-composeAndroidupdateSnapshotenvironment.colorScheme onlyiOS onlytimelines, configurable widgets,Live Activities

What Expo documents for Android today

Android arrived in SDK 58, which Expo released on 15 October 2026. The SDK 58 changelog says expo-widgets adds an Android implementation, and the SDK 58 docs list Android and iOS as its platforms. The docs describe the Android side like this:

Expo Go does not include the package, so Android widgets need a development build as well.

What is still iOS only

Expo's docs list three features as iOS only: timelines (updateTimeline and getTimeline), configurable widgets, and Live Activities on the Lock Screen and in the Dynamic Island. The docs give no date for any of them on Android, so plan the Android widget around updateSnapshot. Interactions are a different case. The changelog says Android widgets support them, and Button is on the Android component list.

Set up an Android widget with expo-widgets

Start on SDK 58. The ReadyNative template is on SDK 57 today, so the first step is a full Expo SDK upgrade. Then install the package the way you install any Expo library:

npx expo install expo-widgets

Turn Android on in the plugin, and keep the ios block in each widget entry. The docs warn that a widgets entry without supportedFamilies generates an invalid widget target that fails to build. The android block points at the Compose layout, which goes in its own file: the SwiftUI file from the iOS guide would render the text "View not found" on Android.

// app.config.ts (inside the expo object)
android: { package: "com.example.myapp" },
plugins: [
  ["expo-widgets", {
    enableAndroid: true,
    widgets: [{
      name: "AppWidget",
      displayName: "At a glance",
      description: "The number that matters, on your Home Screen.",
      ios: { supportedFamilies: ["systemSmall", "systemMedium"] },
      android: { initialLayout: "src/widgets/app-widget-android.tsx" },
    }],
  }],
],

Write the layout in that file. It registers with createWidget under the name from the plugin entry:

// src/widgets/app-widget-android.tsx
import { Column, Text } from "@expo/ui/jetpack-compose";
import { fillMaxSize, paddingAll } from "@expo/ui/jetpack-compose/modifiers";
import { createWidget } from "expo-widgets";

const AppWidget = (props: { title: string; value: string }) => {
  "widget";
  return (
    <Column modifiers={[fillMaxSize(), paddingAll(16)]}>
      <Text>{props.title}</Text>
      <Text>{props.value}</Text>
    </Column>
  );
};

export default createWidget("AppWidget", AppWidget, { title: "Almaty", value: "21°" });

Send data from the app. Pass every prop the layout reads:

import AppWidget from "@/widgets/app-widget-android";

AppWidget.updateSnapshot({ title: "Almaty", value: "21°" });

Rebuild, because the config changed. Prebuild regenerates the Android project, and the config plugin then adds an Android widget for each entry in widgets:

npx expo prebuild
npx expo run:android

To add the widget, touch and hold the home screen, select Widgets, and add the widget for your app.

What an Android layout can use

The layout runs in the isolated widget runtime, so the rules from the iOS guide apply: no hooks, no state, no fetch, and no imports from the app. One rule catches people out. The widget cannot read anything declared outside its function, including a plain const at the top of the same file. Declare constants inside the function, or pass them as props.

Android accepts 18 Compose components from @expo/ui/jetpack-compose, including Box, Column, Row, Text, Image, Button, LazyColumn and Switch. It accepts 12 modifiers from @expo/ui/jetpack-compose/modifiers, including padding, paddingAll, fillMaxSize, background and cornerRadius. Any other component renders the text "View not found" in the widget.

Sizes come from the android block of the plugin entry. On Android 11 and lower the default is 180 by 110 dp. On Android 12 and later it is 4 by 2 grid cells. The resize mode defaults to both. Set android to null to skip a widget on Android.

What ReadyNative does on Android

ReadyNative's widgets module sets up the iOS side only: the iOS widget target, the App Group and the widgets.update() shim. The shim loads the widget only when Platform.OS is ios, so on Android widgets.supported is false and widgets.update() does nothing. The module pins expo-widgets to ~57.0.28. Using the layout above means moving the app to SDK 58 and adding that file yourself.

The alternative: react-native-android-widget

If you cannot move to SDK 58 yet, the other option is react-native-android-widget. It is an MIT-licensed package, version 0.26.0 on npm, published on 29 October 2026. It ships an Expo config plugin, and its expo peer dependency is optional, from version 54 on.

Its layouts use React Native primitives such as FlexWidget and TextWidget, and it exports requestWidgetUpdate for updates. Its limitations page says the library draws React Native views to an image and shows that image in the widget. It also says some launchers report a widget size that differs from the real one. The library currently scales and centers the image, then calibrates the size on the first click.

npx expo install react-native-android-widget

The package has native Android code, and Expo Go only includes its bundled native modules, so make a development build. Pick it when the app stays on SDK 57 and you want React Native views. Pick expo-widgets when you can run SDK 58 and want Expo's own layouts, updateSnapshot and the Expo docs in one place.

Checklist when the Android widget does not show up

Read next: Expo widgets on iOS: a working setup for the iOS target and App Group, and Expo Go vs a development build for why both platforms need one. The option also has its ReadyNative stack page, and the reference is in the Expo Widgets module docs.

FAQ

Does expo-widgets support Android?

Yes, from SDK 58. Expo's SDK 58 docs list Android and iOS, and the SDK 57 docs list iOS only. Android widgets are opt-in: set enableAndroid to true in the config plugin and set android.package.

How do I add an Android widget to an Expo app?

Upgrade to SDK 58, run npx expo install expo-widgets, and set enableAndroid and android.package in the plugin. Write the layout with @expo/ui/jetpack-compose, then run npx expo prebuild and npx expo run:android.

Can an Android widget use SwiftUI components?

No. Android widgets use the Jetpack Compose components Expo lists from @expo/ui/jetpack-compose. Any other component, SwiftUI ones included, renders the text View not found in the widget.

Do timelines and Live Activities work on Android?

Not according to Expo's docs. Timelines, configurable widgets and Live Activities are iOS only. On Android, use updateSnapshot to change what the widget shows; the docs give no date for the rest.

What is an alternative to expo-widgets for Android?

react-native-android-widget, an MIT library with an Expo config plugin. It renders React Native views to an image for the widget. Use it if you cannot move to SDK 58 yet, and make a development build to run it.

More guides