A small React Native todo app, themed with the Coinbase palette and built with
a lightweight functional core (Result and Option monads).
- Create / complete / delete todos
- Inline edit — tap the ✎ pencil to edit a title in place (save on submit/blur, ✓ to confirm, ✕ to cancel)
- Drag to reorder — drag the ☰ handle up or down; other rows slide to show
the drop target (built on
PanResponder+Animated, no extra native deps) - Validation with feedback — empty or over-long (>100 char) titles are rejected with an inline message instead of being silently dropped
- Per-item creation timestamp
- Coinbase theme — Coinbase Blue (
#0052FF) accents, navy text, cool grays
- React Native 0.86, React 19, TypeScript (
strictmode) - Metro bundler (RN default)
react-native-safe-area-context
App.tsx # Root: SafeAreaProvider + StatusBar
src/
TodoApp.tsx # Screen: state, add, validation, list
DraggableTodoList.tsx # Drag-to-reorder list (PanResponder + Animated)
TodoItem.tsx # Row: checkbox, inline edit, drag handle, delete
types.ts # Todo type
result.ts # Result<E,A> (Either) monad
option.ts # Option<A> (Maybe) monad
validateTitle.ts # Title rules composed via Result.flatMap
The domain model avoids null/undefined:
Result<E, A>(src/result.ts) — success or failure.validateTitlecomposes validation rules withflatMap, short-circuiting on the first error.Option<A>(src/option.ts) — presence or absence. Used for nullable state (validation error, drag state) so absence is explicit.
JSX "render nothing" sentinels ({cond ? <X/> : null}) and library-required
nullish values are intentionally left as-is — they're framework idioms, not
domain nulls.
- Node ≥ 22.11 — Metro requires Node 20+. This repo pins Node 24 via
.nvmrc:nvm use # picks up .nvmrc → Node 24 - Android: Android SDK + an emulator (or device). Native builds require
NDK
27.1.12297006and CMake 3.22.x (the versions RN 0.86 expects — newer NDKs are not compatible). Install via Android Studio's SDK Manager (enable Show Package Details to pick the exact NDK version) or:sdkmanager "ndk;27.1.12297006" "cmake;3.22.1"
Start Metro, then build to a device/emulator:
npm start # Metro dev server (port 8081)
npm run android # build + install + launch on Android
# npm run ios # iOS (requires Xcode + `bundle exec pod install`)Edits hot-reload via Fast Refresh.
npm start # Metro
npm run android # run on Android
npm run ios # run on iOS
npm test # Jest
npm run lint # ESLint
npx tsc --noEmit # typecheckconfigs.toReversed is not a functionwhen starting Metro → Node is too old. Runnvm use(Node 24).NDK ... did not have a source.properties file/[CXX1101]→ corrupt or missing NDK. Reinstallndk;27.1.12297006.clang: error: unsupported option '-arch'during the C++ build → wrong NDK version installed. RN 0.86 needs exactly27.1.12297006.