Files
bsky-social-app/docs/build.md
T
2026-07-13 20:44:33 +03:00

11 KiB

Build instructions

Running Web App

  • pnpm install
  • pnpm web

You're all set!

iOS/Android Build

Native Environment Setup

This is NOT required when developing for web.

  • Set up your environment using the expo instructions.
    • make sure that the JAVA_HOME points to the zulu-17 directory in your .zshrc or .bashrc file: export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home. DO NOT use another JDK or you will encounter build errors.
  • If you're running macOS, make sure you are running the correct versions of Ruby and Cocoapods:-
    • If you are using Apple Silicon and this is the first time you are building for RN 0.74+, you may need to run:
      • arch -arm64 brew install llvm
      • sudo gem install ffi
    • Check if you've installed Cocoapods through homebrew. If you have, remove it:
      • brew info cocoapods
      • If output says Installed:
      • brew remove cocoapods
    • If you have not installed rbenv:
      • brew install rbenv
      • rbenv install 2.7.6
      • rbenv global 2.7.6
      • Add eval "$(rbenv init - zsh)" to your ~/.zshrc
    • From inside the project directory:
      • bundler install (this will install Cocoapods)
  • After initial setup:
    • Copy google-services.json.example to google-services.json or provide your own google-services.json. (A real firebase project is NOT required)
    • pnpm prebuild -> you will also need to run this anytime app.json or native package.json deps change

Running the Native App

  • iOS: pnpm ios
    • Xcode must be installed for this to run.
      • A simulator must be preconfigured in Xcode settings.
        • if no iOS versions are available, install the iOS runtime at Xcode > Settings > Platforms.
        • if the simulator download keeps failing you can download it from the developer website.
          • Apple Developer
          • xcode-select -s /Applications/Xcode.app
          • xcodebuild -runFirstLaunch
          • xcrun simctl runtime add "~/Downloads/iOS_17.4_Simulator_Runtime.dmg" (adapt the path to the downloaded file)
      • In addition, ensure Xcode Command Line Tools are installed using xcode-select --install.
    • Expo will require you to configure Xcode Signing. Follow the linked instructions. Error messages in Xcode related to the signing process can be safely ignored when installing on the iOS Simulator; Expo merely requires the profile to exist in order to install the app on the Simulator.
      • Make sure you do have a certificate: open Xcode > Settings > Accounts > (sign-in) > Manage Certificates > + > Apple Development > Done.
      • If you still encounter issues, try rm -rf ios before trying to build again (pnpm ios)
  • Android: pnpm android
    • Install "Android Studio"
      • Make sure you have the Android SDK installed (Android Studio > Tools > Android SDK).
        • In "SDK Platforms": "Android x" (where x is Android's current version).
        • In "SDK Tools": "Android SDK Build-Tools" and "Android Emulator" are required.
        • Add export ANDROID_HOME=/Users/<your_username>/Library/Android/sdk to your .zshrc or .bashrc (and restart your terminal).
      • Setup an emulator (Android Studio > Tools > Device Manager).
  • Web: pnpm web (see the top of this file).

After you do pnpm ios and pnpm android once, you can later just run pnpm web and then press either i or a to open iOS and Android emulators respectively which is much faster. However, if you make native changes, you'll have to do pnpm prebuild -p ios and pnpm prebuild -p android and then pnpm ios and pnpm android again before you can continue with the same workflow.

Tips

  • Copy the .env.example to .env and fill in any necessary tokens. (The Sentry token is NOT required; see instructions below if you want to enable Sentry.)
  • To run on the device, add --device to the command (e.g. pnpm android --device). To build in production mode (slower build, faster app), also add --variant release on Android or --configuration Release on iOS.
  • If you want to use Expo EAS on your own builds without ejecting from Expo, make sure to change the owner and extra.eas.projectId properties. If you do not have an Expo account, you may remove these properties.
  • pnpm exec react-native info Checks what has been installed.
  • If the Android simulator frequently hangs or is very sluggish, bump its memory limit
  • The Android simulator won't be able to access localhost services unless you run adb reverse tcp:{PORT} tcp:{PORT}
    • For instance, the locally-hosted dev-wallet will need adb reverse tcp:3001 tcp:3001
  • For some reason, the typescript compiler chokes on platform-specific files (e.g. foo.native.ts) but only when compiling for Web thus far. Therefore we always have one version of the file that doesn't use a platform specifier, and that should be the Web version. (More info.)

Running E2E Tests

  • Start in various console tabs:
    • pnpm e2e:mock-server
    • pnpm e2e:start
  • Run once: pnpm e2e:build
  • Each test run: pnpm e2e:run

Adding Sentry

Adding Sentry is NOT required. You can keep SENTRY_AUTH_TOKEN= in .env which will build the app without Sentry.

However, if you're a part of the Bluesky team and want to enable Sentry, fill in SENTRY_AUTH_TOKEN in your .env. It can be created on the Sentry dashboard using these instructions.

If you change SENTRY_AUTH_TOKEN, you need to do pnpm prebuild before running pnpm ios or pnpm android again.

Adding bitdrift

Adding bitdrift is NOT required. You can keep EXPO_PUBLIC_BITDRIFT_API_KEY= in .env which will avoid initializing bitdrift during startup.

However, if you're a part of the Bluesky team and want to enable bitdrift, fill in EXPO_PUBLIC_BITDRIFT_API_KEY in your .env to enable bitdrift.

Adding and Updating Locales

  • pnpm intl:build -> you will also need to run this anytime ./src/locale/{locale}/messages.po change

Running the Backend Locally

This is NOT required for app development but if you also want to develop the Bluesky backend locally too, you'll need this.

  • Start the dev servers
    • git clone git@github.com:bluesky-social/atproto.git
    • cd atproto
    • brew install pnpm
    • optional: brew install jq
    • pnpm i
    • pnpm build
    • Start the docker daemon (on MacOS this entails starting the Docker Desktop app)
    • Launch a Postgres database on port 5432
    • cd packages/dev-env && pnpm start

Run the account with the AppView proxy DID passed in as an environment variable: EXPO_PUBLIC_BLUESKY_PROXY_DID=did:plc:dw4kbjf5mn7nhenabiqpkyh3 pnpm start

Then, when logging in or creating an account, point it to the localhost port of the devserver.

Go-Server Build

The Go server in this repository is only used for serving the web app in production. Usually you won't need to touch it.

Prerequisites

Steps

To run the build with Go, use staging credentials, your own, or any other account you create.

cd social-app
pnpm install && pnpm build-web
cd bskyweb/
go mod tidy
go build -v -tags timetzdata -o bskyweb ./cmd/bskyweb
./bskyweb serve --appview-host=https://public.api.bsky.app

On build success, access the application at http://localhost:8100/. Subsequent changes require re-running the above steps in order to be reflected.

Various notes

Debugging

Developer Menu

To open the Developer Menu on an expo-dev-client app you can do the following:

  • Android Device: Shake the device vertically, or if your device is connected via USB, run adb shell input keyevent 82 in your terminal
  • Android Emulator: Either press Cmd ⌘ + m or Ctrl + m or run adb shell input keyevent 82 in your terminal
  • iOS Device: Shake the device, or touch 3 fingers to the screen
  • iOS Simulator: Press Ctrl + Cmd ⌘ + z on a Mac in the emulator to simulate the shake gesture or press Cmd ⌘ + d

Running E2E Tests

See testing.md.

Polyfills

./platform/polyfills.*.ts adds polyfills to the environment. Currently, this includes:

  • TextEncoder / TextDecoder
  • Array#findLast (on web)
  • setImmediate (on web)

Sentry sourcemaps

Sourcemaps upload automatically as part of each build path; there are no manual steps.

  • Native builds (eas build for iOS/Android): the @sentry/react-native Xcode build phase and Gradle plugin upload sourcemaps during the build. SENTRY_AUTH_TOKEN, SENTRY_RELEASE, and SENTRY_DIST are provided by the build workflows and read natively.
  • OTA updates: pnpm export runs expo export --dump-sourcemap and then pnpm upload-native-sourcemaps, which invokes @sentry/expo-upload-sourcemaps on the dist/ folder. The org and project are read from the Sentry plugin config in app.config.js; SENTRY_AUTH_TOKEN is required and SENTRY_RELEASE is optional (it only lets you browse the artifacts under a release in the Sentry UI).
  • Web (pnpm build-web): @sentry/webpack-plugin uploads sourcemaps during the Docker web build.

Matching is by debug ID end-to-end: the Metro serializer stamps a debugId into the bundle and its map, the upload passes --debug-id-reference, and at runtime the event's debug_meta carries the same id. Release/dist is only a legacy fallback, which is why OTA uploads no longer pass a dist.

OTA updates

To create OTA updates, run eas update along with the --branch flag to indicate which branch you want to push the update to, and the --message flag to indicate a message for yourself and your team that shows up on https://expo.dev. All the channels (which make up the options for the --branch flag) are given in eas.json. See more here

The clients which can receive an OTA update are governed by the runtimeVersion property in app.json. Right now, it is set so that only apps with the same appVersion (same as version property in app.json) can receive the update and install it. However, we can manually set "runtimeVersion": "1.34.0" or anything along those lines as well. This is useful if very little native code changes from update to update. If we are manually setting runtimeVersion, we should increment the version each time the native code is changed. See more here