Public knowledge base for the new Dutch Code of Criminal Procedure (Wetboek van Strafvordering)
  • JavaScript 61.3%
  • TypeScript 11.7%
  • XQuery 11.1%
  • Java 9.2%
  • XSLT 5.5%
  • Other 1.1%
Find a file
2026-08-12 14:03:02 +02:00
basex Public release v1.4.1: fulltext document search, search relevance overhaul and WCAG accessibility fixes, performance improvements, small fixes 2026-08-12 14:03:02 +02:00
data-importer Initial public release 2026-06-23 13:01:26 +02:00
documents Public release v1.4.1: fulltext document search, search relevance overhaul and WCAG accessibility fixes, performance improvements, small fixes 2026-08-12 14:03:02 +02:00
frontend Public release v1.4.1: fulltext document search, search relevance overhaul and WCAG accessibility fixes, performance improvements, small fixes 2026-08-12 14:03:02 +02:00
scripts/verify-content Initial public release 2026-06-23 13:01:26 +02:00
.env.example Initial public release 2026-06-23 13:01:26 +02:00
.gitignore Initial public release 2026-06-23 13:01:26 +02:00
LICENSE Initial public release 2026-06-23 13:01:26 +02:00
Makefile Public release v1.4.1: fulltext document search, search relevance overhaul and WCAG accessibility fixes, performance improvements, small fixes 2026-08-12 14:03:02 +02:00
README.md Initial public release 2026-06-23 13:01:26 +02:00

KWEST - Kennisbank Nieuw Wetboek van Strafvordering

Language / Taal: English | Nederlands


English

KWEST is a public, web-based knowledge base for browsing and searching the new Dutch Code of Criminal Procedure (Wetboek van Strafvordering). It presents the consolidated law text, the explanatory memorandum (memorie van toelichting), transposition tables between the old and new law, a glossary of legal terms, and a library of related parliamentary documents through an accessible interface.

The application is live in production at https://kwest.overheid.nl. The API specification is available at https://kwest.overheid.nl/api/swagger-ui.

The application is fully public; there is no end-user authentication.

Repository structure

This is a monorepo with four main components:

Path What it is Stack
frontend/ Web interface for browsing and searching the knowledge base React, TypeScript, Vite, CSS
basex/ XML database + RESTXQ API serving the legal content BaseX, XQuery, XSLT, Docker
data-importer/ Converts source documents (DOCX/XLSX/XML) into the XML the database loads Java 11, Gradle
documents/ Software Bill of Materials and project documentation -
scripts/verify-content/ Node tool that verifies API responses against the source content Node.js

Each component has its own README with detailed documentation:

Architecture

                ┌─────────────────────┐          ┌──────────────────────┐
   Browser ────▶│  Frontend           │─────────▶│  BaseX               │
                │  (React + Vite)     │  /api/*  │  (XML DB + RESTXQ)   │
                │  Nginx serves SPA   │  proxy   │  legal content + API │
                └─────────────────────┘          └──────────┬───────────┘
                                                            │ loads
                                                 ┌──────────▼────────────┐
                                                 │  XML source files     │
                                                 │  (wet.xml, toelichting│
                                                 │   begrippen, …)       │
                                                 └──────────▲────────────┘
                                                            │ generates
                                                 ┌──────────┴───────────┐
                                                 │  Data Importer (Java)│
                                                 │  DOCX / XLSX / XML ->│
                                                 └──────────────────────┘

In production only the frontend container is public-facing; its Nginx config proxies an allowlist of /api/* routes to BaseX. The BaseX HTTP port should never be exposed directly to the internet.

Prerequisites

  • Docker and Docker Compose (to run BaseX and the full stack)
  • Node.js 20+ (for the frontend)
  • JDK 11+ (only to run the data-importer; a Gradle wrapper is included)

Quick start

The frontend always talks to a BaseX backend (there is no mock-data mode), so start BaseX first, then the frontend.

Frontend dev server

cd frontend
npm install
npm run dev        # Vite dev server on http://localhost:5173

The dev server proxies /api/* to KWEST_API_TARGET (default http://localhost:8080). Either run BaseX locally on port 8080 (see below) or set KWEST_API_TARGET in frontend/.env to point at a running backend.

Full stack (frontend + BaseX) with Docker

# 1. Start BaseX (XML database + API)
cd basex
cp .env.example .env          # then edit: set BASEX_ADMIN_PASSWORD, BASEX_KWEST_PASSWORD
docker compose up -d --build
curl http://localhost:8080/versie   # verify the API is up

# 2. Start the frontend (in another terminal)
cd ../frontend
cp .env.example .env          # then edit: set KWEST_API_TARGET=http://localhost:8080
docker compose up -d --build
# open http://localhost

By default the BaseX database initializes from the sample XML in basex/data/. See the BaseX README for re-initializing with your own XML, running the test suite (./scripts/run-tests.sh), and the full REST API reference.

Regenerating the source XML (optional)

The XML the database loads is produced by the data-importer from the source documents in data-importer/data/:

cd data-importer
./gradlew build
./gradlew run --args="--help"     # see all import options
./gradlew run                     # generate all outputs

Configuration

Each component is configured through environment variables documented in its own .env.example file. Copy that file to .env (which is gitignored) and adjust:

Change all default passwords before deploying to any non-local environment.

Building Docker images

A root-level Makefile builds and security-scans both Docker images. Trivy scans each image after it is built and fails the build if any HIGH or CRITICAL vulnerability with a fix available is found.

make build          # build + scan both images
make build-basex    # build + scan basex only
make build-frontend # build + scan frontend only
make scan           # scan already-built images without rebuilding

To accept a known CVE after triage, add its ID to a .trivyignore file in the relevant service directory (basex/ or frontend/).

Documentation

  • SBOM: see documents/ for the Software Bill of Materials and how to (re)generate the machine-readable SBOMs.
  • Component details: see the per-component READMEs linked above.

License

Released under the European Union Public Licence v1.2 (EUPL-1.2). See the LICENSE file for the full text.

Reuse

This repository is published as open source. You are free to fork, adapt, and reuse the code within the terms of the EUPL-1.2 license.

This is the source of a specific government service rather than a community-maintained project. We are not actively soliciting or reviewing external contributions, and pull requests may not be monitored.

To run the checks locally while working with the code:

  • Frontend: cd frontend && npm run build (runs ESLint + TypeScript + Vite build)
  • BaseX: cd basex && ./scripts/run-tests.sh
  • Data Importer: cd data-importer && ./gradlew test

Nederlands

KWEST is een openbare, webgebaseerde kennisbank voor het doorbladeren en doorzoeken van het nieuwe Wetboek van Strafvordering. De applicatie toont de geconsolideerde wettekst, de memorie van toelichting, transponeringstabellen tussen het oude en het nieuwe recht, een begrippenlijst met juridische termen en een bibliotheek met gerelateerde parlementaire documenten via een toegankelijke interface.

De applicatie draait in productie op https://kwest.overheid.nl. De API-specificatie is beschikbaar op https://kwest.overheid.nl/api/swagger-ui.

De applicatie is volledig openbaar; er is geen authenticatie voor eindgebruikers.

Structuur van de repository

Dit is een monorepo met vier hoofdonderdelen:

Pad Wat het is Stack
frontend/ Webinterface voor het doorbladeren en doorzoeken van de kennisbank React, TypeScript, Vite, CSS
basex/ XML-database + RESTXQ-API die de juridische inhoud levert BaseX, XQuery, XSLT, Docker
data-importer/ Converteert brondocumenten (DOCX/XLSX/XML) naar de XML die de database laadt Java 11, Gradle
documents/ Software Bill of Materials en projectdocumentatie -
scripts/verify-content/ Node-tool die API-antwoorden controleert tegen de broninhoud Node.js

Elk onderdeel heeft een eigen README met gedetailleerde documentatie:

Architectuur

                ┌─────────────────────┐          ┌──────────────────────┐
   Browser ────▶│  Frontend           │─────────▶│  BaseX               │
                │  (React + Vite)     │  /api/*  │  (XML DB + RESTXQ)   │
                │  Nginx levert SPA   │  proxy   │  juridische inhoud   │
                └─────────────────────┘          └──────────┬───────────┘
                                                            │ laadt
                                                 ┌──────────▼────────────┐
                                                 │  XML-bronbestanden    │
                                                 │  (wet.xml, toelichting│
                                                 │   begrippen, …)       │
                                                 └──────────▲────────────┘
                                                            │ genereert
                                                 ┌──────────┴───────────┐
                                                 │  Data Importer (Java)│
                                                 │  DOCX / XLSX / XML ->│
                                                 └──────────────────────┘

In productie is alleen de frontend-container publiek bereikbaar; de Nginx-configuratie proxyt een allowlist van /api/*-routes naar BaseX. De HTTP-poort van BaseX mag nooit rechtstreeks aan het internet worden blootgesteld.

Vereisten

  • Docker en Docker Compose (om BaseX en de volledige stack te draaien)
  • Node.js 20+ (voor de frontend)
  • JDK 11+ (alleen om de data-importer te draaien; een Gradle-wrapper is meegeleverd)

Snel aan de slag

De frontend communiceert altijd met een BaseX-backend (er is geen modus met testdata), dus start eerst BaseX en daarna de frontend.

Frontend-ontwikkelserver

cd frontend
npm install
npm run dev        # Vite-ontwikkelserver op http://localhost:5173

De ontwikkelserver proxyt /api/* naar KWEST_API_TARGET (standaard http://localhost:8080). Draai BaseX lokaal op poort 8080 (zie hieronder) of stel KWEST_API_TARGET in frontend/.env in om naar een draaiende backend te wijzen.

Volledige stack (frontend + BaseX) met Docker

# 1. Start BaseX (XML-database + API)
cd basex
cp .env.example .env          # bewerk vervolgens: stel BASEX_ADMIN_PASSWORD, BASEX_KWEST_PASSWORD in
docker compose up -d --build
curl http://localhost:8080/versie   # controleer of de API draait

# 2. Start de frontend (in een andere terminal)
cd ../frontend
cp .env.example .env          # bewerk vervolgens: stel KWEST_API_TARGET=http://localhost:8080 in
docker compose up -d --build
# open http://localhost

Standaard initialiseert de BaseX-database vanuit de voorbeeld-XML in basex/data/. Zie de BaseX README voor het herinitialiseren met eigen XML, het draaien van de testsuite (./scripts/run-tests.sh) en de volledige REST API-referentie.

De bron-XML opnieuw genereren (optioneel)

De XML die de database laadt, wordt geproduceerd door de data-importer op basis van de brondocumenten in data-importer/data/:

cd data-importer
./gradlew build
./gradlew run --args="--help"     # toon alle importopties
./gradlew run                     # genereer alle output

Configuratie

Elk onderdeel wordt geconfigureerd via omgevingsvariabelen die zijn gedocumenteerd in het eigen .env.example-bestand. Kopieer dat bestand naar .env (dat door gitignore wordt genegeerd) en pas het aan:

Wijzig alle standaardwachtwoorden voordat je naar een niet-lokale omgeving deployt.

Docker-images bouwen

Een Makefile op rootniveau bouwt en scant beide Docker-images op beveiligingsproblemen. Trivy scant elke image nadat deze is gebouwd en laat de build mislukken als er een HIGH- of CRITICAL-kwetsbaarheid met een beschikbare fix wordt gevonden.

make build          # bouw + scan beide images
make build-basex    # bouw + scan alleen basex
make build-frontend # bouw + scan alleen frontend
make scan           # scan reeds gebouwde images zonder opnieuw te bouwen

Om een bekende CVE na triage te accepteren, voeg je het ID toe aan een .trivyignore-bestand in de betreffende servicemap (basex/ of frontend/).

Documentatie

  • SBOM: zie documents/ voor de Software Bill of Materials en hoe je de machineleesbare SBOM's (opnieuw) genereert.
  • Onderdeeldetails: zie de per-onderdeel READMEs die hierboven zijn gelinkt.

Licentie

Uitgebracht onder de European Union Public Licence v1.2 (EUPL-1.2). Zie het LICENSE-bestand voor de volledige tekst.

Hergebruik

Deze repository is gepubliceerd als open source. Je bent vrij om de code te forken, aan te passen en te hergebruiken binnen de voorwaarden van de EUPL-1.2-licentie.

Dit is de broncode van een specifieke overheidsdienst en geen door de gemeenschap onderhouden project. We vragen niet actief om externe bijdragen en beoordelen deze ook niet; pull requests worden mogelijk niet opgevolgd.

Om de controles lokaal uit te voeren tijdens het werken met de code:

  • Frontend: cd frontend && npm run build (voert ESLint + TypeScript + Vite-build uit)
  • BaseX: cd basex && ./scripts/run-tests.sh
  • Data Importer: cd data-importer && ./gradlew test