# Bluesky Social App: Building and Forking the React Native Client

> The Bluesky client is a React Native and TypeScript application that builds on the atproto packages, ships through Expo and EAS, and is forkable under MIT with brand and asset carve-outs that forks must handle.

**bluesky-social/social-app** — The Bluesky Social application for Web, iOS, and Android

- Repository: https://github.com/bluesky-social/social-app
- Website: https://bsky.app
- Stars: 18,313 · Forks: 2,846
- Language: TypeScript
- License: MIT
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/bluesky-social-social-app

## What the Bluesky Social App repository actually contains

This is the client, not the network. The README describes the codebase as the Bluesky Social app for Web, iOS and Android, a React Native application written in TypeScript that builds on the atproto TypeScript packages such as @atproto/api. Those packages live in a different git repository, bluesky-social/atproto, so cloning this project gives you a user interface and its supporting services, not a protocol implementation or a relay.

The repository also carries a small amount of Go source in ./bskyweb/, described as a web service that returns the React Native Web application. Around it sit sibling directories with their own Dockerfiles: bskyembed/, bskylink/ and bskyogcard/. Those are the pieces that render embedded posts, resolve links and generate Open Graph cards for shared URLs. If your interest is server-side social infrastructure, this is the wrong repository; if your interest is the client experience and the web deployment around it, it is the whole thing.

## How the client is assembled: Expo, Metro and the atproto API layer

The app is an Expo project. package.json carries an expo key that pins autolinking behaviour for Android, forcing four modules to build from source: expo-notifications, expo-haptics, expo-media-library and expo-image-picker. It also excludes react-native-reanimated, @sentry/react-native and react-native-pager-view from Expo's install step, which means those dependencies are managed by the project rather than by expo install. That is a deliberate pinning strategy, and it is the first thing that breaks when someone upgrades Expo without reading the file.

Build configuration runs through app.config.js, metro.config.ts and babel.config.js, with eas.json for cloud builds. The postinstall script chains two generators: pnpm lexicons:generate and pnpm intl:compile-if-needed. Lexicons are the schema layer. The README states that the application's schemas and APIs use the namespace app.bsky.*, and the repository holds a lexicons/ directory plus a lexicons.json manifest, so the generated types come from those local definitions rather than from a published package. Internationalisation is handled with Lingui, configured in lingui.config.ts, with translations managed through crowdin.yml.

Environment configuration is explicit and public. .env.example lists the variables the app reads, all prefixed EXPO_PUBLIC_ so that they are inlined into the client bundle: EXPO_PUBLIC_ENV, EXPO_PUBLIC_RELEASE_VERSION, EXPO_PUBLIC_BUNDLE_IDENTIFIER, EXPO_PUBLIC_BUNDLE_DATE, EXPO_PUBLIC_LOG_LEVEL, EXPO_PUBLIC_LOG_DEBUG, EXPO_PUBLIC_BLUESKY_PROXY_DID, EXPO_PUBLIC_CHAT_PROXY_DID, EXPO_PUBLIC_METRICS_API_HOST, EXPO_PUBLIC_GROWTHBOOK_API_HOST, EXPO_PUBLIC_GROWTHBOOK_CLIENT_KEY, EXPO_PUBLIC_SENTRY_DSN, EXPO_PUBLIC_BITDRIFT_API_KEY, GEOLOCATION_DEV_URL, LIVE_EVENTS_DEV_URL and APP_CONFIG_DEV_URL. The comment on EXPO_PUBLIC_BUNDLE_DATE is specific: it should be formatted YYMMDDHH so that it increases for each build. Treat every EXPO_PUBLIC_ value as shipped to the user, because it is.

## Installing dependencies and running the web client locally

The README points to ./docs/build.md as the starting point for building the app. The Makefile shows the dependency step the project uses, and .nvmrc plus the engines field in package.json set the runtime expectations: Node >=24.19.0 and pnpm 11.23.0. The Makefile's own nvm-setup target still installs Node 20, which contradicts package.json. Trust package.json.

```bash
nvm install 24
nvm use 24
npm install --global pnpm
pnpm install --frozen-lockfile
```

The frozen lockfile install also triggers postinstall, which regenerates lexicons and compiles translations if needed. After that, the web target starts Expo's web server.

```bash
pnpm web
```

For a static web bundle instead of a dev server, the Makefile wraps the two steps that matter, compiling translations first and then exporting.

```bash
make build-web
```

Native targets are separate scripts in package.json. pnpm ios runs expo run:ios, pnpm android runs expo run:android --variant debugOptimized, and pnpm prebuild runs expo prebuild --clean with EXPO_NO_GIT_STATUS=1. Before any of these, copy .env.example to .env and fill in the values you actually need. A missing EXPO_PUBLIC_BLUESKY_PROXY_DID or EXPO_PUBLIC_CHAT_PROXY_DID leaves the client without an appview or chat service to talk to, and the README does not document defaults for either.

## Where the build breaks and what the project will not support

The Dockerfile is the clearest statement of the project's fragility. It installs with pnpm install --frozen-lockfile, then runs pnpm intl:build and pipes the output through tee to i18n.log, grepping that log for the string "invalid syntax" and failing the build if it appears. Translation compilation is a build gate, not a warning. If you add strings without updating message catalogues, the image build can fail on a text search.

The contribution rules are unusually blunt, and they matter for planning. The README states that the maintainers may not respond to an issue or PR, may close one without much feedback, and will not provide support for build issues. It names the PRs it does not want: renaming "Post" to "Skeet", refactoring the codebase to swap React Query for Redux Toolkit, and adding entirely new features without prior discussion. The README's own framing is that forking is the intended path for ideas the project will not take. Budget for maintaining your own branch, because upstream review is not a reliable dependency.

On the client side, the .env.example file makes the coupling visible. The app expects a Bluesky appview DID and a chat service DID, plus optional Growthbook, Sentry, Bitdrift and metrics hosts. Point the client at infrastructure you do not control and you inherit those services' availability and their data handling. The README does not document a supported self-hosted appview configuration for this client.

## Forking under MIT: what the license covers and what it does not

The LICENSE file covers the source code in the repository under MIT. It does not cover every file. The README is direct about this: certain images, icons, fonts and brand assets are licensed to Bluesky by third parties, or are trademarks, and are carved out. Required third-party attribution notices are collected in NOTICE.md, and ASSETS.md says which files are affected and what to do.

The fork checklist is concrete. Change all branding in the repository and UI. Change support links for feedback, email and terms of service. Replace analytics and error-collection systems with your own. Replace the landing-screen illustration in assets/illustrations/, which the README describes as commissioned artwork licensed to Bluesky alone. Source your own UI icons, because the glyph set in assets/icons/ is licensed to Bluesky by a third party. Replace the Bluesky logo, app icons and other brand assets, since the trademarks are not licensed with the code. The README notes that ASSETS.md is new and that its earlier absence is why some forks shipped assets they did not have rights to. If you fork, read ASSETS.md and NOTICE.md before you ship, and treat the MIT grant as covering the TypeScript and Go sources rather than the visual identity.

## How this differs from building on atproto directly or using another client

The real alternative is not another social app. It is building against the atproto packages in bluesky-social/atproto, or forking an existing third-party client, and the difference is one of scope. The atproto repository gives you the protocol packages, such as @atproto/api, and the lexicon definitions for the app.bsky.* namespace. This repository gives you a finished Expo application that consumes them, plus the Go web service in bskyweb/ and the embed, link and card services in bskyembed/, bskylink/ and bskyogcard/.

Choosing atproto alone means you write your own navigation, feed rendering, composer, moderation surfaces and notification handling, and you decide your own release pipeline. Choosing this repository means you inherit a large React Native codebase with its Expo autolinking rules, its Lingui translation gate and its environment contract, and you accept the maintenance burden of tracking upstream. The trade is speed against control. A team that wants a custom client experience on the same network should start from atproto. A team that wants the Bluesky client with different branding, or that wants to run the web bundle and its supporting services, should start here and follow the fork guidelines.

## Conclusion

Adopt this repository if you need to build, embed or fork the Bluesky client itself, or to study how a production React Native app is wired to atproto. Do not adopt it if you want a self-contained social server: the README points at the separate atproto repository for the protocol packages, and the app expects an appview DID and a chat service DID through EXPO_PUBLIC_BLUESKY_PROXY_DID and EXPO_PUBLIC_CHAT_PROXY_DID. Before you fork, read ASSETS.md and NOTICE.md, because the MIT license covers the source code but not the illustrations in assets/illustrations/, the icon set in assets/icons/, the fonts, or the Bluesky trademarks.

## FAQ

### What is the Bluesky Social App used for?

It is the client application for Web, iOS and Android, distributed at bsky.app and through the App Store and Play Store. The repository holds the React Native and TypeScript source for that client, plus a small Go web service in bskyweb/.

### How do I download or install the Bluesky Social App?

For end users, the README lists the web app at bsky.app, the iOS build on the App Store and the Android build on the Play Store. For developers, the README points to ./docs/build.md, and package.json requires Node >=24.19.0 with pnpm 11.23.0.

### Is the Bluesky Social App free and open source?

The source code in the repository is MIT licensed, and the README states that the license does not cover every file. Certain images, icons, fonts and brand assets are licensed to Bluesky by third parties or are trademarks, and ASSETS.md lists which ones.

### Can I fork the Bluesky Social App and ship my own version?

The README explicitly grants permission to fork, with conditions: change all branding and support links, replace analytics and error collection, replace the illustration in assets/illustrations/ and the icon set in assets/icons/, and replace the logo and app icons. It also says to read ASSETS.md before shipping.

### Does the Bluesky Social App repository include the AT Protocol implementation?

No. The README states that the app builds on the atproto TypeScript packages, such as @atproto/api, which live in a different git repository, bluesky-social/atproto. This repository holds the client and its supporting web services.

## Sources

- [bluesky-social/social-app on GitHub](https://github.com/bluesky-social/social-app)
- [License: MIT](https://github.com/bluesky-social/social-app/blob/main/LICENSE)
- [Project website](https://bsky.app)
- [README](https://github.com/bluesky-social/social-app/blob/main/README.md)
- [Releases](https://github.com/bluesky-social/social-app/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/bluesky-social-social-app
