diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..33fc66f2683080e05ad579f516dbc9e01845e19f
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,160 @@
+################################################################################
+# Gitlab CI integration for Drupal 8/9 project or module: tests, code quality,
+# linting, metrics and deploy samples.
+#
+# Project: https://gitlab.com/mog33/gitlab-ci-drupal
+# Documentation: https://mog33.gitlab.io/gitlab-ci-drupal
+# Issues: https://gitlab.com/mog33/gitlab-ci-drupal/-/issues
+# Author: Jean Valverde contact@dev-drupal.com
+# License: GPL-3
+#
+# If you want to support this project, you can
+# - Buy me a coffee: https://bit.ly/34jPKcE
+# - Hire me as a freelance for any Drupal related work
+# - Promote me to any company looking for any Drupal related work
+# - Help me with testing / documentation / grammar fixes / use cases
+#
+################################################################################
+
+# The ref is relative to the version of the project to use, best to use a tag.
+include:
+  # If hosted on gitlab.com.
+  # - project: 'mog33/gitlab-ci-drupal'
+  #   ref: 3.x-dev
+  #   file: '/.gitlab-ci/.gitlab-ci-template.yml'
+  # If hosted on an other Gitlab instance.
+  # - remote: 'https://gitlab.com/mog33/gitlab-ci-drupal/-/raw/3.x-dev/.gitlab-ci/.gitlab-ci-template.yml'
+  - remote: 'https://git.startx.be/forks/gitlab-ci-drupal/-/raw/startx/.gitlab-ci/.gitlab-ci-template.yml'
+
+# If needed by your Gitlab-ci instance, you can set global tags for all jobs.
+# default:
+#   tags:
+#     - docker
+
+################################################################################
+# Gitlab-CI variables documentation:
+# https://docs.gitlab.com/ee/ci/variables/
+#
+# Variables, can be set here or on
+#   Gitlab CI UI > settings > CI/CD > variables
+# UI take precedence on variables here.
+# https://docs.gitlab.com/ee/ci/variables/README.html#priority-of-environment-variables
+################################################################################
+
+variables:
+  # This is mandatory to get default variables.
+  extends: .default_variables
+
+  # Global config remote files ref.
+  # MUST be the same as include: ref: from above.
+  CI_REF: 3.x-dev
+
+  # Set a version, default is Drupal 8.9, can be 9.0 or 9.1.
+  # CI_DRUPAL_VERSION: "8.9"
+
+  ##############################################################################
+  # Tests disabled by default because need a specific setup / configuration.
+  #
+  # Only needed if you have Behat tests, comment or set to 0 to enable.
+  # https://mog33.gitlab.io/gitlab-ci-drupal/advanced-usage/#behat-tests
+  SKIP_TEST_BEHAT: 1
+
+  # Accessibility tests, need a profile and setup.
+  # https://mog33.gitlab.io/gitlab-ci-drupal/advanced-usage/#accessibility-with-pa11y
+  SKIP_TEST_PA11Y: 1
+
+  # Only if you have Nightwatch tests in your code.
+  # https://mog33.gitlab.io/gitlab-ci-drupal/advanced-usage/#nightwatchjs
+  SKIP_TEST_NIGHTWATCH: 1
+  # Default is '--skiptags core', add your tag.
+  # NIGHTWATCH_TESTS: --tag my_module
+
+  # Phpunit tests to run, default provide only custom code or if this variable
+  # is empty all tests (including Drupal core).
+  # https://mog33.gitlab.io/gitlab-ci-drupal/advanced-usage/#phpunit-tests
+  PHPUNIT_TESTS: "custom"
+
+  ##############################################################################
+  # Override default variables for a module.
+  #
+  # Default CI setup is for a 'project' (full Drupal with a composer.json), next
+  # section contains common variables to change for a module (module, theme or
+  # profile). Simply uncomment and adapt dirs to set the CI for a module.
+  #
+  CI_TYPE: module
+  # Code quality dirs, must include your PHP code to check.
+  # Phpstan need autoloading, that's why we use web_root.
+  DIRS_QA: "${WEB_ROOT}/modules/custom"
+  # Eslint / Stylelint files to test.
+  DIRS_JS: "${CI_PROJECT_DIR}/js/*.js"
+  DIRS_CSS: "${CI_PROJECT_DIR}/css/*.css"
+  # Twig files to test.
+  DIRS_TWIG: "${CI_PROJECT_DIR}/templates"
+  # phpmetrics / phpstats dirs to include.
+  DIRS_PHP: "${CI_PROJECT_DIR}"
+  # Set SKIP_XXX variable to 1 to skip.
+  # Security is for a Drupal project with third party.
+  SKIP_TEST_SECURITY: 1
+  # If you don't have any css files, you can skip with
+  SKIP_LINT_CSS: 1
+  # If you don't have any javascript files, you can skip with
+  SKIP_LINT_JS: 1
+  # If you don't have any twig files, you can skip with
+  SKIP_LINT_TWIG: 1
+  #
+  ##############################################################################
+
+  ##############################################################################
+  # As a sample here is a list of some variables, see documentation for more
+  # variables.
+  #
+  # List of DIRS_* variables to define dirs to analyse for specific jobs.
+  # Code quality dirs, must include your PHP code to check.
+  #
+  # DIRS_QA: "${WEB_ROOT}/modules/custom,${WEB_ROOT}/themes/custom"
+  #
+  # Eslint / Stylelint files to test.
+  # Space separated for multiple folders.
+  # Default is to check files under all custom folders.
+  #
+  # DIRS_JS: "${WEB_ROOT}/**/custom/**/*.js"
+  # DIRS_CSS: "${WEB_ROOT}/**/custom/**/css/*.css"
+  #
+  # Twig files to test, recursive.
+  #
+  # DIRS_TWIG: "${WEB_ROOT}/themes/custom"
+  #
+  # Phpmetrics / Phpstats dirs to include.
+  # Default is to check all dirs.
+  #
+  # DIRS_PHP: "${WEB_ROOT}/modules/custom,${WEB_ROOT}/themes/custom"
+  #
+  # # ALL SKIP variables, uncomment and set to 1 to skip a job.
+  # SKIP_BUILD: 1 # if not running any tests or deploy.
+  #
+  # SKIP_TESTS: 1 # Skip all tests, ignore SKIP_TEST_*.
+  # SKIP_TEST_UNITKERNEL: 1
+  # SKIP_TEST_FUNCTIONAL: 1
+  # SKIP_TEST_FUNCTIONALJS: 1
+  # SKIP_TEST_SECURITY: 1
+  #
+  # SKIP_QA: 1
+  #
+  # SKIP_LINT: 1 # Skip all lint, ignore SKIP_LINT_*.
+  # SKIP_LINT_CSS: 1
+  # SKIP_LINT_JS: 1
+  # SKIP_LINT_TWIG: 1
+  #
+  # SKIP_METRICS: 1
+
+  # QA and Metrics tools.
+  # See Phpqa available tools: https://github.com/EdgedesignCZ/phpqa#available-tools
+  # ':0' is the number of errors allowed, default here is very strict.
+  #
+  # TOOLS_QA: "phpcs:0,phpmd:0,parallel-lint:0,phpstan:0,phpcpd:0"
+  # TOOLS_METRICS: "phpmetrics,phploc,pdepend"
+
+################################################################################
+# Advanced usage with this file, see doc.
+# https://mog33.gitlab.io/gitlab-ci-drupal/advanced-usage
+################################################################################
diff --git a/.gitlab-ci/build.php b/.gitlab-ci/build.php
new file mode 100644
index 0000000000000000000000000000000000000000..d2c67dcc9fecc01f047bcbac628b2a0436aed595
--- /dev/null
+++ b/.gitlab-ci/build.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * You can use this file to run extra Robo build tasks.
+ *
+ * See RoboFile.php and https://robo.li/ documentation to run a task.
+ *
+ * For CI_TYPE='project', this file is executed directly during the Build job
+ * script after the regular composer install.
+ *
+ * For CI_TYPE='module', this file is executed on each 'before_script' part of
+ * jobs.
+ *
+ * It's important to have any action relative to the docRoot or webRoot
+ * as we are not working from the CI_PROJECT_DIR.
+ *
+ * Examples:
+ *
+ * $this->say("This will be run in Build script!");
+ *
+ * $this->taskGulpRun()
+ *   ->dir($this->webRoot . 'themes/my_theme_with_gulp_task')
+ *   ->run();
+ *
+ * $this->taskComposerRequire()
+ *   ->noInteraction()
+ *   ->noAnsi()
+ *   ->workingDir($this->docRoot);
+ *   ->dependency('drupal/webform', '^5.13')
+ *   ->run();
+ *
+ * Or shortcut method in the RoboFile.php with this project:
+ * $this->composerRequire()
+ *  ->dependency('drupal/webform', '^5.13')
+ *  ->run();
+ */
+
+$this->taskComposerConfig()
+  ->noInteraction()
+  ->noAnsi()
+  ->workingDir($this->docRoot)
+  ->repository("0", "https://packages.startx.be", "composer")
+  ->run();
+
+$this->taskComposerConfig()
+  ->noInteraction()
+  ->noAnsi()
+  ->workingDir($this->docRoot)
+  ->repository("1", "https://packages.drupal.org/8", "composer")
+  ->run();
+
+$this->composerRequire()
+  ->dependency('drupal/webform_rrn_nrn', '^2.2.0')
+  ->run();
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..ec171d3bfbcd57e44980557445810b5b9408c4e1
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,17 @@
+{
+  "name": "drupal/field_rrn_nrn",
+  "description": "RRN NRN Field Widget",
+  "type": "drupal-module",
+  "license": "GPL-2.0+",
+  "homepage": "http://drupal.org/project/field_rrn_nrn",
+  "authors": [
+  ],
+  "support": {
+    "issues": "https://www.drupal.org/project/issues/field_rrn_nrn",
+    "source": "https://cgit.drupalcode.org/field_rrn_nrn"
+  },
+  "require": {
+    "drupal/webform_rrn_nrn": "^2.2.0"
+  },
+  "minimum-stability": "dev"
+}
diff --git a/field_rrn_nrn.info.yml b/field_rrn_nrn.info.yml
index b74a93462e9d18dd35f73de2d135ff21746bb604..1f07ffc9404ad2f447950f88ff8ba68bdde6db42 100644
--- a/field_rrn_nrn.info.yml
+++ b/field_rrn_nrn.info.yml
@@ -4,3 +4,5 @@ description: Provides fieldtype for the Belgian National Insurance Number (rijks
 package: startx
 core: 8.x
 core_version_requirement: ^8 || ^9
+dependencies:
+  - webform_rrn_nrn
diff --git a/src/Plugin/Field/FieldWidget/RrnNrnWidget.php b/src/Plugin/Field/FieldWidget/RrnNrnWidget.php
new file mode 100644
index 0000000000000000000000000000000000000000..805d2e5d90a46092090f54d91f7a287a3878bba1
--- /dev/null
+++ b/src/Plugin/Field/FieldWidget/RrnNrnWidget.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace Drupal\field_rrn_nrn\Plugin\Field\FieldWidget;
+
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Plugin implementation of the 'shareholder_address_widget' widget.
+ *
+ * @FieldWidget(
+ *   id = "rrn_nrn_widget",
+ *   label = @Translation("RRN / NRN widget"),
+ *   field_types = {
+ *     "string"
+ *   }
+ * )
+ */
+class RrnNrnWidget extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
+    $item = $items[$delta];
+    $value = $item->getEntity()->isNew() ? [] : $item->toArray();
+
+    $element['value'] = [
+      '#type' => 'webform_belgian_national_insurance_number',
+      '#default_value' => $value,
+      '#error_message' => $this->t('Invalid RRN/NRN'),
+      '#process' => [
+        [static::class, 'processBelgianNationalInsuranceNumber'],
+      ],
+    ];
+    return $element;
+  }
+
+  /**
+   * Processes a 'BelgianNationalInsuranceNumberm' element.
+   */
+  public static function processBelgianNationalInsuranceNumber(&$element, FormStateInterface $form_state, &$complete_form) {
+    $element['#webform_key'] = $element['#parents'];
+    return $element;
+  }
+
+}