tsx@4.21.0 + Node.js v22 has two unfixable interop bugs:
- --import tsx/esm hook: importSyncForRequire fails on @/ path aliases
- tsx runner: @next/env has __esModule:true but no .default export → TypeError
Solution: run SQL migrations directly via psql (alpine + postgresql-client).
All migration files use IF NOT EXISTS guards so they're idempotent on re-run.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
NODE_OPTIONS="--import tsx/esm" registers tsx as a hook, which exposes the
tsx@4.21.0 + Node.js v22 importSyncForRequire bug (named export not found).
Running tsx directly as the process runner handles TypeScript module loading
at a higher level, avoiding the CJS/ESM interop conflict.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add Dockerfile.migrator (node:22-alpine + full source) and
docker-compose.prod.yml `migrate` service (profile: tools) so
migrations can be generated and applied on the server without
Node.js v26/tsx compatibility issues.
Workflow:
# generate migration:
docker compose --profile tools run --rm migrate migrate:create --name <desc>
# apply pending migrations:
docker compose --profile tools run --rm migrate
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>