21 KiB
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:
- Refresh token race conditions bij concurrent
useSession()calls - Session timeout redirects naar
/api/auth/errorna idle time - 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