Eigen is Artsy's mobile app — a bare React Native application that uses the Expo sdk, available on both iOS and Android, that powers the Artsy marketplace for discovering and collecting art.
Detailed docs live in docs/ — reference them instead of duplicating here.
- React Native — Cross-platform mobile framework (preferred for all new features)
- TypeScript — Language (strict mode enabled)
- Relay — GraphQL data fetching (hooks preferred over HOCs)
- GraphQL / Metaphysics — Artsy's GraphQL API server
- @artsy/palette-mobile — Design system and reusable component toolkit
- react-navigation — Screen navigation and routing
- Jest — Test runner
- @testing-library/react-native — Component testing
- Formik — Form handling
- FlashList — Performant list rendering (preferred over FlatList)
- react-native-reanimated / Moti — Animations
- react-native-keyboard-controller — Keyboard management (never use RN's built-in
KeyboardAPI) - Yarn 4 — Package manager
- CircleCI / GitHub Actions — CI/CD and builds
- Objective-C / Swift / Kotlin / Java — Native bridging and platform-specific features only
yarn type-check— Run Relay compiler + TypeScript checkyarn relay— Compile Relay GraphQL queriesyarn test <path>— Run Jest tests for specific filesyarn lint --fix <path>— Lint and auto-fix TypeScript filesyarn start— Start Metro bundler + Relay watcheryarn ios:no-cache— Run iOS app in simulatoryarn ios— Run iOS app in simulator with build cachingyarn android:cached— Run Android app in emulator (uses cached build)yarn android— Run Android app in emulator (full rebuild)
Before every commit, verify code quality on changed files:
yarn tsc
yarn test --findRelatedTests <changed-files>
yarn lint <changed-files>Never commit code that fails these checks. The repo uses lint-staged via a husky pre-commit hook.
@docs/best_practices.md
src/
├── app/
│ ├── Scenes/ # Top-level screens (PascalCase: Artwork, Search, Sale, etc.)
│ │ └── MyScreen/
│ │ ├── MyScreen.tsx
│ │ ├── Components/ # Screen-specific components
│ │ ├── hooks/ # Screen-specific hooks and mutations
│ │ ├── utils/ # Screen-specific utilities
│ │ └── __tests__/
│ ├── Components/ # Shared components across scenes
│ ├── Navigation/ # Route definitions and navigation setup
│ ├── NativeModules/ # Native bridge modules
│ ├── store/ # Global state management
│ ├── system/ # Framework-level code (navigation helpers, etc.)
│ └── utils/ # Shared utilities
├── __generated__/ # Relay-generated artifacts (do not edit)
data/
├── schema.graphql # Metaphysics GraphQL schema
└── complete.queryMap.json # Relay persisted queries
docs/ # Project documentation
ios/ # iOS native code and Xcode workspace
android/ # Android native code and Gradle project
- Do not import components/hooks/functions directly from a different Scene — extract shared code to
src/app/Components/orsrc/app/utils/ - When adding a screen with a corresponding artsy.net page, match the route path and enable deep linking (add to
AndroidManifest.xmlfor Android) - Use independent
NavigationContainerstacks for context-specific flows (multi-step forms, modal sequences) rather than adding global routes - Run
yarn relayafter modifying any GraphQL queries or fragments - Sync the GraphQL schema with
yarn sync-schemawhen Metaphysics changes
yarn pod-installmay fail on first run due to a cocoapods-keys bug — re-run to fix- Legacy
@ts-expect-error STRICTNESS_MIGRATIONcomments exist throughout the codebase — remove them when touching affected code, but only if it's a straightforward change. - Relay artifacts go in
src/__generated__/(configured inrelay.config.js) — never edit these - Some native screens still exist in Obj-C/Swift (Live Auctions, AR View In Room)