AppForShare

Expo internal distribution: share EAS builds and where the link stops

· 7 min read

Expo internal distribution: share EAS builds and where the link stops

Expo internal distribution is the quickest way to get an Expo or React Native build onto a tester's phone. You add one line to a build profile, EAS builds the app, and you get a page with an Install button and a QR code. For many solo developers that is all they need. This guide explains how the internal link works, what Expo's docs say about access, where the link stops being enough, and how to keep building on EAS while testers install from a page that does more. Expo facts below were read on expo.dev and docs.expo.dev on November 4, 2026.

How internal distribution works

Expo now calls its build service Expo Build (EAS Build), and its docs use both names. Internal distribution is a setting on a build profile in eas.json:

{
  "build": {
    "preview": {
      "distribution": "internal",
      "android": { "buildType": "apk" }
    }
  }
}

Then run eas build --profile preview --platform all. On Android you get an APK that any phone can install once the tester allows installs from the browser. On iOS you get an ad hoc signed build (or an enterprise build if your Apple account is an enterprise one). Ad hoc means the build installs only on iPhones whose UDID was in the provisioning profile when the build ran.

When the build finishes, the build page on expo.dev has an Install button that shows a QR code and a link. Testers scan it, or the team installs from the Expo Orbit menu bar app on a Mac. Expo's docs describe the access model like this: internal distribution build URLs "are available to anybody with the URL, and each is identified by a 32 character UUID". An owner can turn off "Unauthenticated access to internal builds", after which a tester needs an Expo login to open the page (Expo internal distribution docs).

When the EAS link is enough

Be honest with yourself here. The EAS link is a good fit when:

  • You build on EAS anyway and the Free plan's 15 Android and 15 iOS builds a month cover you.
  • Testers are you, a cofounder or two developers who already have the URL in Slack.
  • Everyone's iPhone is already in the profile, so nobody waits for a new build.
  • You do not need to know who installed, and you collect bug reports in a chat thread.

Expo is also ahead in places AppForShare does not go at all. It builds your app in the cloud, including iOS without a Mac. It manages signing credentials. It hosts over the air updates with rollouts. AppForShare does none of that. If those are the jobs you need, stay on EAS for them.

Where the link stops

The gaps show up when testers are not developers, when a client is involved, or when builds come every day. We read the internal distribution docs and the internal distribution tutorial on November 4, 2026. The items below were not found in them (not found is not proof of absence):

NeedEAS internal distribution (docs read Nov 4, 2026)AppForShare
Link per buildYes, one URL per buildYes, one install link per build
Link that always opens the newest buildNot found in its docsChannel link such as Beta, with rollback (Pro)
AccessOpen for anyone with the URL, or Expo login for the projectPassword (Free), link controls such as stop date and install limit (Pro), access codes and private projects (Team)
Tester accountsNone for open links, Expo login if turned onNo tester accounts on any plan
Install page languagesNot found in its docs13 languages
Tester feedbackNot found in its docsFeedback with screenshots from the install page, no SDK (Free)
Install analyticsNot found in its docsDevices, OS versions, countries (Pro)
Store readiness checkNot found in its docsOn every build with an account, plus Expo checks
Other build sourcesEAS builds onlyAny build: EAS, eas build --local, GitHub Actions, other CI, Flutter, native

The most common pain is the per build URL. Every new EAS build is a new link, so the link a client saved last week opens last week's build. With a channel link the address stays the same and the newest build in that channel opens. Putting an older build back into the channel rolls the link back. Installed apps are not changed.

Keep EAS Build, send the build to AppForShare

You do not have to change how you build. There are four ways to get an EAS build onto an AppForShare install page.

1. Connect Expo (EAS build webhook)

On Pro and Team, each project can get an EAS webhook address and a secret on the Connect Expo page. You run one command once:

eas webhook:create --event BUILD --url <your AppForShare URL> --secret <your secret>

When an internal build finishes, AppForShare checks Expo's signature first, fetches the artifact from Expo's artifact host, and adds the build to the mapped project. Release notes come from the commit message EAS sends, and a build profile map can put preview builds into your Beta channel. Store builds are skipped with a note, because they cannot be installed from a link. No Expo token is needed.

2. Expo Workflows custom job

If you use Expo Workflows, add a job after the build that downloads the file and uploads it:

jobs:
  build_preview_ios:
    type: build
    params:
      platform: ios
      profile: preview
  share:
    needs: [build_preview_ios]
    steps:
      - uses: eas/download_build
        id: download_build
        with:
          build_id: ${{ needs.build_preview_ios.outputs.build_id }}
      - run: npx --yes appforshare upload "${{ steps.download_build.outputs.artifact_path }}" --channel beta

Store APPFORSHARE_TOKEN as a secret Expo environment variable. Upload tokens are on Pro and Team.

3. The CLI with an EAS build id

From your own machine or any CI that has eas-cli signed in:

npx appforshare upload --eas-latest --profile preview --platform ios
npx appforshare upload --eas <build id>

The CLI runs eas-cli on the same machine, downloads the artifact and fills the notes from the build. Your EXPO_TOKEN never leaves that machine.

4. GitHub Actions or any CI

The Expo EAS CI guide shows a GitHub Actions job that waits for the EAS build, downloads artifacts.buildUrl and uploads it. The full setup, including iPhones and store steps, is in Use AppForShare with Expo EAS.

iPhones: the part that needs a plan

Ad hoc builds only install on registered devices. Expo's docs say "Registering a device with Expo does not register it with Apple" until the device is included in a build, so a new tester means a new build or eas build:resign. The details and both ways to collect devices are in eas device:create for iPhone testers. With AppForShare, testers send their UDID through an onboarding link (Pro), the device can be registered on Apple with your App Store Connect API key, and the tester gets one email when a build with their device is ready.

Readiness and Expo checks

Every build uploaded to an account gets a store readiness check. For Expo apps the build page also shows the Expo SDK, whether updates are on, the runtime version and the update channel the build reads. Readiness flags a development client build sent to testers (it needs a dev server, so testers see an error), a test build that reads your production update channel, and a runtime version change. That catches the two reports Expo teams hear most from testers: a red screen and the wrong update.

More for EAS teams: sending every build from Expo Workflows, sharing eas build --local output, keeping test builds off production updates and Expo EAS alternatives.

Common questions

Is the EAS internal link private?

By default it is open for anyone with the URL. The URL contains a 32 character UUID, so it is hard to guess. A project owner can require an Expo login instead. There is no password option in the docs we read.

Do I need to stop using EAS Build to use AppForShare?

No. AppForShare does not build apps on its own machines. Keep EAS Build, and send the finished file to AppForShare by webhook, Workflows job, CLI or CI. See AppForShare vs Expo EAS for a side by side view.

Does this work with EAS Update?

Yes. EAS Update keeps working inside the installed app. AppForShare shares whole builds and hosts no updates. The readiness check only tells you which update channel a test build reads.

What does it cost?

EAS Free is $0 and Starter is $19 a month, as listed on November 4, 2026. AppForShare Free is $0, Pro is $12 a month and Team is $39 a month with 5 seats. Our EAS Build pricing guide walks through the numbers.

If your testers have outgrown one link per build, keep EAS for the build and try the install page side free. Create an account, upload one EAS build, and send the link to a tester who has never heard of Expo.

Keep reading

App Distribution Platform · · 5 min read

AppForShare File Size and Upload Limits

AppForShare limits the size of each build you upload by plan: 50 MB without an account, 150 MB on the Free plan, 2 GB on Pro and 4 GB on Team. Accounts also have a storage total, and every plan...