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 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:
- Android widgets are opt-in. Set enableAndroid to true in the config plugin, and set android.package in your app config.
- Layouts use @expo/ui/jetpack-compose instead of SwiftUI, and each widget is registered with the same createWidget call.
- updateSnapshot works on both platforms. On Android it is the way to change what the widget shows.
- Each widget runs its own JavaScript bundle on a dedicated Hermes runtime, so its layout cannot use hooks, fetch or anything from your app.
- The environment argument provides only colorScheme on Android.
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-widgetsTurn 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:androidTo 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-widgetThe 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
- Is it a development build, not Expo Go? Expo Go does not include expo-widgets.
- Is the app on SDK 58? The SDK 57 docs list iOS only.
- Did you set enableAndroid and android.package, then run prebuild and rebuild?
- Does the name match in the plugin entry and in createWidget? Expo uses it as the Kotlin class name, so no spaces or dashes.
- Does every component come from the Compose list? Anything else shows View not found.
- Are the constants declared inside the widget function?
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
- Unistyles 3 with Expo: a working setup
- Expo environment variables: which are public?
- TanStack Query in Expo: offline and refetch
- Expo zustand: persist a store across restarts
- jest-expo setup, Expo Router tests and fixes
- Expo auth: Clerk vs Supabase vs Better Auth
- AsyncStorage vs MMKV vs expo-sqlite/kv-store
- Expo i18n: i18next or Lingui, compared
- Tamagui in Expo: setup, styling and themes
- Best paywall tools for Expo in 2026
- Expo widgets on iOS: a working setup
- RevenueCat subscriptions in an Expo Router app
- Supabase auth in Expo: email, Apple and Google
- Expo push notifications: setup, token, testing
- Expo Go vs development build: limitations
- The best Expo boilerplates, compared