diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6dfbe4e0e1ca543cef5cbc59b88adf744507113b
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,49 @@
+image: node:14-alpine
+stages:
+  - test
+  - build
+
+# Prevent detached merge request pipelines
+# https://docs.gitlab.com/ee/ci/merge_request_pipelines/
+# Those do not run the environment on_stop jobs when MRs are closed/merged
+# or when branches get deleted, unlike branch pipelines.
+workflow:
+  rules:
+    - if: '$CI_MERGE_REQUEST_ID'
+      when: never
+    - when: always
+
+before_script:
+  - npm ci
+
+lint:
+  stage: test
+
+  before_script:
+    - apk add --update python3 bash git
+    - pip3 install pre-commit
+
+  script:
+    - pre-commit run -a
+
+audit:
+  stage: test
+  script:
+    - npm audit --parseable
+  allow_failure: true
+
+.build:
+  stage: build
+  # Ignore frontend-audit to speed up CI builds
+  needs:
+    - lint
+  artifacts:
+    paths:
+      - dist
+    expire_in: 2 weeks
+
+build-library:
+  extends: .build
+
+  script:
+    - npm run build