diff --git a/.gitignore b/.gitignore
index f1718355816249ad24a053e163854622f2353531..430d19c61509d2c501520da5999ba2a1c9f8bef2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,4 @@ version.txt
 build/
 dist/
 .tox/
+.mypy_cache/
diff --git a/MANIFEST.in b/MANIFEST.in
index 0d0a1dd746f0b3e8ca2a3b6e76457ac978b2fa5b..7b482047ca7851516a1cb4e5ef1fdb93bec14179 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -5,3 +5,4 @@ include requirements-test.txt
 include version.txt
 include README.md
 recursive-include swh/loader/npm/tests/resources *
+recursive-include swh py.typed
diff --git a/mypy.ini b/mypy.ini
new file mode 100644
index 0000000000000000000000000000000000000000..f5765bb19ab297ae99472d46ce3c48e8e04b8e15
--- /dev/null
+++ b/mypy.ini
@@ -0,0 +1,21 @@
+[mypy]
+namespace_packages = True
+warn_unused_ignores = True
+
+
+# 3rd party libraries without stubs (yet)
+
+[mypy-chardet.*]
+ignore_missing_imports = True
+
+[mypy-celery.*]
+ignore_missing_imports = True
+
+[mypy-requests_mock.*]
+ignore_missing_imports = True
+
+[mypy-pkg_resources.*]
+ignore_missing_imports = True
+
+[mypy-pytest.*]
+ignore_missing_imports = True
diff --git a/swh/__init__.py b/swh/__init__.py
index 69e3be50dac40cddced86e9df2f9c2df5a75f004..f14e196529632bc4e37f7e7deb0b49db4742a423 100644
--- a/swh/__init__.py
+++ b/swh/__init__.py
@@ -1 +1,4 @@
-__path__ = __import__('pkgutil').extend_path(__path__, __name__)
+from pkgutil import extend_path
+from typing import Iterable
+
+__path__ = extend_path(__path__, __name__)  # type: Iterable[str]
diff --git a/swh/loader/__init__.py b/swh/loader/__init__.py
index 69e3be50dac40cddced86e9df2f9c2df5a75f004..f14e196529632bc4e37f7e7deb0b49db4742a423 100644
--- a/swh/loader/__init__.py
+++ b/swh/loader/__init__.py
@@ -1 +1,4 @@
-__path__ = __import__('pkgutil').extend_path(__path__, __name__)
+from pkgutil import extend_path
+from typing import Iterable
+
+__path__ = extend_path(__path__, __name__)  # type: Iterable[str]
diff --git a/swh/loader/npm/py.typed b/swh/loader/npm/py.typed
new file mode 100644
index 0000000000000000000000000000000000000000..1242d43277017748bbbf3d0a104ec4cf78245822
--- /dev/null
+++ b/swh/loader/npm/py.typed
@@ -0,0 +1 @@
+# Marker file for PEP 561.
diff --git a/tox.ini b/tox.ini
index 753ff1c199220330db876b33de19d8e1c1856fad..2461ca656f2068577015f453c07d992fae57611d 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist=flake8,py3
+envlist=flake8,mypy,py3
 
 [testenv:py3]
 deps =
@@ -16,3 +16,11 @@ deps =
   flake8
 commands =
   {envpython} -m flake8
+
+[testenv:mypy]
+skip_install = true
+deps =
+  .[testing]
+  mypy
+commands =
+  mypy swh