Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 0 additions & 25 deletions apps/notification-tester/app.config.ts

This file was deleted.

2 changes: 2 additions & 0 deletions docs/pages/build/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ EAS Build is also designed to work for any native project, whether or not you us

## Quick start

> **info** The `eas` commands below require EAS CLI. See [How to install EAS CLI](/eas/cli/#installation) for more information.

To build your app, run the following command:

<Terminal cmd={['$ eas build --platform all']} />
Expand Down
52 changes: 28 additions & 24 deletions docs/pages/debugging/runtime-issues.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Whether you're developing your app locally, sending it out to select beta tester

Let's go through recommended practices when dealing with each of the above situations.

> **info** Already familiar with React Native debugging? See [Debugging tools](/debugging/tools/) for Expo-specific tooling like React Native DevTools and the built-in profiler.

## Development errors

They are common errors that you encounter while developing your app. Delving into them isn't always straightforward. Usually, debugging when running your app with [Expo CLI](/more/expo-cli/) is enough.
Expand Down Expand Up @@ -99,42 +101,29 @@ You can now utilize [**Low-level debugger (LLDB)**](https://developer.apple.com/

</Step>

> You can delete the **ios** directory when you are done with this process. This ensures that your project remains managed by Expo CLI. Keeping the directory around and manually modifying it outside of `npx expo prebuild` means you'll need to manually upgrade and configure native libraries yourself.

## Production errors

Errors or bugs in your production app can be much harder to solve, mainly because you have less context around the error (that is, where, how, and why did the error occur?).
> You can delete or gitignore the **ios** directory when you are done with this process. This ensures that your project remains managed by Expo CLI. Keeping the directory around and manually modifying it outside of `npx expo prebuild` means you'll need to manually upgrade and configure native libraries yourself.

**The best first step in addressing a production error is to reproduce it locally.** Once you reproduce an error locally, you can follow the [development debugging process](#development-errors) to isolate and address the root cause.
## Viewing native logs

> **info** **Tip**: Sometimes, running your app in **production mode** locally will show errors that normally wouldn't be thrown. You can run the app locally in production by running `npx expo start --no-dev --minify`.
> `--no-dev` tells the server not to be run in development mode, and `--minify` is used to minify your code the same way it is for production JavaScript bundles.

### Production app is crashing

It can be a frustrating scenario when a production app crashes. There is very little information to look into when it happens. It's important to reproduce the issue, and even if you can't do that, to find any related crash reports.

Start by reproducing the crash using your production app and then **find an associated crash report**. For Android, you can use `adb logcat` and for iOS you can use the Console app in Xcode.
When your app crashes or behaves unexpectedly, the JavaScript error output doesn't always tell the full story. Native logs from Android and iOS can reveal crash reasons, native module errors, and system-level warnings that don't surface in the Metro bundler or React Native DevTools.

<VideoBoxLink
videoId="LvCci4Bwmpc"
title="How to use Logcat & macOS Console to debug"
title="How to use ADB Logcat & macOS Console to debug"
description="In this tutorial, you'll learn how to use native device logging features like ADB Logcat and macOS Console to find bugs in your code and quickly fix them."
/>

#### Crash reports using adb logcat
### Android: adb logcat

If your Android app is on Google Play, refer to the crashes section of the [Google Play Console](https://play.google.com/console/about/), or connect your Android device to your computer and run the following command:
Connect your Android device (or use an emulator) and run the following command:

<Terminal cmd={['$ adb logcat']} />

The Android Debug Bridge (`adb`) program is part of the Android SDK and allows you to view streaming logs. An alternative to avoid installing Android SDK is to use [WebADB](https://webadb.com/) in Chrome.

#### Crash reports using Console app
The Android Debug Bridge (`adb`) program is part of the Android SDK and allows you to view streaming logs. An alternative to avoid installing the Android SDK is to use [WebADB](https://webadb.com/) in Chrome.

If your iOS app is on TestFlight or the App Store, you can use the [Crashes Organizer](https://developer.apple.com/news/?id=nra79npr) in Xcode.
### iOS: Console app

If not, you can use the **Console** app in Xcode by connecting your device to your Mac. Follow the steps below on how to access the Console app:
You can use the **Console** app in Xcode by connecting your device to your Mac (or while running an iOS Simulator). Follow the steps below to access the Console app:

<Step label="1">

Expand All @@ -158,15 +147,30 @@ If you have connected a physical device, select it under **Devices**. Otherwise,
Click on **Open Console** button shown in the window to open the console app.

<ContentSpotlight
alt="Devices and Simulators window in Xcode."
alt="Open Console button in Devices and Simulators window in Xcode."
src="/static/images/debugging/open-console.png"
/>

This will open the console app for you to view logs from your device or simulator.

</Step>

For more information, see Apple's [Diagnosing Issues Using Crash Reports and Device Logs](https://developer.apple.com/documentation/xcode/diagnosing-issues-using-crash-reports-and-device-logs) guide.
## Production errors

Errors or bugs in your production app can be much harder to solve, mainly because you have less context around the error (that is, where, how, and why did the error occur?).

**The best first step in addressing a production error is to reproduce it locally.** Once you reproduce an error locally, you can follow the [development debugging process](#development-errors) to isolate and address the root cause.

### Production app is crashing

When a production app crashes, there is very little information available compared to development. Start by trying to reproduce the crash locally, then work through these steps to narrow down the cause:

- **Check platform-specific crash reports.**
- For Android apps on Google Play Store, refer to the crashes section of the [Google Play Console](https://play.google.com/console/about/).
- For iOS apps on TestFlight or the App Store, use the [Crashes Organizer](https://developer.apple.com/news/?id=nra79npr) in Xcode. See also Apple's [Diagnosing Issues Using Crash Reports and Device Logs](https://developer.apple.com/documentation/xcode/diagnosing-issues-using-crash-reports-and-device-logs) guide.
- **Use native log tools.** Connect a device that reproduces the crash and use [`adb logcat` or the Console app](#viewing-native-logs) to capture the native log output. Native logs often reveal the root cause when JavaScript error boundaries don't catch the problem.
- **Try production mode locally.** Running your app in **production mode** locally will show errors that normally wouldn't be thrown. To do so, you can run `npx expo start --no-dev --minify`. The `--no-dev` flag tells the server to run in production mode, and `--minify` is used to minify your code the same way it is for production JavaScript bundles.
- **Check your crash reporting dashboard.** If you use [Sentry](/guides/using-sentry/), [BugSnag](/guides/using-bugsnag/), or a similar service, check for the crash there first. These services provide stack traces, device info, and reproduction context.

### App crashes on certain (older) devices

Expand Down
7 changes: 6 additions & 1 deletion docs/pages/eas-update/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@ EAS Update makes fixing small bugs and pushing quick fixes a snap in between app

## Quick start

> **info** The `eas` commands below require EAS CLI. See [How to install EAS CLI](/eas/cli/#installation) for more information.

Install the `expo-updates` library and configure EAS Update:

<Terminal cmd={['$ npx expo install expo-updates', '', '$ eas update:configure']} />
<Terminal
cmd={['$ npx expo install expo-updates', '', '$ eas update:configure']}
cmdCopy="npx expo install expo-updates && eas update:configure"
/>

You need to create a new build for Android or iOS to include the `expo-updates` library in your build. After that, you can push an update to the production channel:

Expand Down
2 changes: 2 additions & 0 deletions docs/pages/eas/hosting/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ EAS Hosting offers the fastest path from `npx create-expo-app` to a fully deploy

## Quick start

> **info** The `eas` commands below require EAS CLI. See [How to install EAS CLI](/eas/cli/#installation) for more information.

To deploy your web app, you need to create a static build of your web project. Run the following command to export your web project into a **dist** directory:

<Terminal cmd={['$ npx expo export --platform web']} />
Expand Down
2 changes: 2 additions & 0 deletions docs/pages/eas/metadata/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ EAS Metadata uses a [**store.config.json**](/eas/metadata/config/#static-store-c

## Quick start

> **info** The `eas` commands below require EAS CLI. See [How to install EAS CLI](/eas/cli/#installation) for more information.

You can push the store config to the app stores by running the following command:

<Terminal cmd={['$ eas metadata:push']} />
Expand Down
4 changes: 3 additions & 1 deletion docs/pages/eas/workflows/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ EAS Workflows run in managed cloud environments with pre-packaged job types desi

## Quick start

> **info** The `eas` commands below require EAS CLI. See [How to install EAS CLI](/eas/cli/#installation) for more information.

Workflows are defined as YAML files in the **.eas/workflows/** directory at the root of your project. Each file specifies a `name`, optional triggers (`on`), and one or more `jobs` that run in the cloud. You can run a workflow with EAS CLI with the following command:

<Terminal cmd={['$ npx eas-cli@latest workflow:run .eas/workflows/your-workflow.yml']} />
<Terminal cmd={['$ eas workflow:run .eas/workflows/your-workflow.yml']} />

## Key features

Expand Down
2 changes: 2 additions & 0 deletions docs/pages/submit/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ EAS Submit works with apps built with [EAS Build](/build/introduction/) or local

## Quick start

> **info** The `eas` commands below require EAS CLI. See [How to install EAS CLI](/eas/cli/#installation) for more information.

Submit an Android build:

<Terminal cmd={['$ eas submit --platform android']} />
Expand Down
11 changes: 1 addition & 10 deletions docs/pages/tutorial/build-a-screen.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ hasVideoLink: true
import { Collapsible } from '~/ui/components/Collapsible';
import { ContentSpotlight } from '~/ui/components/ContentSpotlight';
import { ProgressTracker } from '~/ui/components/ProgressTracker';
import { Terminal } from '~/ui/components/Snippet';
import { Step } from '~/ui/components/Step';
import { CODE } from '~/ui/components/Text';
import { VideoBoxLink } from '~/ui/components/VideoBoxLink';
Expand Down Expand Up @@ -61,15 +60,7 @@ Now that we've broken down the UI into smaller chunks, we're ready to start codi

## Display the image

We'll use `expo-image` library to display the image in the app. It provides a cross-platform `<Image>` component to load and render an image.

The `expo-image` library comes out of the box, but if you don't have it, stop the development server by pressing <kbd>Ctrl</kbd> + <kbd>c</kbd> in the terminal. Then, install the `expo-image` library:

<Terminal cmd={['$ npx expo install expo-image']} />

The [`npx expo install`](/more/expo-cli/#installation) command will install the library and add it to the project's dependencies in **package.json**.

> **info** **Tip:** Any time we install a new library in our project, stop the development server by pressing <kbd>Ctrl</kbd> + <kbd>c</kbd> in the terminal and then run the installation command. After the installation completes, we can start the development server again by running `npx expo start` from the same terminal window.
We'll use `expo-image` library to display the image in the app. It provides a cross-platform `<Image>` component to load and render an image. It is already included in the default project template we're using.

The Image component takes the source of an image as its value. The source can be either a [static asset](https://reactnative.dev/docs/images#static-image-resources) or a URL. For example, the source required from **assets/images** directory is static. It can also come from [Network](https://reactnative.dev/docs/images#network-images) as a `uri` property.

Expand Down
6 changes: 5 additions & 1 deletion docs/pages/tutorial/image-picker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,14 @@ We'll use [`expo-image-picker`](/versions/latest/sdk/imagepicker), a library fro

## Install expo-image-picker

To install the library, run the following command:
To install the `expo-image-picker` library, stop the development server by pressing <kbd>Ctrl</kbd> + <kbd>c</kbd> in the terminal, then run the following command:

<Terminal cmd={['$ npx expo install expo-image-picker']} />

The [`npx expo install`](/more/expo-cli/#installation) command will install the library and add it to the project's dependencies in **package.json**.

> **info** **Tip:** Any time we install a new library in the project, stop the development server by pressing <kbd>Ctrl</kbd> + <kbd>c</kbd> in the terminal and then run the installation command. After the installation completes, start the development server again by running `npx expo start`.

</Step>

<Step label="2">
Expand Down
1 change: 1 addition & 0 deletions packages/@expo/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ _This version does not introduce any user-facing changes._
- Retrieve default route's IP address concurrently ([#42923](https://github.com/expo/expo/pull/42923) by [@kitten](https://github.com/kitten))
- Replace `require-from-string` with `@expo/require-utils` ([#42884](https://github.com/expo/expo/pull/42884) by [@kitten](https://github.com/kitten))
- Refactor env loading and reloading to unified logic and don't overwrite original system values ([#43038](https://github.com/expo/expo/pull/43038) by [@kitten](https://github.com/kitten))
- Add initial event logging system ([#43013](https://github.com/expo/expo/pull/43013) by [@kitten](https://github.com/kitten))

## 55.0.7 — 2026-02-08

Expand Down
38 changes: 37 additions & 1 deletion packages/@expo/cli/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ CLI tool for all Expo projects. The public interface should be lean, all command
├── bin/cli.ts # CLI entry point - registers all commands
├── src/
│ ├── api/ # expo.dev API client
│ ├── events/ # JSONL event-based debugger
│ ├── config/ # `expo config` command
│ ├── customize/ # `expo customize` command
│ ├── export/ # `expo export` command (production bundling)
Expand Down Expand Up @@ -138,7 +139,42 @@ See `src/utils/open.ts` for an example of handling the `SYSTEMROOT`/`SystemRoot`

## Debug logs

Debug logs support `DEBUG=expo:*`, for legacy reasons we support `EXPO_DEBUG=1` which sets `DEBUG=expo:*` in the bin.ts file.
**Old debugging system:**
Debug logs used to be created with the `debug` package with individual modules creating a `debug` function to use for logging.
This can then be activated with `DEBUG=expo:*`, and for legacy reasons `EXPO_DEBUG=1` currently sets `DEBUG=expo:*` in the bin.ts file.

```ts
const debug = require('debug')('expo:utils:example');
debug('hello');
```

**New debugging system:**
Newer modules use the `events` helper from `src/events/index.ts` to define structured events in JSON format.

```ts
export const event = events('metro', (t) => [
t.event<'example:start', {
value: string;
}>(),
]);

event('metro:example:start', { value: 'hello' });
```

The `events` function accepts a category name and a function that is used to define the event types, but never called.
When setting `LOG_EVENTS=1` JSONL events will be logged to the standard output, or with `LOG_EVENTS=events.log` events will log to an events.log file.
This is a faster events system than `debug`, captures structured JSON events, and is scalable, and can be used in any module to add richer debug output.

When creatin a nwe events category, add the `event` function it returns to the `Events` type in `src/events/types.ts` to collect all the events' types in one place:

```
// Add a new import:
import type { event as myNewEvent } from '...';

export type Events = collectEventLoggers<[
typeof myNewEvent, // Add the imported new event function here
]>;
```

## Production

Expand Down
6 changes: 6 additions & 0 deletions packages/@expo/cli/bin/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ import chalk from 'chalk';
import Debug from 'debug';
import { boolish } from 'getenv';

import { installEventLogger } from '../src/events';

// Setup event logger output
// NOTE: Done before any console output
installEventLogger();

// Check Node.js version and issue a loud warning if it's too outdated
// This is sent to stderr (console.error) so it doesn't interfere with programmatic commands
const NODE_MIN = [20, 19, 4];
Expand Down
Loading
Loading