diff --git a/hackens_orga/shared/__init__.py b/hackens_orga/shared/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/hackens_orga/shared/admin.py b/hackens_orga/shared/admin.py
new file mode 100644
index 0000000..8c38f3f
--- /dev/null
+++ b/hackens_orga/shared/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/hackens_orga/shared/apps.py b/hackens_orga/shared/apps.py
new file mode 100644
index 0000000..87efe00
--- /dev/null
+++ b/hackens_orga/shared/apps.py
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class SharedConfig(AppConfig):
+    default_auto_field = 'django.db.models.BigAutoField'
+    name = 'shared'
diff --git a/hackens_orga/shared/migrations/__init__.py b/hackens_orga/shared/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/hackens_orga/shared/models.py b/hackens_orga/shared/models.py
new file mode 100644
index 0000000..71a8362
--- /dev/null
+++ b/hackens_orga/shared/models.py
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
diff --git a/hackens_orga/shared/templates/forms/checkbox.html b/hackens_orga/shared/templates/forms/checkbox.html
new file mode 100644
index 0000000..f50ad04
--- /dev/null
+++ b/hackens_orga/shared/templates/forms/checkbox.html
@@ -0,0 +1,16 @@
+<div class="control">
+  {% if field.auto_id %}
+  <label class="checkbox {% if field.field.required %}{{ form.required_css_class }}{% endif %}" {% if field.field.disabled %}disabled="" {% endif %}>
+    {{ field }} {{ field.label }}
+  </label>
+  {% endif %}
+  {% for error in field.errors %}
+  <span class="help is-danger {{ form.error_css_class }}">{{ error }}</span>
+  {% endfor %}
+
+  {% if field.help_text %}
+  <p class="help">
+    {{ field.help_text|safe }}
+  </p>
+  {% endif %}
+</div>
diff --git a/hackens_orga/shared/templates/forms/common-form.html b/hackens_orga/shared/templates/forms/common-form.html
new file mode 100644
index 0000000..46a6611
--- /dev/null
+++ b/hackens_orga/shared/templates/forms/common-form.html
@@ -0,0 +1,31 @@
+{% load i18n %}
+
+<div class="columns is-centered">
+  <div class="column {% if c_size %}{{ c_size }}{% else %}is-two-thirds{% endif %}">
+    <form action="" method="post">
+      {% csrf_token %}
+
+      {% include "forms/form.html" %}
+
+      <div class="field is-grouped">
+        <div class="control is-expanded">
+          <button class="button is-fullwidth is-outlined is-primary is-light" type="submit">
+            <span class="icon">
+              <i class="fas fa-{% if f_icon %}{{ f_icon }}{% else %}check{% endif %}"></i>
+            </span>
+            <span>{% if f_submit %}{{ f_submit }}{% else %}{% trans "Enregister" %}{% endif %}</span>
+          </button>
+        </div>
+
+        <div class="control">
+          <a class="button is-primary" href="{{ r_url }}{% if r_anchor %}#{{ r_anchor }}{% endif %}">
+            <span class="icon">
+              <i class="fas fa-undo-alt"></i>
+            </span>
+            <span>{% if f_return %}{{ f_return }}{% else %}{% trans "Retour" %}{% endif %}</span>
+          </a>
+        </div>
+      </div>
+    </form>
+  </div>
+</div>
diff --git a/hackens_orga/shared/templates/forms/field.html b/hackens_orga/shared/templates/forms/field.html
new file mode 100644
index 0000000..8072a7d
--- /dev/null
+++ b/hackens_orga/shared/templates/forms/field.html
@@ -0,0 +1,33 @@
+{% load bulma %}
+
+<div class="field">
+  {% if field|is_checkbox %}
+
+  {% include "forms/checkbox.html" %}
+
+  {% elif field|is_radio %}
+
+  {% include "forms/radio.html" %}
+
+  {% elif field|is_input %}
+
+  {% include "forms/input.html" %}
+
+  {% elif field|is_textarea %}
+
+  {% include "forms/textarea.html" %}
+
+  {% elif field|is_select %}
+
+  {% include "forms/select.html" %}
+
+  {% elif field|is_file %}
+
+  {% include "forms/file.html" %}
+
+  {% else %}
+
+  {% include "forms/other.html" %}
+
+  {% endif %}
+</div>
diff --git a/hackens_orga/shared/templates/forms/file.html b/hackens_orga/shared/templates/forms/file.html
new file mode 100644
index 0000000..8d83d84
--- /dev/null
+++ b/hackens_orga/shared/templates/forms/file.html
@@ -0,0 +1,35 @@
+{% load i18n bulma %}
+
+<label class="label {% if field.field.required %}{{ form.required_css_class }}{% endif %}">
+  {{ field.label_tag }}
+</label>
+
+<div class="control">
+
+  <div class="file has-name is-fullwidth">
+    <label class="file-label">
+      {{ field|bulmafy:'file-input' }}
+      <span class="file-cta">
+        <span class="file-icon">
+          <i class="fas fa-upload"></i>
+        </span>
+        <span class="file-label">
+          {% trans "Choisissez un fichier..." %}
+        </span>
+      </span>
+      <span class="file-name is-expanded has-text-centered">
+        {% trans "Aucun fichier sélectionné" %}
+      </span>
+    </label>
+  </div>
+
+  {% for error in field.errors %}
+  <span class="help is-danger {{ form.error_css_class }}">{{ error }}</span>
+  {% endfor %}
+
+  {% if field.help_text %}
+  <p class="help">
+    {{ field.help_text|safe }}
+  </p>
+  {% endif %}
+</div>
diff --git a/hackens_orga/shared/templates/forms/form.html b/hackens_orga/shared/templates/forms/form.html
new file mode 100644
index 0000000..1159714
--- /dev/null
+++ b/hackens_orga/shared/templates/forms/form.html
@@ -0,0 +1,18 @@
+{% if errors %}
+{% if form.non_field_errors %}
+<div class="notification is-danger px-3 has-text-centered">
+  {% for non_field_error in form.non_field_errors %}
+  {{ non_field_error }}
+  {% if not forloop.last %}<hr>{% endif %}
+  {% endfor %}
+</div>
+{% endif %}
+{% endif %}
+
+{% for field in form.hidden_fields %}
+{{ field }}
+{% endfor %}
+
+{% for field in form.visible_fields %}
+{% include 'forms/field.html' %}
+{% endfor %}
diff --git a/hackens_orga/shared/templates/forms/formset.html b/hackens_orga/shared/templates/forms/formset.html
new file mode 100644
index 0000000..276821c
--- /dev/null
+++ b/hackens_orga/shared/templates/forms/formset.html
@@ -0,0 +1,14 @@
+{% if formset.non_form_errors %}
+<div class="message is-danger">
+  <p class="message-body">
+    {% for error in formset.non_form_errors %}
+    {{ error }}<br>
+    {% endfor %}
+  </p>
+</div>
+{% endif %}
+
+{{ formset.management_form }}
+{% for form in formset %}
+{% include 'forms/form.html' %}
+{% endfor %}
diff --git a/hackens_orga/shared/templates/forms/input.html b/hackens_orga/shared/templates/forms/input.html
new file mode 100644
index 0000000..7e74dbd
--- /dev/null
+++ b/hackens_orga/shared/templates/forms/input.html
@@ -0,0 +1,19 @@
+{% load bulma %}
+
+<label class="label {% if field.field.required %}{{ form.required_css_class }}{% endif %}">
+  {{ field.label_tag }}
+</label>
+
+<div class="control">
+  {{ field|bulmafy:'input' }}
+
+  {% for error in field.errors %}
+  <span class="help is-danger {{ form.error_css_class }}">{{ error }}</span>
+  {% endfor %}
+
+  {% if field.help_text %}
+  <div class="help">
+    {{ field.help_text|safe }}
+  </div>
+  {% endif %}
+</div>
diff --git a/hackens_orga/shared/templates/forms/modal-form.html b/hackens_orga/shared/templates/forms/modal-form.html
new file mode 100644
index 0000000..ecbddb2
--- /dev/null
+++ b/hackens_orga/shared/templates/forms/modal-form.html
@@ -0,0 +1,35 @@
+{% load i18n %}
+
+<div class="modal" id="modal-{{ modal_id }}">
+  <div class="modal-background" data-closes="modal-{{ modal_id }}"></div>
+  <div class="modal-card">
+
+    <header class="modal-card-head">
+      <p class="modal-card-title">{{ modal_title }}</p>
+      <button class="delete" aria-label="close" data-closes="modal-{{ modal_id }}"></button>
+    </header>
+
+    <section class="modal-card-body">
+      <form method="post" action="{{ post_url }}" id="form-{{ modal_id }}" data-modal="modal-{{ modal_id }}">
+        {% csrf_token %}
+        {% include "forms/form.html" %}
+      </form>
+    </section>
+
+    <footer class="modal-card-foot">
+      <button class="button is-fullwidth is-outlined is-primary is-light" form="form-{{ modal_id }}" type="submit">
+        <span class="icon">
+          <i class="fas fa-check"></i>
+        </span>
+        <span>{% trans "Enregistrer" %}</span>
+      </button>
+
+      <button class="button is-primary button-close" data-closes="modal-{{ modal_id }}">
+        <span class="icon">
+          <i class="fas fa-times"></i>
+        </span>
+        <span>{% trans "Annuler" %}</span>
+      </button>
+    </footer>
+  </div>
+</div>
diff --git a/hackens_orga/shared/templates/forms/other.html b/hackens_orga/shared/templates/forms/other.html
new file mode 100644
index 0000000..0a2a84a
--- /dev/null
+++ b/hackens_orga/shared/templates/forms/other.html
@@ -0,0 +1,19 @@
+{% if field.auto_id %}
+<label class="label {% if field.field.required %}{{ form.required_css_class }}{% endif %}" for="{{ field.auto_id }}">
+  {{ field.label }}
+</label>
+{% endif %}
+
+<div class="control {% if field|is_multiple_checkbox %}multiple-checkbox{% endif %}">
+  {{ field }}
+
+  {% for error in field.errors %}
+  <span class="help is-danger {{ form.error_css_class }}">{{ error }}</span>
+  {% endfor %}
+
+  {% if field.help_text %}
+  <p class="help">
+    {{ field.help_text|safe }}
+  </p>
+  {% endif %}
+</div>
diff --git a/hackens_orga/shared/templates/forms/radio.html b/hackens_orga/shared/templates/forms/radio.html
new file mode 100644
index 0000000..6fc8b8a
--- /dev/null
+++ b/hackens_orga/shared/templates/forms/radio.html
@@ -0,0 +1,24 @@
+{% if field.auto_id %}
+<label class="label {% if field.field.required %}{{ form.required_css_class }}{% endif %}">
+  {{ field.label_tag }}
+</label>
+{% endif %}
+
+<div class="control">
+  {% for choice in field %}
+  <label class="radio">
+    {{ choice.tag }}
+    {{ choice.choice_label }}
+  </label>
+  {% endfor %}
+
+  {% for error in field.errors %}
+  <span class="help is-danger {{ form.error_css_class }}">{{ error }}</span>
+  {% endfor %}
+
+  {% if field.help_text %}
+  <p class="help">
+    {{ field.help_text|safe }}
+  </p>
+  {% endif %}
+</div>
diff --git a/hackens_orga/shared/templates/forms/select.html b/hackens_orga/shared/templates/forms/select.html
new file mode 100644
index 0000000..f23fcde
--- /dev/null
+++ b/hackens_orga/shared/templates/forms/select.html
@@ -0,0 +1,21 @@
+{% load bulma %}
+
+<label class="label {% if field.field.required %}{{ form.required_css_class }}{% endif %}">
+  {{ field.label_tag }}
+</label>
+
+<div class="control is-expanded">
+  <span class="select is-fullwidth{% if field|is_multiple_select %} is-multiple{% endif %}{% if field.errors|length > 0 %} is-danger{% endif %}">
+    {{ field }}
+  </span>
+
+  {% for error in field.errors %}
+  <span class="help is-danger {{ form.error_css_class }}">{{ error }}</span>
+  {% endfor %}
+
+  {% if field.help_text %}
+  <p class="help">
+    {{ field.help_text|safe }}
+  </p>
+  {% endif %}
+</div>
diff --git a/hackens_orga/shared/templates/forms/textarea.html b/hackens_orga/shared/templates/forms/textarea.html
new file mode 100644
index 0000000..1bc2d78
--- /dev/null
+++ b/hackens_orga/shared/templates/forms/textarea.html
@@ -0,0 +1,19 @@
+{% load bulma %}
+
+<label class="label {% if field.field.required %}{{ form.required_css_class }}{% endif %}">
+  {{ field.label_tag }}
+</label>
+
+<div class="control">
+  {{ field|bulmafy:'textarea' }}
+
+  {% for error in field.errors %}
+  <span class="help is-danger {{ form.error_css_class }}">{{ error }}</span>
+  {% endfor %}
+
+  {% if field.help_text %}
+  <p class="help">
+    {{ field.help_text|safe }}
+  </p>
+  {% endif %}
+</div>
diff --git a/hackens_orga/shared/templatetags/bulma.py b/hackens_orga/shared/templatetags/bulma.py
new file mode 100644
index 0000000..e0e15e2
--- /dev/null
+++ b/hackens_orga/shared/templatetags/bulma.py
@@ -0,0 +1,74 @@
+from django import forms, template
+
+register = template.Library()
+
+
+@register.filter
+def widget_type(field):
+    return field.field.widget
+
+
+@register.filter
+def is_select(field):
+    return isinstance(field.field.widget, forms.Select)
+
+
+@register.filter
+def is_multiple_select(field):
+    return isinstance(field.field.widget, forms.SelectMultiple)
+
+
+@register.filter
+def is_textarea(field):
+    return isinstance(field.field.widget, forms.Textarea)
+
+
+@register.filter
+def is_input(field):
+    return isinstance(
+        field.field.widget,
+        (
+            forms.TextInput,
+            forms.NumberInput,
+            forms.EmailInput,
+            forms.PasswordInput,
+            forms.URLInput,
+        ),
+    )
+
+
+@register.filter
+def is_checkbox(field):
+    return isinstance(field.field.widget, forms.CheckboxInput)
+
+
+@register.filter
+def is_multiple_checkbox(field):
+    return isinstance(field.field.widget, forms.CheckboxSelectMultiple)
+
+
+@register.filter
+def is_radio(field):
+    return isinstance(field.field.widget, forms.RadioSelect)
+
+
+@register.filter
+def is_file(field):
+    return isinstance(field.field.widget, forms.FileInput)
+
+
+@register.filter
+def bulmafy(field, css_class):
+    if len(field.errors) > 0:
+        css_class += " is-danger"
+    field_classes = field.field.widget.attrs.get("class", "")
+    field_classes += f" {css_class}"
+    return field.as_widget(attrs={"class": field_classes})
+
+
+@register.filter
+def bulma_message_tag(tag):
+    if tag == "error":
+        return "danger"
+
+    return tag
diff --git a/hackens_orga/shared/tests.py b/hackens_orga/shared/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/hackens_orga/shared/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/hackens_orga/shared/views.py b/hackens_orga/shared/views.py
new file mode 100644
index 0000000..91ea44a
--- /dev/null
+++ b/hackens_orga/shared/views.py
@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.