diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f4ae13d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+/vendor/
+composer.lock
+/var
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..b2cbf2a
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,29 @@
+language: php
+
+matrix:
+  include:
+    # PHP tests
+    - language: php
+      php: 7.1
+      env: COMPOSER_FLAGS="--prefer-lowest"
+      before_script:
+        - composer update $COMPOSER_FLAGS --prefer-dist
+      script: vendor/bin/phpunit
+    - language: php
+      php: 7.1
+      env: COMPOSER_FLAGS="--prefer-stable"
+      before_script:
+        - composer update $COMPOSER_FLAGS --prefer-dist
+      script: vendor/bin/phpunit
+    - language: php
+      php: 7.1
+      env: COMPOSER_FLAGS=""
+      before_script:
+        - composer update $COMPOSER_FLAGS --prefer-dist
+      script: vendor/bin/phpunit
+    - language: php
+      php: 7.1
+      env: SYMFONY_VERSION="4.0.*"
+      before_script:
+        - composer update $COMPOSER_FLAGS --prefer-dist
+      script: vendor/bin/phpunit
diff --git a/README.md b/README.md
index aa5b5ba..b20ae6a 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,52 @@
 # financial-twig-extension-bundle
-A simple Symfony Bundle that contains twig extensions for displaying financial information
+A simple Symfony Bundle that contains twig extensions for
+displaying financial information
+
+Installation
+------------
+Install the latest version via [composer](https://getcomposer.org/):
+```bash
+php composer.phar require hostnet/financial-twig-extension-bundle
+```
+
+Then add the bundle to your AppKernel bundles:
+```php
+<?php
+// app/AppKernel.php
+
+public function registerBundles()
+{
+    $bundles = array(
+        // ...
+        new \Hostnet\Bundle\FinancialTwigExtensionBundle\Bundle\HostnetFinancialTwigExtensionBundle(),
+        // ...
+    );
+}
+```
+
+Usage
+-----
+Currently, we support formatting International Bank Account
+Numbers (IBAN) for displaying on a page (a space for every four characters):
+```twig
+{{ "NL85INGB0008523141"|formatIban }}
+```
+
+This will result in the following output:
+```text
+NL85 INGB 0008 5231 41
+```
+
+Requirements
+------------
+
+PHP 7.1.x or above.
+
+License
+-------
+
+This library is licensed under the MIT License, meaning you can reuse the code
+within proprietary software provided that all copies of the licensed software
+include a copy of the MIT License terms and the copyright notice.
+
+For more information, see the [LICENSE](LICENSE) file.
\ No newline at end of file
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..dee8d75
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,35 @@
+{
+    "name":        "hostnet/financial-twig-extension-bundle",
+    "type":        "symfony-bundle",
+    "description": "A simple Symfony Bundle that contains twig extensions for displaying financial information.",
+    "license":     "MIT",
+    "require": {
+        "php":                      "^7.1",
+        "symfony/framework-bundle": "^3.3|^4.0"
+    },
+    "require-dev": {
+        "hostnet/phpcs-tool":  "^5.2",
+        "phpunit/phpunit":     "^6.3",
+        "symfony/twig-bundle": "^3.3|^4.0",
+        "symfony/yaml":        "^3.3|^4.0",
+        "twig/twig":           "^1.26|^2.0"
+    },
+    "conflict": {
+        "twig/twig": "<1.26"
+    },
+    "autoload": {
+        "psr-4": {
+            "Hostnet\\Bundle\\FinancialTwigExtensionBundle\\": "src/"
+        }
+    },
+    "autoload-dev": {
+        "psr-4": {
+            "Hostnet\\Bundle\\FinancialTwigExtensionBundle\\": "test/"
+        }
+    },
+    "archive": {
+        "exclude": [
+            "/test"
+        ]
+    }
+}
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..9b500d6
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit
+        xmlns:xsi                     = "http://www.w3.org/2001/XMLSchema-instance"
+        xsi:noNamespaceSchemaLocation = "http://schema.phpunit.de/4.7/phpunit.xsd"
+        colors                        = "true"
+        forceCoversAnnotation         = "true"
+        bootstrap                     = "vendor/autoload.php"
+>
+    <php>
+        <server name="KERNEL_CLASS" value="Hostnet\Bundle\FinancialTwigExtensionBundle\Functional\Fixtures\TestKernel"/>
+    </php>
+    <testsuites>
+        <testsuite name="unit">
+            <directory>./test</directory>
+            <exclude>./test/Functional</exclude>
+        </testsuite>
+        <testsuite name="functional">
+            <directory>./test/Functional</directory>
+        </testsuite>
+    </testsuites>
+    <filter>
+        <whitelist>
+            <directory>./src</directory>
+        </whitelist>
+    </filter>
+</phpunit>
\ No newline at end of file
diff --git a/src/Bundle/HostnetFinancialTwigExtensionBundle.php b/src/Bundle/HostnetFinancialTwigExtensionBundle.php
new file mode 100644
index 0000000..97becf3
--- /dev/null
+++ b/src/Bundle/HostnetFinancialTwigExtensionBundle.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * @copyright 2017 Hostnet B.V.
+ */
+declare(strict_types=1);
+namespace Hostnet\Bundle\FinancialTwigExtensionBundle\Bundle;
+
+use Symfony\Component\Config\FileLocator;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+
+class HostnetFinancialTwigExtensionBundle extends Bundle
+{
+    public function build(ContainerBuilder $container)
+    {
+        $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/Resources'));
+        $loader->load('services.yml');
+    }
+}
diff --git a/src/Bundle/Resources/services.yml b/src/Bundle/Resources/services.yml
new file mode 100644
index 0000000..08f53a7
--- /dev/null
+++ b/src/Bundle/Resources/services.yml
@@ -0,0 +1,5 @@
+services:
+    Hostnet\Bundle\FinancialTwigExtensionBundle\Twig\FormatIbanExtension:
+        public: false
+        tags:
+            - twig.extension
\ No newline at end of file
diff --git a/src/Twig/FormatIbanExtension.php b/src/Twig/FormatIbanExtension.php
new file mode 100644
index 0000000..a52c76d
--- /dev/null
+++ b/src/Twig/FormatIbanExtension.php
@@ -0,0 +1,24 @@
+<?php
+/**
+ * @copyright 2017 Hostnet B.V.
+ */
+declare(strict_types=1);
+namespace Hostnet\Bundle\FinancialTwigExtensionBundle\Twig;
+
+class FormatIbanExtension extends \Twig_Extension
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getFilters()
+    {
+        return [
+            new \Twig_SimpleFilter('formatIban', [$this, 'formatIban'])
+        ];
+    }
+
+    public function formatIban(string $iban): string
+    {
+        return implode(' ', str_split(preg_replace('/\s+/', '', $iban), 4));
+    }
+}
diff --git a/test/Bundle/HostnetFinancialTwigExtensionBundleTest.php b/test/Bundle/HostnetFinancialTwigExtensionBundleTest.php
new file mode 100644
index 0000000..01135a9
--- /dev/null
+++ b/test/Bundle/HostnetFinancialTwigExtensionBundleTest.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * @copyright 2017 Hostnet B.V.
+ */
+declare(strict_types=1);
+namespace Hostnet\Bundle\FinancialTwigExtensionBundle\Bundle;
+
+use Hostnet\Bundle\FinancialTwigExtensionBundle\Twig\FormatIbanExtension;
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\DependencyInjection\Definition;
+
+/**
+ * @covers \Hostnet\Bundle\FinancialTwigExtensionBundle\Bundle\HostnetFinancialTwigExtensionBundle
+ */
+class HostnetFinancialTwigExtensionBundleTest extends TestCase
+{
+    /**
+     * @var HostnetFinancialTwigExtensionBundle
+     */
+    private $hostnet_financial_twig_extension_bundle;
+
+    protected function setUp()
+    {
+        $this->hostnet_financial_twig_extension_bundle = new HostnetFinancialTwigExtensionBundle();
+    }
+
+    public function testBuild()
+    {
+        $container = new ContainerBuilder();
+        $this->hostnet_financial_twig_extension_bundle->build($container);
+
+        self::assertInstanceOf(
+            Definition::class,
+            $container->getDefinition(FormatIbanExtension::class)
+        );
+    }
+}
diff --git a/test/Functional/ConfigurationTest.php b/test/Functional/ConfigurationTest.php
new file mode 100644
index 0000000..05727b2
--- /dev/null
+++ b/test/Functional/ConfigurationTest.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * @copyright 2017 Hostnet B.V.
+ */
+declare(strict_types=1);
+
+namespace Hostnet\Bundle\FinancialTwigExtensionBundle\Functional;
+
+use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
+
+class ConfigurationTest extends KernelTestCase
+{
+    protected function setUp()
+    {
+        static::bootKernel();
+    }
+
+    public function testFormatIban()
+    {
+        $container = static::$kernel->getContainer();
+        $twig      = $container->get('twig');
+
+        self::assertSame(
+            'NL85 INGB 0008 5231 41',
+            $twig->render('/ibantest.html.twig', ['iban' => 'NL85INGB0008523141'])
+        );
+
+        self::assertSame(
+            'NL85 INGB 0008 5231 41',
+            $twig->render('/ibantest.html.twig', ['iban' => 'NL8 5I NGB00 085 2314 1'])
+        );
+    }
+}
diff --git a/test/Functional/Fixtures/Resources/views/ibantest.html.twig b/test/Functional/Fixtures/Resources/views/ibantest.html.twig
new file mode 100644
index 0000000..de114af
--- /dev/null
+++ b/test/Functional/Fixtures/Resources/views/ibantest.html.twig
@@ -0,0 +1 @@
+{{ iban|formatIban }}
\ No newline at end of file
diff --git a/test/Functional/Fixtures/TestKernel.php b/test/Functional/Fixtures/TestKernel.php
new file mode 100644
index 0000000..ecfd886
--- /dev/null
+++ b/test/Functional/Fixtures/TestKernel.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * @copyright 2017 Hostnet B.V.
+ */
+declare(strict_types=1);
+
+namespace Hostnet\Bundle\FinancialTwigExtensionBundle\Functional\Fixtures;
+
+use Symfony\Component\Config\Loader\LoaderInterface;
+use Symfony\Component\HttpKernel\Kernel;
+
+class TestKernel extends Kernel
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function registerBundles()
+    {
+        return [
+            new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
+            new \Symfony\Bundle\TwigBundle\TwigBundle(),
+            new \Hostnet\Bundle\FinancialTwigExtensionBundle\Bundle\HostnetFinancialTwigExtensionBundle()
+        ];
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function registerContainerConfiguration(LoaderInterface $loader)
+    {
+        $loader->load(__DIR__ . '/config/config.yml');
+    }
+
+    public function getLogDir()
+    {
+        return __DIR__ . '/../../../var/log';
+    }
+
+    public function getCacheDir()
+    {
+        return __DIR__ . '/../../../var/cache';
+    }
+}
diff --git a/test/Functional/Fixtures/config/config.yml b/test/Functional/Fixtures/config/config.yml
new file mode 100644
index 0000000..68f8d04
--- /dev/null
+++ b/test/Functional/Fixtures/config/config.yml
@@ -0,0 +1,2 @@
+framework:
+    secret: test
diff --git a/test/Twig/FormatIbanExtensionTest.php b/test/Twig/FormatIbanExtensionTest.php
new file mode 100644
index 0000000..b0da3bf
--- /dev/null
+++ b/test/Twig/FormatIbanExtensionTest.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * @copyright 2017 Hostnet B.V.
+ */
+declare(strict_types=1);
+namespace Hostnet\Bundle\FinancialTwigExtensionBundle\Twig;
+
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @covers \Hostnet\Bundle\FinancialTwigExtensionBundle\Twig\FormatIbanExtension
+ */
+class FormatIbanExtensionTest extends TestCase
+{
+    /**
+     * @var FormatIbanExtension
+     */
+    private $format_iban_extension;
+
+    protected function setUp()
+    {
+        $this->format_iban_extension = new FormatIbanExtension();
+    }
+
+    public function testGetFilters()
+    {
+        self::assertEquals(
+            [new \Twig_SimpleFilter('formatIban', [$this->format_iban_extension, 'formatIban'])],
+            $this->format_iban_extension->getFilters()
+        );
+    }
+
+    public function testFormatIban()
+    {
+        self::assertSame('NL85 INGB 0008 5231 41', $this->format_iban_extension->formatIban('NL85INGB0008523141'));
+        self::assertSame('NL85 INGB 0008 5231 41', $this->format_iban_extension->formatIban('N L85IN GB00085 23141'));
+    }
+}