diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ad191388463ed466d039e54debf1600b4f1cb093
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,51 @@
+stages:
+  - vendor
+  - test
+  - build
+
+.node:
+  tags: [docker]
+  stage: test
+  image: node:10
+  dependencies: [node_modules]
+  variables:
+    NPM_CONFIG_CACHE: "$CI_PROJECT_DIR/.npm"
+
+node_modules:
+  extends: .node
+  stage: vendor
+  dependencies: []
+  script:
+    - npm install
+  artifacts:
+    name: $CI_JOB_NAME
+    expire_in: 1 day
+    paths:
+      - node_modules/
+  cache:
+    key: "$CI_COMMIT_REF_NAME-$CI_JOB_NAME"
+    paths:
+      - "$NPM_CONFIG_CACHE"
+
+ng-lint:
+  extends: .node
+  script: npm run lint
+
+ng-test:
+  extends: .node
+  before_script:
+    - apt-get update -yq
+    - apt-get install -yq --no-install-recommends xvfb firefox-esr xauth
+  script: xvfb-run npm run test
+  coverage: '/Lines.*:.*\d+\.\d+%/'
+  artifact:
+    name: code-coverage
+      expire_in: 1 month
+      paths:
+        - coverage
+
+ng-build:
+  extends: .node
+  stage: build
+  script: npm run build
+