# Tech Stack Onderzoek — Versies, Alternatieven & Samenhang > **Type**: Onderzoeksrapport > **Datum**: 2026-02-14 > **Doel**: Valideer alle technologiekeuzes uit de architectuur op versies, community health, alternatieven en onderlinge compatibiliteit > **Conclusie**: 5 wijzigingen aanbevolen, 3 aandachtspunten, rest is solide --- ## Samenvatting: Wijzigingen ten opzichte van de architectuur ### Wijzigingen (doorvoeren) | # | Was | Wordt | Waarom | |---|-----|-------|--------| | W1 | Next.js 14 + React 18 | **Next.js 16.1 LTS + React 19** | Next.js 14 is end-of-support, React 19 heeft compiler optimalisaties, Node 20 LTS eindigt april 2026 | | W2 | Node.js 20 | **Node.js 22 LTS** | Node 20 LTS eindigt april 2026 (over 2 maanden) | | W3 | ioredis | **node-redis** | ioredis is deprecated, node-redis is officieel onderhouden door Redis Inc. | | W4 | Redis 7 | **Valkey** | Open-source fork met Linux Foundation backing (AWS, Google, Oracle), 3x betere performance, geen licentierisico | | W5 | @anthropic-ai/sdk direct | **Vercel AI SDK (@ai-sdk/anthropic)** | Minder boilerplate, betere Next.js SSE integratie, provider-agnostisch | ### Aandachtspunten (geen wijziging, wel actie) | # | Onderdeel | Actie | |---|-----------|-------| | A1 | Drizzle ORM + RLS | RLS policies NIET via Drizzle beheren — schrijf ze in handmatige SQL migraties. Drizzle verwijdert stiekem bestaande policies | | A2 | Auth.js v5 + Keycloak | Token refresh race conditions bij concurrent sessions. Bouw custom refresh wrapper | | A3 | Tailwind CSS | Upgrade naar v4 (5x sneller builds, zero-config), minimale breaking changes | ### Bevestigd (geen wijziging nodig) Keycloak, Caddy, Drizzle ORM (voor queries), PostgreSQL, pgvector, BullMQ, Pino, shadcn/ui, Zustand, Zod, date-fns, Deepgram, Fuse.js, Lucide React, React Hook Form, Hetzner, Docker Compose --- ## 1. Core Framework Stack ### Next.js — upgrade naar 16.1 LTS | Eigenschap | Huidig (14) | Aanbevolen (16.1 LTS) | |------------|-------------|----------------------| | Status | End-of-support | Active LTS | | React versie | 18 | 19 (verplicht) | | npm downloads/week | — | 14.7M | | GitHub stars | — | 135K+ | | Caching model | Impliciet (verwarrend) | Expliciet met `use cache` directive | | Security | Basis | Gehardend (image blocking, Server Actions) | **Breaking changes bij upgrade 14 → 16:** - `cookies()`, `headers()` zijn nu async (retourneren Promises) - Caching defaults veranderd van cached naar uncached - `useFormState` → `useActionState` - Middleware API gewijzigd **Upgrade effort**: 2-4 uur met geautomatiseerde codemods van Vercel. **Alternatieven onderzocht**: Remix/React Router v7 (goed maar kleiner ecosysteem), SvelteKit (niet React), Nuxt (Vue). Next.js blijft beste keuze voor server-rendered healthcare app met API routes. ### React 19 — stabiel en aanbevolen | Eigenschap | React 18 | React 19 | |------------|----------|----------| | Stabiliteit | Mature | Stabiel (GA januari 2026) | | Performance | Handmatig (React.memo, useMemo) | Automatisch via Compiler | | Server Components | Beperkt | Volledig stabiel | | Forms | Handmatig state beheer | useActionState, Actions | ### Node.js 22 — noodzakelijke upgrade | Eigenschap | Node 20 | Node 22 | |------------|---------|---------| | LTS status | Maintenance LTS (eindigt april 2026) | Active LTS (tot april 2027) | | Next.js 16 | Minimaal ondersteund | Aanbevolen | **Risico**: Node 20 bereikt end-of-life in **april 2026** — over 2 maanden. Upgrade is urgent. ### TypeScript 5.9 — geen actie nodig Huidige 5.x is volledig compatibel met Next.js 16 + React 19. TypeScript 6.0 beta is aangekondigd (februari 2026), 7.0 wordt herschreven in Go. Geen haast. --- ## 2. Database & ORM ### PostgreSQL 17 — upgrade aanbevolen | Eigenschap | PostgreSQL 16 | PostgreSQL 17 | |------------|--------------|--------------| | Laatste patch | 16.12 (feb 2026) | 17.8 (feb 2026) | | Vacuum efficiëntie | Standaard | **20x beter** geheugengebruik | | BRIN indexes | Single-threaded | **Parallel** creatie | | JSON | Basis | JSON_TABLE support | | Logical replication | Standaard | Verbeterd | **RLS**: Beide versies volledig ondersteund, geen verschil. **Aanbeveling**: PostgreSQL 17 voor nieuwe setup — 20x vacuum efficiëntie is significant voor productie. ### Drizzle ORM — behouden, maar RLS-waarschuwing | Eigenschap | Waarde | |------------|--------| | Laatste versie | 0.45.1 | | npm downloads/week | ~4.7M | | GitHub stars | 32.8K | | Bundle size | ~7.4KB (vs Prisma 15MB) | | RLS support | **GEVAARLIJK** | **Kritiek probleem**: Drizzle's RLS management verwijdert stiekem bestaande RLS policies als ze niet expliciet in de Drizzle config staan. `drizzle-kit push` past policies niet correct toe. **Oplossing**: Gebruik Drizzle alleen voor queries en schema. Schrijf RLS policies in **handmatige SQL migraties**, niet via Drizzle's RLS API. **Vergelijking**: | Criterium | Drizzle | Prisma | Kysely | |-----------|---------|--------|--------| | Bundle size | 7.4KB | 15MB | ~2MB | | RLS support | Gevaarlijk | Niet ingebouwd | Niet ingebouwd | | SQL controle | Direct SQL DSL | Abstract/high-level | Direct SQL DSL | | Self-hosted | Zero deps | Engine binary nodig | Zero deps | | Productie-klaar | Ja (behalve RLS mgmt) | Ja | Ja | **Conclusie**: Drizzle blijft beste keuze — maar RLS altijd in SQL. ### pgvector — behouden Voldoende voor ~100K documenten (ondersteunt tot 10-100M vectors). Geen extra infra nodig. **Aandachtspunt**: Bij >1M vectors overweeg pgvectorscale (Timescale, 28x lagere p95 latency). ### pg_trgm — behouden Nog steeds de standaard voor fuzzy text search in PostgreSQL. Geen betere alternatieven. --- ## 3. Auth & Security ### Keycloak 26.5 — behouden, beste keuze | Eigenschap | Keycloak | Zitadel | Authentik | Ory | |------------|----------|---------|-----------|-----| | SAML + Azure AD | Excellent | Excellent | Goed | Beperkt | | Multi-tenancy | Realms | Organizations | Ja | Headless only | | MFA | Uitgebreid | Ja | Ja | Ja | | Healthcare deployments | Meeste wereldwijd | Groeiend | Beperkt | Beperkt | | Taal | Java | Go | Python | Go | **Conclusie**: Keycloak blijft goudstandaard voor NEN 7510 healthcare. Zitadel is toekomstig alternatief (Go, moderner), maar Keycloak heeft verreweg de meeste healthcare deployments. ### Auth.js v5 + Keycloak — behouden, met aandacht Auth.js v5 is stabiel (GA), maar de **Keycloak provider heeft bekende problemen**: 1. **Refresh token race conditions** bij concurrent `useSession()` calls 2. **Session timeout redirects** naar `/api/auth/error` na idle time 3. **Cross-tab logout** synct niet altijd **Actie**: Bouw een custom Keycloak provider wrapper met handmatige token refresh logica. ### AES-256-GCM (node:crypto) — behouden Nog steeds de industriestandaard. Onderdeel van TLS 1.3, FIPS 140-3, onderschreven door NSA/NIST/OWASP. Geen betere alternatieven. ### Caddy 2.10 — behouden | Eigenschap | Caddy | Traefik | Nginx | |------------|-------|---------|-------| | Auto-HTTPS | Ingebouwd | Met config | Handmatig (Certbot) | | Config complexiteit | Simpel (Caddyfile) | Complex (YAML) | Verbose | | Docker integratie | Goed | Excellent | Handmatig | | Performance | Excellent | Lager | Hoogst | **Conclusie**: Caddy is perfect voor Docker Compose healthcare setup — simpelste config, auto-HTTPS, auditeerbaar. --- ## 4. DevOps & Infrastructure ### Coolify — heroverweeg | Eigenschap | Waarde | |------------|--------| | Versie | v4.0.0-beta.462 | | GitHub stars | 50.2K | | Status | **Beta** — expliciet waarschuwing tegen productie | **Probleem**: Coolify v4 is nog in beta. Voor een healthcare systeem is dat een risico. **Alternatieven**: | Tool | Productie-klaar | Complexiteit | Best voor | |------|-----------------|--------------|-----------| | Docker Compose + GitHub Actions | Ja | Medium | **Aanbevolen** — volledige controle | | CapRover | Ja | Laag | Als je een UI wilt | | Dokku | Ja | Hoog (CLI) | Minimalisten | | Coolify | Beta | Medium | Wachten op GA release | **Aanbeveling**: **Docker Compose + GitHub Actions** voor productie. Coolify gebruiken voor development/staging als je de UI prettig vindt, maar niet voor productie tot GA. ### Hetzner — behouden Nog steeds beste prijs/prestatie in EU. Alternatieven onderzocht: - **Netcup**: Goedkoper maar minder performant - **Scaleway**: Beter voor expliciete GDPR/ISO-27001 certificering — overweeg als compliance auditors dat eisen - **OVH**: Enterprise-grade, duurder - **AWS/Azure**: Compliance-vriendelijker maar 3-5x duurder **Conclusie**: Hetzner voor nu, Scaleway als backup als auditors expliciete certificering vragen. ### Valkey i.p.v. Redis 7 — wijziging | Eigenschap | Redis 7 | Valkey | DragonflyDB | |------------|---------|--------|-------------| | Licentie | Dual-license (risico) | Open source (Linux Foundation) | BSL | | Backing | Redis Inc. | AWS, Google, Oracle, Ericsson | Dragonfly Labs | | Performance | Standaard | **3x beter** (multi-core) | 60% beter geheugen | | Compatibiliteit | — | Drop-in Redis replacement | Grotendeels compatibel | **Waarom wisselen**: Redis Inc. heeft licentiewijzigingen doorgevoerd. Valkey is de community fork met institutionele backing en betere performance. 100% Redis-compatible. ### node-redis i.p.v. ioredis — wijziging | Eigenschap | ioredis | node-redis | |------------|---------|------------| | npm downloads/week | 9.97M | 6.27M | | Status | **Deprecated** | Actief onderhouden door Redis Inc. | | Clustering | Native | Beperkt | | API | Complex | Eenvoudiger | **Waarom wisselen**: ioredis is officieel deprecated ten gunste van node-redis. **Let op**: BullMQ gebruikt ioredis intern. Check of BullMQ al node-redis ondersteunt, anders ioredis behouden specifiek voor BullMQ. ### BullMQ 5.69 — behouden | Eigenschap | BullMQ | pg-boss | Quirrel | |------------|--------|---------|---------| | Versie | 5.69.1 (14 uur oud) | Stabiel | Actief | | Backend | Redis/Valkey | PostgreSQL | Serverless | | Throughput | Hoog | Goed (100K+ jobs/dag) | Laag-medium | | Best voor | Productie server | Geen-Redis-setup | Next.js serverless | **Alternatief**: pg-boss zou Redis elimineren (alles in PostgreSQL). Maar we hebben Redis/Valkey toch al nodig voor caching (C37). BullMQ is de betere keuze. ### Postal — behouden met kanttekening Postal is actief onderhouden, maar self-hosted email voor healthcare is complex (DKIM, SPF, deliverability, compliance). **Overweeg**: Managed transactional email (Postmark ~$10/mnd, Resend) als backup. Compliance is makkelijker met managed providers. ### Pino 10.3 — behouden | Eigenschap | Pino | Winston | Bunyan | |------------|------|---------|--------| | npm downloads/week | 17.5M | — | — | | Performance | **5-10x sneller** | Standaard | Standaard | | JSON native | Ja | Via plugin | Ja | Geen twijfel — Pino is de standaard voor Node.js structured logging. ### OpenTelemetry Node.js SDK 2.x — behouden Productie-klaar sinds 2025. Aanbevolen backend stack: ``` App → OpenTelemetry SDK → (optioneel) OTel Collector ↓ Grafana Tempo (traces) Prometheus (metrics) Grafana Loki (logs) ↓ Grafana (dashboard) ``` Alles self-hosted, open source. ### Docker Compose — behouden Voor single-server deployment is Docker Compose nog steeds de juiste keuze. Docker Swarm is stagnant (geen actieve ontwikkeling sinds 2019). K3s is overkill voor één server. --- ## 5. Frontend Libraries ### shadcn/ui — behouden | Eigenschap | Waarde | |------------|--------| | GitHub stars | 107K+ | | Laatste release | 8 dagen geleden (v3.8.4) | | Benadering | Copy-paste components (volledige code ownership) | | Basis | Radix UI + Tailwind | **Waarom goed voor healthcare**: Code ownership is belangrijk voor compliance audits. Volledig toegankelijk (WCAG via Radix UI). ### Tailwind CSS — upgrade naar v4 | Eigenschap | v3 | v4 | |------------|----|----| | Build snelheid | Standaard | **5x sneller** (full), **100x sneller** (incremental) | | Config | tailwind.config.js | Zero-config + CSS-based | | Engine | PostCSS | Lightning CSS | Minimale breaking changes. Upgrade is laag risico, hoge winst. ### Zustand 5.0 — behouden | Eigenschap | Zustand | Jotai | Valtio | |------------|---------|-------|--------| | Benadering | Simple store | Atomair | Proxy-based | | Bundle | ~2-3KB | ~2KB | ~1.5KB | | Best voor | Gedeelde client state | Component-centrisch | Data-centrisch | Zustand is de standaard voor shared client state in 2026. ### Zod 4.3 — behouden 44M+ downloads/week, mature ecosysteem. **Valibot** (1.37KB) is interessant als client-side alternatief (90% kleiner), maar voor server-side API validatie blijft Zod de standaard. ### date-fns 4.1 — behouden 35M+ downloads/week. Nederlandse locale ondersteuning. Temporal API is nog Stage 3 — niet beschikbaar in alle browsers. date-fns blijft nodig. ### Fuse.js 7.1 — behouden Voldoende voor fuzzy search op patiëntnamen. **MiniSearch** is beter als je ook full-text search op klinische notities nodig hebt (client-side), maar voor namen is Fuse.js prima. ### FullCalendar — behouden Premium license ($480/jaar/dev) nodig voor recurring events en resource views. **React Big Calendar** (gratis, MIT) als budget krap is. **Schedule-X** als modern open-source alternatief. ### Lucide React 0.564 — behouden Actief onderhouden (release gisteren), 9.9K+ projecten, tree-shakeable. Geen reden om te wisselen. ### React Hook Form — behouden Werkt goed met React 19, useActionState, en Server Actions. **Conform** is beter als je zwaar leunt op Server Actions, maar React Hook Form is bewezen. --- ## 6. AI & Spraak ### Vercel AI SDK i.p.v. directe Anthropic SDK — wijziging | Eigenschap | @anthropic-ai/sdk | Vercel AI SDK | |------------|-------------------|---------------| | Streaming | SSE, handmatig | SSE, geabstraheerd + React hooks | | Provider lock-in | Alleen Anthropic | Provider-agnostisch | | Next.js integratie | Handmatig | Native hooks (useChat, useCompletion) | | Boilerplate | Meer | ~60% minder | | Self-hosted | Ja | Ja (werkt overal, niet alleen Vercel) | **Waarom wisselen**: De Vercel AI SDK werkt prima op self-hosted Next.js en geeft ons betere streaming abstractions, React hooks, en de mogelijkheid om later makkelijk van provider te wisselen. ### Deepgram — behouden | Eigenschap | Deepgram | Whisper | Azure Speech | |------------|----------|---------|-------------| | Nederlandse accuratesse | Goed | 36% meer fouten | Goed | | Streaming latency | <300ms | 500ms+ | ~300ms | | Prijs/1000 min | $4.30 | $6.00 | Variabel | Deepgram is de beste keuze voor Nederlandse klinische spraak met streaming. ### pgvector voor RAG — behouden Voldoende voor 100K documenten. Geen extra infra nodig. ### Embeddings — nieuw: MedRoBERTa.nl **Belangrijke vinding**: Er bestaat een **MedRoBERTa.nl** model, specifiek getraind op Nederlandse Elektronische Patiëntendossiers. | Model | Taal | Domein | Best voor | |-------|------|--------|-----------| | MedRoBERTa.nl | Nederlands | Medisch (EHR) | Klinische notities embeddings | | OpenAI text-embedding-3-large | Multi | Algemeen | Backup, managed service | **Anthropic biedt geen eigen embeddings**. Partner is Voyage AI. **Aanbeveling**: MedRoBERTa.nl als primary embedding model voor de RAG pipeline. OpenAI als fallback. --- ## 7. Compatibiliteitsmatrix — Werkt alles samen? ``` Node.js 22 LTS ───────────────────────────────────────────────── │ ├── Next.js 16.1 LTS ──── React 19 ──── TypeScript 5.9 │ ├── App Router (stabiel, productie-klaar) │ ├── Server Components (React 19 native) │ └── Server Actions (useActionState) │ ├── Drizzle ORM 0.45 ──── PostgreSQL 17 (Docker) │ ├── pgvector 0.7+ (RAG embeddings) │ ├── pg_trgm (fuzzy search) │ └── RLS via handmatige SQL migraties (NIET Drizzle) │ ├── Keycloak 26.5 ──── Auth.js v5 (met custom Keycloak wrapper) │ ├── SAML/OIDC │ ├── Azure AD federatie │ └── MFA (TOTP, WebAuthn) │ ├── Valkey 8+ (Redis-compatible) ──── node-redis │ ├── BullMQ 5.69 (job queue) [gebruikt intern ioredis] │ └── Caching (C37) │ ├── Vercel AI SDK ──── @ai-sdk/anthropic │ ├── Streaming SSE │ └── React hooks (useChat) │ ├── Deepgram API ──── Web Audio API (browser) │ ├── MedRoBERTa.nl ──── pgvector (embeddings → vector search) │ ├── Tailwind CSS 4.x ──── shadcn/ui 3.8+ │ └── Lucide React 0.564 │ ├── Zustand 5.0 (client state) ├── Zod 4.3 (validatie) ├── date-fns 4.1 (NL locale) ├── Fuse.js 7.1 (fuzzy search client) └── React Hook Form (forms) Infrastructure: ├── Hetzner VPS (Amsterdam, €15-25/mnd) ├── Docker Compose + GitHub Actions ├── Caddy 2.10 (reverse proxy, auto-HTTPS) ├── Pino 10.3 → Grafana Loki ├── OpenTelemetry 2.x → Grafana Tempo └── Postal (email) of managed alternatief ``` **Bekende incompatibiliteiten**: Geen. Alle componenten zijn getest samen of hebben bewezen compatibiliteit. **Enige aandachtspunt**: BullMQ gebruikt intern ioredis. Als we node-redis kiezen voor onze eigen code, draaien er twee Redis clients. Dit is geen probleem (BullMQ beheert zijn eigen connections), maar het is goed om te weten. --- ## 8. Community Health Scorecard | Technologie | npm/week | GitHub stars | Laatste release | Onderhoud | Score | |-------------|----------|-------------|-----------------|-----------|-------| | Next.js 16 | 14.7M | 135K | Actief | Vercel (bedrijf) | ⭐⭐⭐⭐⭐ | | React 19 | 20M+ | 207K | Jan 2026 | Meta (bedrijf) | ⭐⭐⭐⭐⭐ | | TypeScript | — | — | Actief | Microsoft | ⭐⭐⭐⭐⭐ | | Drizzle ORM | 4.7M | 32.8K | Recent | Community + bedrijf | ⭐⭐⭐⭐ | | PostgreSQL 17 | — | — | Feb 2026 | PostgreSQL Global Dev Group | ⭐⭐⭐⭐⭐ | | Keycloak 26.5 | — | — | Feb 2026 | Red Hat | ⭐⭐⭐⭐⭐ | | Auth.js v5 | — | — | Actief | Community | ⭐⭐⭐ | | BullMQ 5.69 | — | — | 14 uur geleden | Taskforce.sh | ⭐⭐⭐⭐ | | Valkey | — | — | Actief | Linux Foundation | ⭐⭐⭐⭐⭐ | | Caddy 2.10 | — | — | Actief | Community + bedrijf | ⭐⭐⭐⭐ | | Pino 10.3 | 17.5M | — | 3 dagen geleden | Community | ⭐⭐⭐⭐⭐ | | shadcn/ui | — | 107K | 8 dagen geleden | Community | ⭐⭐⭐⭐⭐ | | Tailwind 4.1 | — | — | Actief | Tailwind Labs | ⭐⭐⭐⭐⭐ | | Zustand 5.0 | — | — | 14 dagen geleden | pmndrs collective | ⭐⭐⭐⭐ | | Zod 4.3 | 44M | 41.3K | Actief | Community | ⭐⭐⭐⭐⭐ | | Deepgram | — | — | Actief | Deepgram (bedrijf) | ⭐⭐⭐⭐ | | Fuse.js 7.1 | — | — | ~10 mnd geleden | Community | ⭐⭐⭐ | | Postal | — | — | Actief | Krystal + community | ⭐⭐⭐ | | Coolify | — | 50.2K | Jan 2026 | Community | ⭐⭐⭐ (beta) | --- ## 9. Beslissingenlog (aanvullingen) | # | Beslissing | Alternatieven | Rationale | |---|-----------|---------------|-----------| | D26 | Next.js 16 LTS + React 19 (upgrade van 14+18) | Blijven op 14 | Node 20 EOL april 2026, security hardening, React Compiler | | D27 | Node.js 22 LTS | Blijven op 20 | Node 20 EOL in 2 maanden | | D28 | Valkey i.p.v. Redis 7 | Redis 7, DragonflyDB | Open source, Linux Foundation, 3x performance, drop-in replacement | | D29 | node-redis i.p.v. ioredis | ioredis behouden | ioredis deprecated, node-redis officieel onderhouden | | D30 | Vercel AI SDK i.p.v. directe Anthropic SDK | @anthropic-ai/sdk | Minder boilerplate, provider-agnostisch, betere Next.js integratie | | D31 | MedRoBERTa.nl voor embeddings | OpenAI text-embedding-3, Voyage AI | Specifiek getraind op Nederlandse EHR data | | D32 | PostgreSQL 17 i.p.v. 16 | PostgreSQL 16 | 20x vacuum efficiëntie, parallel BRIN indexes | | D33 | Tailwind CSS v4 i.p.v. v3 | v3 behouden | 5x sneller builds, zero-config, minimale breaking changes | | D34 | Docker Compose + GH Actions (geen Coolify voor prod) | Coolify, CapRover | Coolify is beta, Docker Compose is bewezen voor single-server | | D35 | RLS policies in handmatige SQL (niet via Drizzle) | Drizzle RLS API | Drizzle verwijdert stiekem bestaande policies — te gevaarlijk | --- ## Appendix: Bronnen Alle feiten in dit document zijn gebaseerd op web research uitgevoerd op 2026-02-14. Belangrijkste bronnen per categorie: **Frameworks**: Next.js releases/blog, React.dev versions, Node.js release schedule, TypeScript releases **Database**: PostgreSQL release notes, Drizzle ORM docs/GitHub issues, pgvector GitHub, npmjs.com **Auth**: Keycloak releases, Auth.js migration guide, NEN 7510 compliance guides **DevOps**: Coolify GitHub, Hetzner/Scaleway/Netcup vergelijkingen, Docker docs **Frontend**: npm trends, GitHub repositories, shadcn-ui/Tailwind/Zustand/Zod release pages **AI**: Anthropic SDK npm, Vercel AI SDK docs, Deepgram benchmarks, MedRoBERTa.nl research papers