diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c6880d5ebca0208ec2a55957eedd18602b5ed696..8394058b69750f8505f316ad7370ec107cab08da 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -3,8 +3,7 @@ image: docker-registry.apertis.org/apertis/apertis-19.03-testcases-builder
 pages:
   stage: deploy
   script:
-    - cd renderer
-    - ./render-test-case ../test-cases/ -d ../public/ --index-page
+    - ./atc test-cases/ -d public/ --index-page
   artifacts:
     paths:
       - public
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000000000000000000000000000000000000..c7f4cd04dd5a7ed6757552f24143bbbd97c2939b
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,4 @@
+include atc_renderer/css/*
+include atc_renderer/images/*
+include atc_renderer/templates/*
+include atc_renderer/tests_files/*
diff --git a/README.md b/README.md
index 897dff68df39e510478c6fbd315fd22fde2ec6ca..7dbbb650d1dfcd1145cde60df2f32bd5a4db0f85 100644
--- a/README.md
+++ b/README.md
@@ -47,12 +47,11 @@ name, then this image should be placed under the `renderer/images` directory.
 
 ## Renderer
 
-The main program is located inside the `renderer/` subdirectory and can be directly
-invoked from inside that directory:
+The main program is named `atc` in the parent directory and can be directly invoked
+like:
 
 ```
-$ cd renderer/
-$ ./render-test-case --help
+$ ./atc --help
 ```
 
 The above command will show the help.
@@ -60,7 +59,7 @@ The above command will show the help.
 To render a single test case, use something like:
 
 ```
-$ ./render-test-case ../test-cases/<test-case-name>.yaml
+$ ./atc test-cases/<test-case-name>.yaml
 ```
 
 That will create a `<test-case-name>.html` page.
@@ -71,7 +70,7 @@ the `-d` flag so all the newly generated test cases are saved there instead of t
 current directory:
 
 ```
-$ ./render-test-case ../test-cases/ -d apertis-test-cases-v0.1/
+$ ./atc test-cases/ -d apertis-test-cases-v0.1/
 ```
 
 Now all the html tests cases should be available inside the
@@ -94,10 +93,10 @@ The module `renderer/tests.py` contains tests for the parser, renderer and
 different formatting methods. There are also a set of tests files located inside
 the `renderer/tests_files/` directory that are used by some of these tests.
 
-The unittest can be executed from the `renderer/` directory like:
+The unittest can be executed from the parent directory with:
 
 ```
-$ python3 -m unittest -v tests.py
+$ python3 -m unittest discover -v
 ```
 
 It is highly recommended to execute these tests if changes are applied to any
diff --git a/atc b/atc
new file mode 100755
index 0000000000000000000000000000000000000000..e40e3c39e2a5438d631ff427af3512a85555395b
--- /dev/null
+++ b/atc
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+###################################################################################
+# Main program to render test case files.
+# Create a HTML page from a YAML test case file.
+#
+# Copyright (C) 2018
+# Luis Araujo <luis.araujo@collabora.co.uk>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  US
+###################################################################################
+
+from atc_renderer import main
+
+if '__main__' == __name__:
+    main()
+    exit(0)
diff --git a/renderer/render-test-case b/atc_renderer/__init__.py
old mode 100755
new mode 100644
similarity index 74%
rename from renderer/render-test-case
rename to atc_renderer/__init__.py
index c3d72efe38ed1480fa1185af6e465fb6044f69f6..6c3377056ea2447373102cdd45e1d688e2f90de8
--- a/renderer/render-test-case
+++ b/atc_renderer/__init__.py
@@ -1,6 +1,5 @@
-#!/usr/bin/env python3
 ###################################################################################
-# render-test-case: Main program to render test case files.
+# Main program to render test case files.
 # Create a HTML page from a YAML test case file.
 #
 # Copyright (C) 2018
@@ -23,33 +22,34 @@
 
 import os
 import shutil
+import pkg_resources
 from argparse import ArgumentParser
 
-from renderer import generate_test_case_page, generate_index_page
+from atc_renderer.renderer import generate_test_case_page, \
+    generate_index_page, \
+    PYTHON_PKGNAME
 
-
-def copy_files(directory, dirname, msg):
+def copy_files(directory, dirname, dirpath, msg):
     """
     Only copy files if destination directory (dst_dir) is not in the cwd.
     """
-    dst_dir = os.path.join(directory, dirname)
-    if dst_dir != os.path.join(os.getcwd(), dirname):
-        if not os.path.isdir(dst_dir):
-            print("Creating directory", dst_dir)
-            os.mkdir(dst_dir)
+    dst_dir = os.path.join(os.path.realpath(directory), dirname)
+    if not os.path.isdir(dst_dir):
+        print("Creating directory", dst_dir)
+        os.mkdir(dst_dir)
 
-        print(msg, dst_dir)
-        files = os.listdir(dirname)
-        for f in files:
-            shutil.copy2(os.path.join(dirname, f), dst_dir)
+    print(msg, dst_dir)
+    files = os.listdir(dirpath)
+    for f in files:
+        shutil.copy2(os.path.join(dirpath, f), dst_dir)
 
 
-if '__main__' == __name__:
-    cli_parser = ArgumentParser(description="render-test-case")
-    cli_parser.add_argument('-d', '--test-case-dir',
-                            help="Directory path for generated test cases")
+def main():
+    cli_parser = ArgumentParser(description="atc (Test Cases Renderer)")
     cli_parser.add_argument('-i', '--index-page', action='store_true',
                             help="Create index page")
+    cli_parser.add_argument('-d', '--test-case-dir',
+                            help="Directory path for generated test cases")
     cli_parser.add_argument('yaml_files',
                             help="YAML file or files directory")
     args = cli_parser.parse_args()
@@ -83,8 +83,10 @@ if '__main__' == __name__:
         print("Total of test cases processed:", c)
 
     # Copy CSS and images directory
-    copy_files(directory, 'css/', "Copying css style to")
-    copy_files(directory, 'images/', "Copying images to")
+    css_dir = pkg_resources.resource_filename(PYTHON_PKGNAME, 'css/')
+    images_dir = pkg_resources.resource_filename(PYTHON_PKGNAME, 'images/')
+    copy_files(directory, 'css/', css_dir, "Copying css style to")
+    copy_files(directory, 'images/', images_dir, "Copying images to")
 
     if index_files:
         generate_index_page(index_files, directory)
diff --git a/renderer/css/bootstrap.min.css b/atc_renderer/css/bootstrap.min.css
similarity index 100%
rename from renderer/css/bootstrap.min.css
rename to atc_renderer/css/bootstrap.min.css
diff --git a/renderer/css/bootstrap.min.css.map b/atc_renderer/css/bootstrap.min.css.map
similarity index 100%
rename from renderer/css/bootstrap.min.css.map
rename to atc_renderer/css/bootstrap.min.css.map
diff --git a/renderer/exceptions.py b/atc_renderer/exceptions.py
similarity index 98%
rename from renderer/exceptions.py
rename to atc_renderer/exceptions.py
index 3b5ea7ab22830232a766430cdb368e895eca9361..b93dcf82f9579fdd84f22183f206c08904ca259f 100644
--- a/renderer/exceptions.py
+++ b/atc_renderer/exceptions.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python3
 ###################################################################################
 # Test case parser exceptions.
 #
diff --git a/renderer/images/3d-rendering-reference.png b/atc_renderer/images/3d-rendering-reference.png
similarity index 100%
rename from renderer/images/3d-rendering-reference.png
rename to atc_renderer/images/3d-rendering-reference.png
diff --git a/renderer/images/Actor-tiles-01.png b/atc_renderer/images/Actor-tiles-01.png
similarity index 100%
rename from renderer/images/Actor-tiles-01.png
rename to atc_renderer/images/Actor-tiles-01.png
diff --git a/renderer/images/Actor-tiles-02.png b/atc_renderer/images/Actor-tiles-02.png
similarity index 100%
rename from renderer/images/Actor-tiles-02.png
rename to atc_renderer/images/Actor-tiles-02.png
diff --git a/renderer/images/Actor-tiles-03.png b/atc_renderer/images/Actor-tiles-03.png
similarity index 100%
rename from renderer/images/Actor-tiles-03.png
rename to atc_renderer/images/Actor-tiles-03.png
diff --git a/renderer/images/Actor-tiles-04.png b/atc_renderer/images/Actor-tiles-04.png
similarity index 100%
rename from renderer/images/Actor-tiles-04.png
rename to atc_renderer/images/Actor-tiles-04.png
diff --git a/renderer/images/Actor-tiles-05.png b/atc_renderer/images/Actor-tiles-05.png
similarity index 100%
rename from renderer/images/Actor-tiles-05.png
rename to atc_renderer/images/Actor-tiles-05.png
diff --git a/renderer/parser.py b/atc_renderer/parser.py
similarity index 97%
rename from renderer/parser.py
rename to atc_renderer/parser.py
index 76602ac6de83151dccbca34d21737b012b7945cc..3597ca8681c5a34cbf2b9f205e6e84f043b605a8 100644
--- a/renderer/parser.py
+++ b/atc_renderer/parser.py
@@ -24,7 +24,7 @@
 import sys
 import yaml
 
-from exceptions import ParserTypeError, ParserMissingFieldError
+from atc_renderer.exceptions import ParserTypeError, ParserMissingFieldError
 
 image_types = [ "any", "development", "minimal", "SDK", "target", "tiny-lxc" ]
 image_arch = ['any', 'amd64', 'arm64', 'armhf']
@@ -59,6 +59,7 @@ test_case_format = {
     'parse': (False, {})
 }
 
+
 def _parse_format(test_case, test_case_format):
     for tagf, valuestr in test_case_format.items():
         mandatory, valuef = valuestr
diff --git a/renderer/renderer.py b/atc_renderer/renderer.py
similarity index 93%
rename from renderer/renderer.py
rename to atc_renderer/renderer.py
index fbb023cc528293d0246ba9810160a9923877ac4f..04bacf62637cc22ce94a1502ec2853a4df29b374 100644
--- a/renderer/renderer.py
+++ b/atc_renderer/renderer.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python3
 ###################################################################################
 # Test case renderer.
 # Create a HTML page from a YAML test case file.
@@ -23,12 +22,12 @@
 
 import os
 import yaml
-from jinja2 import Environment, FileSystemLoader
+from jinja2 import Environment, PackageLoader
 
-from parser import parse_format
-from exceptions import ParserTypeError, ParserMissingFieldError
+from atc_renderer.parser import parse_format
+from atc_renderer.exceptions import ParserTypeError, ParserMissingFieldError
 
-TEMPLATE_DIR="."
+PYTHON_PKGNAME='atc_renderer'
 
 # This command parses each line of a list and returns a structure of the form
 # (comment, command, output) to apply the following formatting for the respective
@@ -159,7 +158,7 @@ def get_template_values(testcase_data):
 
     return template_values
 
-def generate_test_case_page(tc_file, directory='.', return_out=False):
+def generate_test_case_page(tc_file, directory, return_out=False):
     try:
         with open(tc_file) as testcase:
             tc_data = yaml.safe_load(testcase)
@@ -177,9 +176,9 @@ def generate_test_case_page(tc_file, directory='.', return_out=False):
         print("Error: " + str(error))
         exit(1)
 
-    env = Environment(loader=FileSystemLoader([TEMPLATE_DIR]))
+    env = Environment(loader=PackageLoader(PYTHON_PKGNAME, 'templates/'))
     # Get template from environment and render it.
-    data = env.get_template('templates/test_case.html').render(get_template_values(tc_data))
+    data = env.get_template('test_case.html').render(get_template_values(tc_data))
 
     # Return the data if return_out=True
     if return_out:
@@ -190,7 +189,7 @@ def generate_test_case_page(tc_file, directory='.', return_out=False):
     with open(os.path.join(directory, filename), 'w') as test_case_html_file:
         test_case_html_file.write(data)
 
-def generate_index_page(tc_files, directory='.'):
+def generate_index_page(tc_files, directory):
     # Sort alphabetically in the index.
     tc_files.sort()
     # The `index` list is the main structure, each element has the form:
@@ -222,10 +221,10 @@ def generate_index_page(tc_files, directory='.'):
         counts[priority] = counts.copy()[priority] + 1
         counts['total'] = counts.copy()['total'] + 1
 
-    env = Environment(loader=FileSystemLoader([TEMPLATE_DIR]))
+    env = Environment(loader=PackageLoader(PYTHON_PKGNAME, 'templates/'))
     # Get template from environment and render it.
     template_values = { 'index_files': index, 'counts': counts }
-    data = env.get_template('templates/index.html').render(template_values)
+    data = env.get_template('index.html').render(template_values)
 
     index_path = os.path.join(directory, 'index.html')
     with open(index_path, 'w') as index_html_file:
diff --git a/renderer/templates/index.html b/atc_renderer/templates/index.html
similarity index 100%
rename from renderer/templates/index.html
rename to atc_renderer/templates/index.html
diff --git a/renderer/templates/macros.html b/atc_renderer/templates/macros.html
similarity index 100%
rename from renderer/templates/macros.html
rename to atc_renderer/templates/macros.html
diff --git a/renderer/templates/test_case.html b/atc_renderer/templates/test_case.html
similarity index 98%
rename from renderer/templates/test_case.html
rename to atc_renderer/templates/test_case.html
index 6cf942f1025e8eda565f776ddd79496db54cc3fb..95384ec4e8b7c5e9aeb525b46ab6c50d1cac5f90 100644
--- a/renderer/templates/test_case.html
+++ b/atc_renderer/templates/test_case.html
@@ -7,7 +7,7 @@
     <title>{{ name }}</title>
   </head>
   <body>
-    {% import 'templates/macros.html' as macros %}
+    {% import 'macros.html' as macros %}
     <main role="main" class="container" style="margin-top: 40px; margin-bottom: 40px">
       <h2>{{ name }} <small class="text-muted">{{ exec_type }}</small></h2>
       <h3><span class="badge badge-{{ priority_color }}">{{ priority }}</span></h3>
diff --git a/renderer/tests.py b/atc_renderer/tests.py
similarity index 92%
rename from renderer/tests.py
rename to atc_renderer/tests.py
index dbe6bf0f64eee59f092aa3c7bf6007ab98da1f2e..dd6894af12da6e1f2b9db339afae1cb63df1f5c6 100644
--- a/renderer/tests.py
+++ b/atc_renderer/tests.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python3
 ###################################################################################
 # Unit tests for the test case parser and renderer.
 #
@@ -25,12 +24,13 @@ import unittest
 import os.path
 import copy
 
-from parser import parse_format
-from renderer import parse_list, generate_test_case_page
-from exceptions import ParserTypeError, ParserMissingFieldError
+from atc_renderer.parser import parse_format
+from atc_renderer.renderer import parse_list, \
+    generate_test_case_page, \
+    PYTHON_PKGNAME
+from atc_renderer.exceptions import ParserTypeError, ParserMissingFieldError
 
-
-TESTS_FILES_PATH="tests_files/"
+TESTS_FILES_PATH= PYTHON_PKGNAME + "/tests_files/"
 
 def read_tc(filepath):
     with open(filepath) as test_case:
@@ -231,19 +231,23 @@ class TestRenderFile(unittest.TestCase):
     def test_render_file1(self):
         tcfile = os.path.join(TESTS_FILES_PATH, "test_file1.yaml")
         page = read_file(os.path.join(TESTS_FILES_PATH, "test_file1.html"))
-        self.assertEqual(generate_test_case_page(tcfile, return_out=True), page)
+        self.assertEqual(generate_test_case_page(tcfile, None, return_out=True),
+                         page)
 
     def test_render_file3(self):
         tcfile = os.path.join(TESTS_FILES_PATH, "test_file3.yaml")
         page = read_file(os.path.join(TESTS_FILES_PATH, "test_file3.html"))
-        self.assertEqual(generate_test_case_page(tcfile, return_out=True), page)
+        self.assertEqual(generate_test_case_page(tcfile, None, return_out=True),
+                         page)
 
     def test_render_file4(self):
         tcfile = os.path.join(TESTS_FILES_PATH, "test_file4.yaml")
         page = read_file(os.path.join(TESTS_FILES_PATH, "test_file4.html"))
-        self.assertEqual(generate_test_case_page(tcfile, return_out=True), page)
+        self.assertEqual(generate_test_case_page(tcfile, None, return_out=True),
+                         page)
 
     def test_render_file5(self):
         tcfile = os.path.join(TESTS_FILES_PATH, "test_file5.yaml")
         page = read_file(os.path.join(TESTS_FILES_PATH, "test_file5.html"))
-        self.assertEqual(generate_test_case_page(tcfile, return_out=True), page)
+        self.assertEqual(generate_test_case_page(tcfile, None, return_out=True),
+                         page)
diff --git a/renderer/tests_files/test_file1.html b/atc_renderer/tests_files/test_file1.html
similarity index 100%
rename from renderer/tests_files/test_file1.html
rename to atc_renderer/tests_files/test_file1.html
diff --git a/renderer/tests_files/test_file1.yaml b/atc_renderer/tests_files/test_file1.yaml
similarity index 100%
rename from renderer/tests_files/test_file1.yaml
rename to atc_renderer/tests_files/test_file1.yaml
diff --git a/renderer/tests_files/test_file2.yaml b/atc_renderer/tests_files/test_file2.yaml
similarity index 100%
rename from renderer/tests_files/test_file2.yaml
rename to atc_renderer/tests_files/test_file2.yaml
diff --git a/renderer/tests_files/test_file3.html b/atc_renderer/tests_files/test_file3.html
similarity index 100%
rename from renderer/tests_files/test_file3.html
rename to atc_renderer/tests_files/test_file3.html
diff --git a/renderer/tests_files/test_file3.yaml b/atc_renderer/tests_files/test_file3.yaml
similarity index 100%
rename from renderer/tests_files/test_file3.yaml
rename to atc_renderer/tests_files/test_file3.yaml
diff --git a/renderer/tests_files/test_file4.html b/atc_renderer/tests_files/test_file4.html
similarity index 100%
rename from renderer/tests_files/test_file4.html
rename to atc_renderer/tests_files/test_file4.html
diff --git a/renderer/tests_files/test_file4.yaml b/atc_renderer/tests_files/test_file4.yaml
similarity index 100%
rename from renderer/tests_files/test_file4.yaml
rename to atc_renderer/tests_files/test_file4.yaml
diff --git a/renderer/tests_files/test_file5.html b/atc_renderer/tests_files/test_file5.html
similarity index 100%
rename from renderer/tests_files/test_file5.html
rename to atc_renderer/tests_files/test_file5.html
diff --git a/renderer/tests_files/test_file5.yaml b/atc_renderer/tests_files/test_file5.yaml
similarity index 100%
rename from renderer/tests_files/test_file5.yaml
rename to atc_renderer/tests_files/test_file5.yaml
diff --git a/setup.py b/setup.py
new file mode 100644
index 0000000000000000000000000000000000000000..e779139543a7b161840bba1e393e763e2541dc0e
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,45 @@
+###################################################################################
+# setuptools script for atc (Apertis Test Case and Renderer)
+#
+# Copyright (C) 2018
+# Luis Araujo <luis.araujo@collabora.co.uk>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  US
+###################################################################################
+
+from setuptools import setup, find_packages
+
+setup(
+    name='atc',
+    version='1.0',
+    license='LGPL-2.1+',
+    description='Apertis Test Cases Renderer',
+    author='Luis Araujo',
+    author_email='luis.araujo@collabora.co.uk',
+    url='https://gitlab.apertis.org/tests/apertis-test-cases.git',
+    packages=find_packages(),
+    classifiers = [
+        'Operating System :: OS Independent',
+        'Programming Language :: Python',
+    ],
+    entry_points = {
+        'console_scripts': [
+            'atc = atc_renderer:main'
+        ]
+    },
+    include_package_data=True,
+    install_requires=['PyYaml', 'jinja2'],
+    zip_safe=False,
+)