diff --git a/.mlc-config.json b/.mlc-config.json
index f678b247..a929247a 100644
--- a/.mlc-config.json
+++ b/.mlc-config.json
@@ -3,6 +3,9 @@
     "ignorePatterns": [
         {
             "pattern": "^http://localhost"
+        },
+        {
+            "pattern": "\\{\\{"
         }
     ],
     "replacementPatterns": [
diff --git a/README.md b/README.md
index 6b727b43..092dc184 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,7 @@ an empty Python package. Features include:
 - [Editorconfig]({{cookiecutter.project_slug}}/.editorconfig),
 - Miscellaneous files, such as [Change log]({{cookiecutter.project_slug}}/CHANGELOG.rst), [Code of Conduct]({{cookiecutter.project_slug}}/CODE_OF_CONDUCT.rst), and [Contributing guidelines]({{cookiecutter.project_slug}}/CONTRIBUTING.rst),
 - A [README]({{cookiecutter.project_slug}}/README.rst) and [a separate document]({{cookiecutter.project_slug}}/project_setup.md) with extensive documentation about project setup.
+- Continuous code quality and code coverage reporting using [Sonarcloud](https://sonarcloud.io/)
 
 ## Badges
 
diff --git a/{{cookiecutter.project_slug}}/.github/workflows/quality.yml b/{{cookiecutter.project_slug}}/.github/workflows/quality.yml
new file mode 100644
index 00000000..0469d6cc
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/.github/workflows/quality.yml
@@ -0,0 +1,30 @@
+name: quality
+on:
+  push:
+  pull_request:
+    types: [opened, synchronize, reopened]
+jobs:
+  sonarcloud:
+    name: SonarCloud
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+        with:
+          fetch-depth: 0  # Shallow clones should be disabled for a better relevancy of analysis
+      - name: Set up Python
+        uses: actions/setup-python@v2
+        with:
+          python-version: 3.8
+      - name: Install dependencies
+        run: python -m pip install .[dev]
+      - name: Check style against standards using prospector
+        run: prospector --zero-exit -o grouped -o pylint:pylint-report.txt
+      - name: Run unit tests with coverage
+        run: pytest --cov --cov-report term --cov-report xml --junitxml=xunit-result.xml tests/
+      - name: Correct coverage paths
+        run: sed -i "s+$PWD/++g" coverage.xml
+      - name: SonarCloud Scan
+        uses: SonarSource/sonarcloud-github-action@master
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}  # Needed to get PR information, if any
+          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
diff --git a/{{cookiecutter.project_slug}}/README.rst b/{{cookiecutter.project_slug}}/README.rst
index add1c986..2e724942 100644
--- a/{{cookiecutter.project_slug}}/README.rst
+++ b/{{cookiecutter.project_slug}}/README.rst
@@ -20,6 +20,10 @@
      - |Python Build| |PyPI Publish|
    * - Metadata consistency
      - |metadata consistency|
+   * - Code quality
+     - |sonarcloud quality badge|
+   * - Code coverage of unit tests
+     - |sonarcloud coverage badge|
 
 (Customize these badges with your own links, and check https://shields.io/ or https://badgen.net/ to see which other badges are available.)
 
@@ -65,6 +69,14 @@
    :target: https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.project_slug }}/actions?query=workflow%3A%22cffconvert%22
    :alt: metadata consistency badge
 
+.. |sonarcloud quality badge| image:: https://sonarcloud.io/api/project_badges/measure?project={{ cookiecutter.github_organization }}_{{ cookiecutter.project_slug }}&metric=alert_status
+   :target: https://sonarcloud.io/dashboard?id={{ cookiecutter.github_organization }}_{{ cookiecutter.project_slug }}
+   :alt: Quality Gate Status
+
+.. |sonarcloud coverage badge| image:: https://sonarcloud.io/api/project_badges/measure?project={{ cookiecutter.github_organization }}_{{ cookiecutter.project_slug }}&metric=coverage
+   :target: https://sonarcloud.io/dashboard?id={{ cookiecutter.github_organization }}_{{ cookiecutter.project_slug }}
+   :alt: Coverage
+
 ################################################################################
 {{ cookiecutter.project_name }}
 ################################################################################
diff --git a/{{cookiecutter.project_slug}}/project_setup.md b/{{cookiecutter.project_slug}}/project_setup.md
index c447d543..0a3c603d 100644
--- a/{{cookiecutter.project_slug}}/project_setup.md
+++ b/{{cookiecutter.project_slug}}/project_setup.md
@@ -104,6 +104,18 @@ help you decide which tool to use for packaging.
 -   [Relevant section in the
     guide](https://guide.esciencecenter.nl/#/best_practices/language_guides/python?id=coding-style-conventions)
 
+## Continuous code quality
+
+-   [Sonarcloud](https://sonarcloud.io/) is used to perform quality analysis and code coverage report on each push
+-   The GitHub organization and repository must be added Sonarcloud for analysis to work
+    1. go to [Sonarcloud](https://sonarcloud.io/projects/create)
+    2. login with your GitHub account
+    3. add organization or reuse existing
+    4. setup repository
+    5. go to [new code definition administration page](https://sonarcloud.io/project/new_code?id={{ cookiecutter.github_organization }}_{{ cookiecutter.project_slug }}) and select `Number of days` option
+-   The analysis will be run by [GitHub Action workflow](.github/workflows/quality.yml)
+-   To be able to run the analysis, a token must be created at [Sonarcloud account](https://sonarcloud.io/account/security/) and this token must be added as `SONAR_TOKEN` to [secrets on GitHub](https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.project_slug }}/settings/secrets/actions)
+
 ## Package version number
 
 -   We recommend using [semantic
diff --git a/{{cookiecutter.project_slug}}/sonar-project.properties b/{{cookiecutter.project_slug}}/sonar-project.properties
new file mode 100644
index 00000000..e8ead930
--- /dev/null
+++ b/{{cookiecutter.project_slug}}/sonar-project.properties
@@ -0,0 +1,12 @@
+sonar.organization={{ cookiecutter.github_organization }}
+sonar.projectKey={{ cookiecutter.github_organization }}_{{ cookiecutter.project_slug }}
+sonar.host.url=https://sonarcloud.io
+sonar.sources={{ cookiecutter.project_slug.lower().replace(" ", "_").replace("-", "_")}}/
+sonar.tests=tests/
+sonar.links.homepage=https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.project_slug }}
+sonar.links.scm=https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.project_slug }}
+sonar.links.issue=https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.project_slug }}/issues
+sonar.links.ci=https://github.com/{{ cookiecutter.github_organization }}/{{ cookiecutter.project_slug }}/actions
+sonar.python.coverage.reportPaths=coverage.xml
+sonar.python.xunit.reportPath=xunit-result.xml
+sonar.python.pylint.reportPaths=pylint-report.txt
