diff --git a/.gitignore b/.gitignore
index 369657525..db7c881cd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,6 @@ nbproject
 /.vscode/
 .idea/
 .cache/
+.mypy_cache/
+.pytest_cache/
+monkeytype.sqlite3
diff --git a/README.md b/README.md
index befb2afb5..0d0edeb43 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,7 @@ If it is not in your `PATH`, you can help GitPython find it by setting
 the `GIT_PYTHON_GIT_EXECUTABLE=<path/to/git>` environment variable.
 
 * Git (1.7.x or newer)
-* Python >= 3.4
+* Python >= 3.5
 
 The list of dependencies are listed in `./requirements.txt` and `./test-requirements.txt`.
 The installer takes care of installing them for you.
diff --git a/doc/source/changes.rst b/doc/source/changes.rst
index cfb7f1fad..405179d0c 100644
--- a/doc/source/changes.rst
+++ b/doc/source/changes.rst
@@ -8,6 +8,7 @@ Changelog
 * git.Commit objects now have a ``replace`` method that will return a
   copy of the commit with modified attributes.
 * Add python 3.9 support
+* Drop python 3.4 support
 
 3.1.13
 ======
diff --git a/doc/source/intro.rst b/doc/source/intro.rst
index 638a91667..7168c91b1 100644
--- a/doc/source/intro.rst
+++ b/doc/source/intro.rst
@@ -13,7 +13,7 @@ The object database implementation is optimized for handling large quantities of
 Requirements
 ============
 
-* `Python`_ >= 3.4
+* `Python`_ >= 3.5
 * `Git`_ 1.7.0 or newer
     It should also work with older versions, but it may be that some operations
     involving remotes will not work as expected.
diff --git a/git/py.typed b/git/py.typed
new file mode 100644
index 000000000..e69de29bb
diff --git a/git/types.py b/git/types.py
new file mode 100644
index 000000000..dc44c1231
--- /dev/null
+++ b/git/types.py
@@ -0,0 +1,6 @@
+import os  # @UnusedImport  ## not really unused, is in type string
+from typing import Union, Any
+
+
+TBD = Any
+PathLike = Union[str, 'os.PathLike[str]']
diff --git a/mypy.ini b/mypy.ini
new file mode 100644
index 000000000..349266b77
--- /dev/null
+++ b/mypy.ini
@@ -0,0 +1,4 @@
+
+[mypy]
+
+disallow_untyped_defs = True
diff --git a/setup.py b/setup.py
index 500e88c8c..f8829c386 100755
--- a/setup.py
+++ b/setup.py
@@ -95,10 +95,11 @@ def build_py_modules(basedir, excludes=[]):
     license="BSD",
     url="https://github.com/gitpython-developers/GitPython",
     packages=find_packages(exclude=("test.*")),
+    package_data={'git': ['**/*.pyi', 'py.typed']},
     include_package_data=True,
     py_modules=build_py_modules("./git", excludes=["git.ext.*"]),
     package_dir={'git': 'git'},
-    python_requires='>=3.4',
+    python_requires='>=3.5',
     install_requires=requirements,
     tests_require=requirements + test_requirements,
     zip_safe=False,
@@ -122,7 +123,6 @@ def build_py_modules(basedir, excludes=[]):
         "Operating System :: MacOS :: MacOS X",
         "Programming Language :: Python",
         "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.4",
         "Programming Language :: Python :: 3.5",
         "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: 3.7",
diff --git a/test/tstrunner.py b/test/tstrunner.py
new file mode 100644
index 000000000..a3bcfa3cb
--- /dev/null
+++ b/test/tstrunner.py
@@ -0,0 +1,7 @@
+import unittest
+loader = unittest.TestLoader()
+start_dir = '.'
+suite = loader.discover(start_dir)
+
+runner = unittest.TextTestRunner()
+runner.run(suite)
diff --git a/tox.ini b/tox.ini
index 4167cb637..ad126ed4e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist = py34,py35,py36,py37,py38,py39,flake8
+envlist = py35,py36,py37,py38,py39,flake8
 
 [testenv]
 commands = python -m unittest --buffer {posargs}