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
705 changes: 366 additions & 339 deletions apps/bare-expo/macos/Podfile.lock

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion apps/expo-go/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ apply plugin: 'com.facebook.react'
react {
def projectRoot = rootDir.getAbsoluteFile().getParentFile().getAbsolutePath()

entryFile = file(["node", "-e", "require('expo/scripts/resolveAppEntry')", projectRoot, "android", "absolute"].execute(null, rootDir).text.trim())
reactNativeDir = new File(projectRoot, "../../react-native-lab/react-native/packages/react-native")
codegenDir = new File(projectRoot, "../../react-native-lab/react-native/packages/react-native-codegen")

Expand Down
38 changes: 38 additions & 0 deletions apps/expo-go/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"expo": {
"name": "expo-home",
"description": "",
"slug": "home",
"privacy": "unlisted",
"sdkVersion": "55.0.0",
"version": "55.0.0",
"platforms": ["ios", "android"],
"primaryColor": "#cccccc",
"icon": "https://s3.amazonaws.com/exp-brand-assets/ExponentEmptyManifest_192.png",
"updates": {
"checkAutomatically": "NEVER",
"fallbackToCacheTimeout": 0,
"url": "https://u.expo.dev/6b6c6660-df76-11e6-b9b4-59d1587e6774"
},
"userInterfaceStyle": "automatic",
"ios": {
"supportsTablet": true,
"bundleIdentifier": "host.exp.exponent"
},
"newArchEnabled": true,
"android": {
"package": "host.exp.exponent"
},
"androidStatusBar": {
"barStyle": "dark-content"
},
"scheme": "exp",
"jsEngine": "hermes",
"extra": {
"eas": {
"projectId": "6b6c6660-df76-11e6-b9b4-59d1587e6774"
}
},
"runtimeVersion": "55.0.0"
}
}
1 change: 1 addition & 0 deletions docs/constants/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ export const general = [
makePage('router/reference/src-directory.mdx'),
makePage('router/reference/testing.mdx'),
makePage('router/reference/troubleshooting.mdx'),
makePage('router/reference/reserved-paths.mdx'),
]),
makeGroup('Migration', [
makePage('router/migrate/from-react-navigation.mdx'),
Expand Down
2 changes: 2 additions & 0 deletions docs/pages/guides/customizing-metro.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ You can overwrite the default **index.html** in Metro web by creating a **public

In the future, this will work universally across platforms with EAS Update hosting. Currently, the feature is web-only based on the static host used for the native app, for example, the legacy Expo service updates do not support this feature.

> **warning** Some paths such as `/assets` are reserved by Metro. Avoid placing files in **public/assets/** or other reserved paths. See [Reserved paths](/router/reference/reserved-paths/) for the complete list.

## TypeScript

Expo's Metro config supports the `compilerOptions.paths` and `compilerOptions.baseUrl` fields in the project's **tsconfig.json** (or **jsconfig.json**) file. This enables absolute imports and aliases in the project. See [TypeScript](/guides/typescript) guide for more information.
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/guides/publishing-websites.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ Run the universal export command to compile the project for web:

The resulting project files are located in the **dist** directory. Any files inside the **public** directory are also copied to the **dist** directory.

> **warning** Avoid creating the directory `/public/assets/`. The path `/assets` is reserved by Metro and will cause file access errors during development.
> **warning** Some paths such as `/assets` are reserved by Metro. Avoid placing files in **public/assets/** or other reserved paths. See [Reserved paths](/router/reference/reserved-paths/) for the complete list.

## Serve locally

Expand Down
2 changes: 1 addition & 1 deletion docs/pages/router/basics/notation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Routes that include a `+` have special significance to Expo Router, and are used
- [`+native-intent`](/router/advanced/native-intent/) is used to handle deep links into your app that don't match a specific route, such as links generated by third-party services.
- [`+middleware`](/router/web/middleware/) is used to run code before a route is rendered, allowing you to perform tasks like authentication or redirection for every request.

> **warning** Avoid creating a top-level route named `assets` (like `/app/assets.tsx` or `/app/assets/[other-pages].tsx`). The path `/assets` is reserved by Metro and will cause errors when trying to access it from the URL.
> **warning** Some path names such as `/assets` are reserved by Metro and Expo Router. Avoid using them for routes. See [Reserved paths](/router/reference/reserved-paths/) for the complete list.

## Route notation applied

Expand Down
63 changes: 63 additions & 0 deletions docs/pages/router/reference/reserved-paths.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
title: Reserved paths
description: URL paths reserved by Metro and Expo Router that you should avoid using for routes or static files.
---

import { FileTree } from '~/ui/components/FileTree';

If you create a route or place static files at certain URL paths, Metro or Expo Router will intercept the request instead of serving your content. Depending on the path, this can result in a "404 Asset not found" error or your page being silently replaced by an internal dev server response.

## `/assets/*`

Metro serves all bundled assets (images, fonts, and other files) at this path. If you create a route at **app/assets.tsx** or a directory at **public/assets/**, Metro intercepts the request and your content is never reached.

This applies to both top-level routes and static files:

<FileTree
files={[
['app/assets.tsx', 'Conflicts with Metro'],
['app/assets/index.tsx', 'Conflicts with Metro'],
['public/assets/logo.png', 'Conflicts with Metro'],
]}
/>

Rename your route or directory to avoid the conflict:

<FileTree
files={[
['app/media.tsx', 'Works'],
['public/images/logo.png', 'Works'],
]}
/>

## `/_expo/*`

Expo Router uses this path for multiple internal middlewares, including dev tools and manifests. Do not create routes or static files under this path.

## `/_flight/*`

React Server Components use this path internally. Do not create routes or static files under this path.

## `/inspector`

React Native uses `/inspector/debug` and `/inspector/network` for the debugger. Avoid creating routes that match `/inspector` or its sub-paths.

## `/expo-dev-plugins/*`

Expo development tool plugins use this path. Do not create routes or static files under this path.

## `/manifest`

The dev server serves the native app manifest at this path. If you create a route at **app/manifest.tsx**, the dev server responds with manifest JSON instead of your page. Your route will appear to silently not load during development.

## `/_sitemap`

Expo Router automatically generates a sitemap route at this path for debugging. If you create a route at **app/\_sitemap.tsx**, it will override the built-in sitemap. See [Sitemap](/router/reference/sitemap/) for more details on this feature.

## `/public/*`

If your project has a **public** directory, the `/public` URL path may conflict with static file serving. Avoid creating a route at **app/public.tsx** or **app/public/index.tsx** since the path is implicitly reserved when the **public** directory exists.

## `/favicon.ico`

Unlike the paths above, `/favicon.ico` is safe to override. Expo CLI serves a default favicon when none is provided. You can replace it by placing a **favicon.ico** file in your **public** directory or by creating an [API route](/router/web/api-routes/).
4 changes: 1 addition & 3 deletions docs/pages/router/web/static-rendering.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,6 @@ export async function generateStaticParams(params: {

</PaddedAPIBox>

> **warning** Avoid creating a top-level route named `assets` (like `/app/assets.tsx` or `/app/assets/[other-pages].tsx`). The path `/assets` is reserved by Metro and will cause errors when trying to access it from the URL.

### Read files using `process.cwd()`

Since Expo Router compiles your code into a separate directory you cannot use `__dirname` to form a path as its value will be different than expected.
Expand Down Expand Up @@ -229,7 +227,7 @@ Expo CLI supports a root **public** directory that gets copied to the **dist** d
files={['public/favicon.ico', 'public/logo.png', 'public/.well-known/apple-app-site-association']}
/>

> **warning** Avoid creating the directory `/public/assets/`. The path `/assets` is reserved by Metro and will cause file access errors during development.
> **warning** Some paths such as `/assets` are reserved by Metro. Avoid placing files in **public/assets/** or other reserved paths. See [Reserved paths](/router/reference/reserved-paths/) for the complete list.

These files will be copied to the **dist** directory during static rendering:

Expand Down
22 changes: 8 additions & 14 deletions docs/pages/workflow/upgrading-expo-sdk-walkthrough.mdx
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
---
title: Upgrade Expo SDK
description: Learn how to incrementally upgrade the Expo SDK version in your project.
hasVideoLink: true
---

import { Collapsible } from '~/ui/components/Collapsible';
import { Terminal } from '~/ui/components/Snippet';
import { Step } from '~/ui/components/Step';
import { VideoBoxLink } from '~/ui/components/VideoBoxLink';

> **info** We recommend upgrading SDK versions incrementally, one at a time. Doing so will help you pinpoint breakages and issues that arise during the upgrade process.

With a new SDK release, the latest version enters the current release status. This applies to Expo Go as it only supports the latest SDK version and previous versions are no longer supported. We recommend using [development builds](/develop/development-builds/introduction/) for production apps as the backwards compatibility for older SDK versions on EAS services tends to be much longer, but not forever.

If you are looking to install a specific version of Expo Go, visit [expo.dev/go](https://expo.dev/go). It supports downloads for Android devices/emulators and iOS simulators. However, due to iOS platform restrictions, only the latest version of Expo Go is available for installation on physical iOS devices.

<VideoBoxLink
videoId="QuN63BRRhAM"
title="Watch: How to upgrade from Expo SDK 53 to SDK 54 in 5 minutes"
/>

## How to upgrade to the latest SDK version

<Step label="1">
Expand All @@ -30,14 +23,14 @@ Install the new version of the Expo package:

<Terminal
cmd={{
npm: ['$ npm install expo@^54.0.0'],
yarn: ['$ yarn add expo@^54.0.0'],
pnpm: ['$ pnpm add expo@^54.0.0'],
bun: ['$ bun install expo@^54.0.0'],
npm: ['$ npm install expo@^55.0.0'],
yarn: ['$ yarn add expo@^55.0.0'],
pnpm: ['$ pnpm add expo@^55.0.0'],
bun: ['$ bun install expo@^55.0.0'],
}}
/>

Depending on which SDK you're upgrading to, substitute the `expo@^54.0.0` with the version range of the Expo SDK version you're targeting. For example, `expo@^54.0.0` stands for SDK 54.
Depending on which SDK you're upgrading to, substitute `expo@^55.0.0` with the version range of the Expo SDK version you're targeting. For example, `expo@^55.0.0` stands for SDK 55.

</Step>

Expand Down Expand Up @@ -75,17 +68,18 @@ Read the [SDK changelogs](#sdk-changelogs) for the SDK version you are upgrading

Each SDK announcement release notes post contains information deprecations, breaking changes, and anything else that might be unique to that particular SDK version. When upgrading, be sure to check these out to make sure you don't miss anything.

- **SDK 55**: [Release notes](https://expo.dev/changelog/sdk-55)
- **SDK 54**: [Release notes](https://expo.dev/changelog/sdk-54)
- **SDK 53**: [Release notes](https://expo.dev/changelog/sdk-53)
- **SDK 52**: [Release notes](https://expo.dev/changelog/2024-11-12-sdk-52)
- **React Native 0.77 is available with Expo SDK 52**. To upgrade, see these [Release notes](https://expo.dev/changelog/2025/01-21-react-native-0.77).

### Deprecated SDK Version Changelogs

The following blog posts may included outdated information, but they are still useful for reference if you happen to fall far behind on SDK upgrades.

<Collapsible summary="See a full list of deprecated SDK release changelogs">

- **SDK 52**: [Release notes](https://expo.dev/changelog/2024-11-12-sdk-52)
- **React Native 0.77 is available with Expo SDK 52**. To upgrade, see these [Release notes](https://expo.dev/changelog/2025/01-21-react-native-0.77).
- **SDK 51**: [Release notes](https://expo.dev/changelog/2024-05-07-sdk-51)
- **SDK 50**: [Release notes](https://expo.dev/changelog/2024-01-18-sdk-50)
- **SDK 49**: [Release notes](https://blog.expo.dev/expo-sdk-49-c6d398cdf740)
Expand Down
2 changes: 1 addition & 1 deletion docs/public/static/data/unversioned/expo-widgets.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions packages/@expo/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

- Add `@react-navigation/core` and `@react-navigation/native` to autolinking resolution ([#43456](https://github.com/expo/expo/pull/43456) by [@kitten](https://github.com/kitten))
- Drop `expo-router/doctor` install check ([#43461](https://github.com/expo/expo/pull/43461) by [@kitten](https://github.com/kitten))
- Pass on `tls` options from Metro config to Metro `runServer` fork ([#43186](https://github.com/expo/expo/pull/43186) by [@cortinico](https://github.com/cortinico))

## 55.0.12 — 2026-02-25

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {
type ImmutableRequest,
resolveLoaderContextKey,
} from 'expo-server/private';
import https from 'https';
import path from 'path';

import {
Expand Down Expand Up @@ -1232,9 +1233,6 @@ export class MetroBundlerDevServer extends BundlerDevServer {
resetCache: options.resetDevServer,
};

// Required for symbolication:
process.env.EXPO_DEV_SERVER_ORIGIN = `http://localhost:${options.port}`;

event('start', {
mode,
web: this.isTargetingWeb(),
Expand All @@ -1257,6 +1255,11 @@ export class MetroBundlerDevServer extends BundlerDevServer {
}
);

const protocol = server instanceof https.Server ? 'https' : 'http';

// Required for symbolication:
process.env.EXPO_DEV_SERVER_ORIGIN = `${protocol}://localhost:${options.port}`;

if (!options.isExporting) {
const manifestMiddleware = await this.getManifestMiddlewareAsync(options);

Expand Down Expand Up @@ -1494,9 +1497,8 @@ export class MetroBundlerDevServer extends BundlerDevServer {
port: options.port,
// localhost isn't always correct.
host: 'localhost',
// http is the only supported protocol on native.
url: `http://localhost:${options.port}`,
protocol: 'http',
url: `${protocol}://localhost:${options.port}`,
protocol,
},
middleware,
messageSocket,
Expand Down
18 changes: 16 additions & 2 deletions packages/@expo/cli/src/start/server/metro/instantiateMetro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import MetroHmrServer, { Client as MetroHmrClient } from '@expo/metro/metro/HmrS
import RevisionNotFoundError from '@expo/metro/metro/IncrementalBundler/RevisionNotFoundError';
import type MetroServer from '@expo/metro/metro/Server';
import formatBundlingError from '@expo/metro/metro/lib/formatBundlingError';
import { InputConfigT, mergeConfig, resolveConfig, type ConfigT } from '@expo/metro/metro-config';
import { mergeConfig, resolveConfig, type ConfigT } from '@expo/metro/metro-config';
import { Terminal } from '@expo/metro/metro-core';
import { createStableModuleIdFactory, getDefaultConfig } from '@expo/metro-config';
import chalk from 'chalk';
Expand All @@ -21,7 +21,7 @@ import { MetroTerminalReporter } from './MetroTerminalReporter';
import { attachAtlasAsync } from './debugging/attachAtlas';
import { createDebugMiddleware } from './debugging/createDebugMiddleware';
import { createMetroMiddleware } from './dev-server/createMetroMiddleware';
import { runServer } from './runServer-fork';
import { runServer, type SecureServerOptions } from './runServer-fork';
import { withMetroMultiPlatformAsync } from './withMetroMultiPlatform';
import { events, shouldReduceLogs } from '../../../events';
import { Log } from '../../../log';
Expand Down Expand Up @@ -359,13 +359,27 @@ export async function instantiateMetroAsync(
resetAtlasFile: isExporting,
});

// Support HTTPS based on the metro's tls server config
// TODO(@kitten): Remove cast once `@expo/metro` is updated to a Metro version that supports the tls config
const tls = (metroConfig.server as typeof metroConfig.server & { tls?: SecureServerOptions })
?.tls;
const secureServerOptions = tls
? {
key: tls.key,
cert: tls.cert,
ca: tls.ca,
requestCert: tls.requestCert,
}
: undefined;

const { address, server, hmrServer, metro } = await runServer(
metroBundler,
metroConfig,
{
host: options.host,
websocketEndpoints,
watch: !isExporting && isWatchEnabled(),
secureServerOptions,
},
{
mockServer: isExporting,
Expand Down
21 changes: 20 additions & 1 deletion packages/@expo/cli/src/start/server/metro/runServer-fork.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,25 @@ import { MetroBundlerDevServer } from './MetroBundlerDevServer';
import { Log } from '../../../log';
import type { ConnectAppType } from '../middleware/server.types';

export interface SecureServerOptions {
readonly key: string | Buffer;
readonly cert: string | Buffer;
readonly ca: string | Buffer;
readonly requestCert: boolean;
}

interface RunServerOptionsFork {
hasReducedPerformance?: boolean;
host?: string;
onError?($$PARAM_0$$: Error & { code?: string }): void;
onReady?(server: http.Server | https.Server): void;
onClose?(): void;
websocketEndpoints?: RunServerOptions['websocketEndpoints'];
secureServerOptions?: SecureServerOptions;
waitForBundler?: boolean;
watch?: boolean;
}

export const runServer = async (
_metroBundler: MetroBundlerDevServer,
config: ConfigT,
Expand All @@ -32,7 +51,7 @@ export const runServer = async (
waitForBundler = false,
websocketEndpoints = {},
watch,
}: RunServerOptions,
}: RunServerOptionsFork,
{
mockServer,
}: {
Expand Down
3 changes: 3 additions & 0 deletions packages/expo-brownfield/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

### 🎉 New features

- [android] add basic implementation of shared state for android ([#43097](https://github.com/expo/expo/pull/43097) by [@pmleczek](https://github.com/pmleczek))
- [cli] allow shipping ios artifacts as swift package ([#43369](https://github.com/expo/expo/pull/43369) by [@pmleczek](https://github.com/pmleczek))

### 🐛 Bug fixes

### 💡 Others
Expand Down
1 change: 1 addition & 0 deletions packages/expo-brownfield/cli/build/commands/build-ios.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/expo-brownfield/cli/build/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading