Meet your true face.
Mira is a front-camera app that shows a live, horizontally un-reversed feed — so you see the face the world actually sees, not the left-right-flipped image an ordinary mirror (or a normal selfie camera) gives you.
A normal mirror, and every selfie camera, flips you left-to-right. You're so used to that reflection that the real, un-flipped you can look subtly "off." Mira shows the un-flipped view by default, and lets you flick back to the familiar mirror to see the difference.
- True / Mirror toggle — flip the live preview between the un-reversed true view (how others see you) and the familiar mirror view.
- Clean-mirror mode — controls auto-hide after a few seconds; tap anywhere to bring them back. At rest it's just an unobstructed, full-screen mirror.
- Freeze & compare — capture one frame and view True | Flipped side-by-side, then save both versions to your photos.
- Capture — save a still to your library, with shutter flash, haptics, and a thumbnail of your last shot.
- Front-camera only, portrait, fully offline (no network, no accounts, no tracking).
The interesting part is the live flip. On Android, expo-camera's mirror prop only flips
the captured photo, never the live preview, and a React Native transform: scaleX(-1)
is ignored by the camera's underlying SurfaceView. Mira flips the preview at the native
layer instead — it mirrors the CameraX PreviewView directly (previewView.scaleX = -1),
applied via a small patch-package patch to
expo-camera (patches/expo-camera+*.patch). On iOS the preview is flipped with a normal
RN transform.
Note: Expo SDK 54 ships expo-camera as a precompiled binary, so the patch only takes effect when the module is built from source. That's enabled via
expo.autolinking.buildFromSourceinpackage.json. Because of this, Mira runs as a native build, not in Expo Go.
- Expo SDK 54 · React Native 0.81 · TypeScript
expo-camera(preview + capture),expo-image-manipulator(mirror the saved frame),expo-media-library(save),expo-haptics,expo-sharing,expo-system-uireact-native-safe-area-context- Fonts via
@expo-google-fonts: Instrument Serif, Hanken Grotesk, Spline Sans Mono
npm install # also applies the expo-camera patch via postinstallPrerequisites: Node (LTS recommended), the Android SDK / Android Studio, and a JDK (17).
Run on a connected device or emulator (builds a dev client — this is not Expo Go):
npm run androidStandalone, installable artifacts (JS bundled in, no Metro needed):
cd android
./gradlew assembleRelease # -> app/build/outputs/apk/release/app-release.apk (sideload)
./gradlew bundleRelease # -> app/build/outputs/bundle/release/app-release.aab (Play upload)Release builds are signed from a gitignored keystore.properties at the repo root:
storeFile=your-upload-key.jks
storePassword=…
keyAlias=…
keyPassword=…Generate an upload key with keytool -genkeypair -v -keystore your-upload-key.jks -alias … -keyalg RSA -keysize 2048 -validity 10000. Keep the keystore and password backed up —
losing them means you can't publish updates. If keystore.properties is absent, the
release falls back to debug signing so the build still succeeds.
android/is generated byexpo prebuildand is gitignored. Re-running prebuild regeneratesandroid/app/build.gradle, which drops the signing block — re-apply it, or move to EAS Build for managed signing.
App.tsx # single screen: permission gate, camera, compare, capture
theme.ts # Mira design tokens (color, radii, fonts)
components/
MiraMark.tsx # the lens + seam + off-center-dot logo
SegmentedToggle.tsx # True | Mirror switch
Toast.tsx # save confirmation
app.json # Expo config (name, icons, permissions, plugins)
patches/ # expo-camera native preview-flip patch
assets/ # icon, adaptive icon, splash, favicon
- Camera — required, the whole point of the app.
- Save to photos / vibrate — to save captures and provide haptic feedback.
Microphone, system-overlay, and audio/video read permissions are explicitly removed
(android.blockedPermissions in app.json). Nothing is collected or sent anywhere.
The identity ("Mira") is defined in design_handoff_mira_brand/ — a warm Ink/Clay/Bone
palette, a serif wordmark, mono labels, and the lens-with-an-off-center-dot symbol (a face
that refuses to be symmetrical). Tokens live in theme.ts.
Application code is released under the MIT License. Fonts are licensed under the
SIL Open Font License via @expo-google-fonts. "Mira", its wordmark, and the logo are brand
assets — you're welcome to fork the code, but please ship your own branding.




