Files
triqura-ecd/docs/architecture/tech-stack-onderzoek.md
2026-07-09 23:16:28 +02:00

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
  • useFormStateuseActionState
  • 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