diff --git a/CMakeLists.txt b/CMakeLists.txt
index fda15aaf390332092cf8bae72d81fc4f2a085f64..9ce83c3f76734f6beea4686fcc557e318952ba3e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -219,6 +219,7 @@ execute_process(
   ${PYTHON_EXEC} ${SCRIPTS_DIR}/gen_qml_qrc.py ${GEN_QRC_ARGS}
   WORKING_DIRECTORY ${APP_SRC_DIR})
 set(QML_RESOURCES_QML ${APP_SRC_DIR}/qml.qrc)
+
 # Image and misc. resources
 # check files in the resources directory and force a reconfigure if it
 # changes
@@ -230,6 +231,11 @@ execute_process(
   WORKING_DIRECTORY ${APP_SRC_DIR})
 set(QML_RESOURCES ${APP_SRC_DIR}/resources.qrc)
 
+# Find modules (QtCreator) under the root source dir.
+list(APPEND QML_DIRS ${APP_SRC_DIR})
+set(QML_IMPORT_PATH ${QML_DIRS}
+  CACHE STRING "Qt Creator extra qml import paths" FORCE)
+
 # library compatibility (boost, libnotify, etc.)
 add_definitions(-DQT_NO_KEYWORDS)
 
diff --git a/extras/scripts/gen_qml_qrc.py b/extras/scripts/gen_qml_qrc.py
index b46b0603a607760eeefeece12712b828acd3efdc..2644ed6ae74ba9dc88f6b88425963060cfd56adf 100644
--- a/extras/scripts/gen_qml_qrc.py
+++ b/extras/scripts/gen_qml_qrc.py
@@ -62,7 +62,8 @@ def gen_qml_qrc(with_webengine):
                 continue
             filtered = [k for k in files if k.endswith('.qml') or
                         k.endswith('.js') or k.endswith('.html') or
-                        k.endswith('.css') or k.endswith('.conf')]
+                        k.endswith('.css') or k.endswith('.conf') or
+                        k == 'qmldir']
             # if there are no files of interest in this directory, skip it
             if not filtered:
                 continue
diff --git a/extras/scripts/gen_resources_qrc.py b/extras/scripts/gen_resources_qrc.py
index 21704d0078ac440e04a49f9e2819c6510781e360..38d9b917643310aa8b4cb0b8d6fe3f92fd608eb5 100644
--- a/extras/scripts/gen_resources_qrc.py
+++ b/extras/scripts/gen_resources_qrc.py
@@ -32,7 +32,7 @@ import re
 # script as set in the project CMakeLists, which should in turn be
 # where the resources.qrc will be located (currently 'src/app').
 resdir = os.path.join('..', '..', 'resources')
-qmlfile = os.path.join('constant', 'JamiResources.qml')
+qmlfile = os.path.join('net/jami/Constants', 'JamiResources.qml')
 resfile = os.path.join('resources.qrc')
 
 print("Generating resource.qrc file ...")
diff --git a/src/app/.gitignore b/src/app/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..8b70bf180b0b5ce41772f0eb96eaee51e731b193
--- /dev/null
+++ b/src/app/.gitignore
@@ -0,0 +1,4 @@
+# auto-gen files
+resources.qrc
+qml.qrc
+net/jami/Constants/JamiResources.qml
diff --git a/src/app/mainapplication.cpp b/src/app/mainapplication.cpp
index 330412dccb2110a4ea17bf8738f2d5dc340b5ed6..f7efc018c1c23c37c7387a2fe4ac3c7025188965 100644
--- a/src/app/mainapplication.cpp
+++ b/src/app/mainapplication.cpp
@@ -416,6 +416,9 @@ MainApplication::initQmlLayer()
     auto videoProvider = new VideoProvider(lrcInstance_->avModel(), this);
     engine_->rootContext()->setContextProperty("videoProvider", videoProvider);
 
+    // Find modules (runtime) under the root source dir.
+    engine_->addImportPath("qrc:/");
+
     engine_->load(QUrl(QStringLiteral("qrc:/MainApplicationWindow.qml")));
     qCWarning(app_) << "Main window loaded using" << getRenderInterfaceString();
 }
diff --git a/src/app/constant/JamiQmlUtils.qml b/src/app/net/jami/Constants/JamiQmlUtils.qml
similarity index 100%
rename from src/app/constant/JamiQmlUtils.qml
rename to src/app/net/jami/Constants/JamiQmlUtils.qml
diff --git a/src/app/constant/JamiStrings.qml b/src/app/net/jami/Constants/JamiStrings.qml
similarity index 100%
rename from src/app/constant/JamiStrings.qml
rename to src/app/net/jami/Constants/JamiStrings.qml
diff --git a/src/app/constant/JamiTheme.qml b/src/app/net/jami/Constants/JamiTheme.qml
similarity index 100%
rename from src/app/constant/JamiTheme.qml
rename to src/app/net/jami/Constants/JamiTheme.qml
diff --git a/src/app/constant/MsgSeq.qml b/src/app/net/jami/Constants/MsgSeq.qml
similarity index 100%
rename from src/app/constant/MsgSeq.qml
rename to src/app/net/jami/Constants/MsgSeq.qml
diff --git a/src/app/net/jami/Constants/qmldir b/src/app/net/jami/Constants/qmldir
new file mode 100644
index 0000000000000000000000000000000000000000..b894099b6434484c76a155bab9a59ea487d5c826
--- /dev/null
+++ b/src/app/net/jami/Constants/qmldir
@@ -0,0 +1,5 @@
+singleton JamiStrings 1.1 JamiStrings.qml
+singleton JamiQmlUtils 1.1 JamiQmlUtils.qml
+singleton JamiTheme 1.1 JamiTheme.qml
+singleton JamiResources 1.1 JamiResources.qml
+singleton MsgSeq 1.1 MsgSeq.qml
diff --git a/src/app/qmlregister.cpp b/src/app/qmlregister.cpp
index 96480c2ba072bdf82451efd2cdd213bea0c25a5c..bbd55300b7c94f3be64be9a0f8a7b05d4e495b82 100644
--- a/src/app/qmlregister.cpp
+++ b/src/app/qmlregister.cpp
@@ -232,13 +232,6 @@ registerTypes(QQmlEngine* engine,
     QML_REGISTERNAMESPACE(NS_MODELS, MessageList::staticMetaObject, "MessageList");
     QML_REGISTERNAMESPACE(NS_MODELS, PluginStatus::staticMetaObject, "PluginStatus");
 
-    // Qml singleton components
-    QML_REGISTERSINGLETONTYPE_URL(NS_CONSTANTS, "qrc:/constant/JamiTheme.qml", JamiTheme);
-    QML_REGISTERSINGLETONTYPE_URL(NS_MODELS, "qrc:/constant/JamiQmlUtils.qml", JamiQmlUtils);
-    QML_REGISTERSINGLETONTYPE_URL(NS_CONSTANTS, "qrc:/constant/JamiStrings.qml", JamiStrings);
-    QML_REGISTERSINGLETONTYPE_URL(NS_CONSTANTS, "qrc:/constant/JamiResources.qml", JamiResources);
-    QML_REGISTERSINGLETONTYPE_URL(NS_CONSTANTS, "qrc:/constant/MsgSeq.qml", MsgSeq);
-
     QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, app, "MainApplication")
     QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, screenInfo, "CurrentScreenInfo")
     QML_REGISTERSINGLETONTYPE_POBJECT(NS_CONSTANTS, lrcInstance, "LRCInstance")
diff --git a/src/app/qmlregister.h b/src/app/qmlregister.h
index 3e0bc38a234242317e1c4517a74ec5f4385c3884..c9ba09bf0ea03c1640ba35ce33a144c5e61a3137 100644
--- a/src/app/qmlregister.h
+++ b/src/app/qmlregister.h
@@ -38,13 +38,6 @@ class ScreenInfo;
 class MainApplication;
 class ConnectivityMonitor;
 
-// Hack for QtCreator autocomplete (part 1)
-// https://bugreports.qt.io/browse/QTCREATORBUG-20569
-namespace dummy {
-Q_NAMESPACE
-Q_CLASSINFO("RegisterEnumClassesUnscoped", "false")
-} // namespace dummy
-
 // clang-format off
 #define QML_REGISTERSINGLETON_TYPE(NS, T) \
     qmlRegisterSingletonType<T>(NS, MODULE_VER_MAJ, MODULE_VER_MIN, #T, T::create);