diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..07837ec6768ace0f114216102ee5413798c3f780
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,43 @@
+.PHONY: docs tests check check-format mypy pylint format build deploy deploy_test
+.SILENT: deploy deploy_test # do not echo commands with password
+
+# run tests
+tests:
+	pytest -q -s ${TESTS_FILTER}
+
+# check
+check: mypy pylint check-format
+
+# check static typing
+mypy:
+	python3 -m mypy src --ignore-missing-imports
+	python3 -m mypy tests --ignore-missing-imports
+
+# check code errors
+pylint:
+	pylint --disable=C,R0902,R0903,R0904,R0912,R0913,R0914,R0915,W0613 --enable=C0121,C0202,C0321 --jobs=0 src/sakia/
+	pylint --disable=C,R0902,R0903,R0904,R0912,R0913,R0914,R0915,W0613 --enable=C0121,C0202,C0321 --jobs=0 tests/
+
+# check format
+check-format:
+	black --check src
+	black --check tests
+
+# format code
+format:
+	black src
+	black tests
+
+# build a wheel package in build folder and put it in dist folder
+build:
+	if [ -d "./build" ]; then rm -r build/*; fi
+	if [ -d "./dist" ]; then rm -r dist/*; fi
+	python setup.py sdist bdist_wheel
+
+# upload on PyPi repository
+deploy:
+	twine upload dist/* --username ${PYPI_LOGIN} --password ${PYPI_PASSWORD}
+
+# upload on PyPi test repository
+deploy_test:
+	twine upload dist/* --username ${PYPI_TEST_LOGIN} --password ${PYPI_TEST_PASSWORD} --repository-url https://test.pypi.org/legacy/
diff --git a/README.md b/README.md
index 1bb51b929bb406cf28198da2490ca52245238ab7..2eaadb89ee5f973e49ea6f140658885597484c67 100644
--- a/README.md
+++ b/README.md
@@ -53,5 +53,80 @@ Python3 and PyQt5 Client for [duniter](http://www.duniter.org) project.
   * Unzip and start "sakia" :)
   * Join our beta community by contacting us on [duniter forum](http://forum.duniter.org/)
 
+## Development
+* When writing docstrings, use the reStructuredText format recommended by https://www.python.org/dev/peps/pep-0287/#docstring-significant-features
+* Use make commands to check the code and the format it correct.
+
+The development tools require Python 3.6.x or higher.
+
+* Create a python virtual environment with [pyenv](https://github.com/pyenv/pyenv)
+```bash
+curl -L https://github.com/pyenv/pyenv-installer/raw/master/bin/pyenv-installer | bash
+```
+
+* Install dependencies
+```bash
+pip install -r requirements.txt
+```
+
+* Run Sakia from the source code
+```bash
+PYTHONPATH="`pwd`/src/." python src/sakia/main.py
+```
+
+* Before submiting a merge requests, please check the static typing and tests.
+
+* Install dev dependencies
+```bash
+pip install -r requirements_dev.txt
+```
+
+* Check static typing with [mypy](http://mypy-lang.org/)
+```bash
+make check
+```
+
+* Run all unit tests (pytest module) with:
+```bash
+make tests
+```
+
+* Run only some unit tests by passing a special ENV variable:
+```bash
+make tests TESTS_FILTER=tests.documents.test_block.TestBlock.test_fromraw
+```
+
+## Packaging and deploy
+### PyPi
+In the development pyenv environment, install the tools to build and deploy
+```bash
+pip install --upgrade -r requirements_deploy.txt
+```
+
+Change and commit and tag the new version number (semantic version number)
+```bash
+./release.sh 0.x.y
+```
+
+Build the PyPi package in the `dist` folder
+```bash
+make build
+```
+
+Deploy the package to PyPi test repository (prefix the command with a space in order for the shell not to save in its history system the command containing the password)
+```bash
+[SPACE]make deploy_test PYPI_TEST_LOGIN=xxxx PYPI_TEST_PASSWORD=xxxx
+```
+
+Install the package from PyPi test repository
+```bash
+pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.python.org/simple/ duniterpy
+```
+
+Deploy the package on the PyPi repository (prefix the command with a space in order for the shell not to save in its history system the command containing the password)
+```bash
+[SPACE]make deploy PYPI_LOGIN=xxxx PYPI_PASSWORD=xxxx
+```
+
 ## License
 This software is distributed under [GNU GPLv3](https://raw.github.com/duniter/sakia/dev/LICENSE).
diff --git a/requirements.txt b/requirements.txt
index becd14a4e6a137751fbd3a00326766e587a238ce..79e4a75543556720ce1aee3a29c5be95b249c136 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -2,11 +2,8 @@ quamash
 asynctest
 networkx
 attrs
-duniter-mirage
 duniterpy>=0.40,<0.50.0
-pytest
-pytest-asyncio<0.6
-pyyaml
 aiohttp
 async_timeout
-PyQt5>=5.9,<5.10
\ No newline at end of file
+PyQt5>=5.9,<5.10
+pyyaml
\ No newline at end of file
diff --git a/requirements_deploy.txt b/requirements_deploy.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ba996edcec3893f32b1aa660f95dc62a1ca4d249
--- /dev/null
+++ b/requirements_deploy.txt
@@ -0,0 +1,3 @@
+setuptools
+wheel
+twine
\ No newline at end of file
diff --git a/requirements_dev.txt b/requirements_dev.txt
new file mode 100644
index 0000000000000000000000000000000000000000..77a67b53f328d8e8d3cbac3526d759dc593ae532
--- /dev/null
+++ b/requirements_dev.txt
@@ -0,0 +1,6 @@
+duniter-mirage
+pytest
+pytest-asyncio<0.6
+black
+mypy
+pylint
\ No newline at end of file
diff --git a/ubuntu_packages.sh b/ubuntu_packages.sh
new file mode 100755
index 0000000000000000000000000000000000000000..20beef3ab1ab098048f929f8c96a3913146ba5eb
--- /dev/null
+++ b/ubuntu_packages.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+
+# Ubuntu 18.04+
+sudo apt-get install curl qt5-qmake qtbase5-dev qttools5-dev-tools libqt5svg5-dev libdbus-1-dev libdbus-glib-1-dev autoconf automake libtool libsodium23
\ No newline at end of file