Dependencies and how long they last¶
Checked on 2026-08-21. Support dates are the kind of fact that is easy to remember wrongly, so every one here was read from a source rather than recalled, and the sources are at the bottom. Anything unverified says so.
The point of this page is not the inventory — package.json and
pyproject.toml are the inventory. It is the horizon: what forces an
upgrade, and when.
The clock that matters most¶
| What | Deadline | Why it bites |
|---|---|---|
| Google Play target API 36 | 31 Aug 2026 (extension to 1 Nov 2026) | New apps and updates must target Android 16. We already comply — Expo SDK 54 targets API 36 |
| Node 22 maintenance ends | 30 Apr 2027 | Build tooling only; nothing ships to a user |
| Postgres 16 end of life | 09 Nov 2028 | Neon would migrate long before |
| Python 3.12 security-only until | 31 Oct 2028 | The container pins 3.12 |
Nothing here is urgent. The one with a date inside the next year is the Play requirement, and Expo has already handled it.
Mobile¶
| Package | Version | Notes |
|---|---|---|
| Expo SDK | 54 | Released 10 Sep 2025. Three releases behind: 57 is current. Expo ships three SDKs a year |
| React Native | 0.81.5 | What SDK 54 pins |
| React | 19.1.0 | What SDK 54 pins |
| Node (build) | 22.23.1 local | SDK 54 requires ≥ 20.19.4 |
| Android target | API 36 (Android 16) | From SDK 54 |
| Android minimum | API 24 | Anything newer than that in the native module compiles and fails at runtime; native.yml's lintDebug (NewApi) is what catches it at build time — see gotchas |
@sentry/react-native |
7.2.x | |
expo-video |
3.0.x | Replaced expo-av, which is deprecated |
zustand |
5.0.x |
What forces an Expo upgrade. Not age by itself. In order of likelihood: a new Play target-API deadline that SDK 54 does not meet; Expo Go, which only ever ships the newest SDK and is therefore already unusable here; and EAS Build eventually dropping old SDKs, which happens but is not on a published schedule.
Upgrading is not free. SDK upgrades have moved native APIs under this
project before — expo-av to expo-video, expo-file-system to its /legacy
entry point. Budget a build cycle and read the changelog for the camera and
media modules specifically.
Backend¶
| Package | Constraint | Notes |
|---|---|---|
| Python | >=3.11, container runs 3.12 |
3.12 gets security fixes until 31 Oct 2028 |
| FastAPI | >=0.115 |
Pre-1.0; minor releases can still break |
| SQLAlchemy | >=2.0.36 |
|
| Alembic | >=1.14 |
|
| psycopg | >=3.2 |
Prepares statements — see the note about connection pooling in gotchas |
| Pydantic | >=2.9 |
|
| boto3 / botocore | >=1.35 |
1.36 changed upload checksum defaults and broke presigned PUTs to R2. Pinned behaviour, not version — see app/services/storage.py |
| APScheduler | >=3.10 |
In-process, which is why there can only be one machine |
| sentry-sdk | >=2.18 |
|
| PostgreSQL | 16 | EOL 09 Nov 2028. Neon runs 16.15 |
The local development database is postgres:16-alpine, deliberately the same
major version as production: a difference there is the kind of bug that only
appears in production.
Already dead, and what replaced it¶
Worth knowing so nobody reintroduces them.
- FCM Legacy API — shut down by Google in 2024. The
eas credentialsmenu still offers it, directly above the option that works. Use FCM V1 with a Google service account key. expo-av— deprecated; this project usesexpo-video.ffmpeg-kit-react-native— deprecated and its binaries withdrawn from Maven Central. This is why the native engine is written against MediaCodec directly rather than wrapping FFmpeg.- Expo Go for this project — it ships only the newest SDK. Use a development build.
What is pinned, and what is not¶
pyproject.toml declares >= ranges as the source of truth — the same
constraints listed above — and backend/requirements.lock (committed,
regenerated with uv pip compile pyproject.toml -o requirements.lock) pins the
exact resolved set that backend/Dockerfile installs in its deps stage. A
rebuild of the same git tag installs the same dependency graph; the botocore
checksum change that arrived unannounced predates the lock file.
requirements.lock is the only lock file that counts. A backend/uv.lock may
appear if you run uv commands in backend/; it is gitignored, nothing
installs from it, and it is not kept in step with anything.
The mobile side is pinned by package-lock.json and by Expo's own version
constraints, which is stricter.