diff --git a/src/Main.qml b/src/Main.qml
index 5b8586289eecf98313e2fc5caeb807528326d4a5..e53eafe61542336eca7b77b7d60231ead2c17668 100644
--- a/src/Main.qml
+++ b/src/Main.qml
@@ -132,6 +132,8 @@ Rectangle {
             anchors.bottom: parent.bottom
             anchors.left: parent.left
             anchors.right: parent.right
+            from: 0
+            to: 100
             height: 2
             visible: true
             indeterminate: true
@@ -148,20 +150,22 @@ Rectangle {
 
         Connections {
             target: backend
-            function onPopupOpen(text, timeout) {
+            function onPopupOpen() {
                 popup.visible = true
-                popupText.text = text
-                timer.interval = timeout
-                timer.running = timeout <= 0
             }
 
             function onPopupClose() {
                 popup.visible = false
             }
 
-            function onPopupTextChanged(text) {
-                console.log("Popup text changed", text)
+            function onPopupChangeText(text, timeout) {
                 popupText.text = text
+                timer.interval = timeout
+                timer.running = timeout > 0
+            }
+
+            function onPopupChangeProgress(percentage){
+                progressBar.value = percentage
             }
 
             function onPopupProgressIndeterminateChanged(indeterminate) {
diff --git a/src/backend/backend.cpp b/src/backend/backend.cpp
index 5a7be45d196e9311bb0dab9de544e211400fbcf4..009d3a38d0dd2b397a9ad0c27fe8573c362bc0b7 100644
--- a/src/backend/backend.cpp
+++ b/src/backend/backend.cpp
@@ -118,10 +118,19 @@ QString Backend::buildInfo() const
     // clang-format on
 }
 
-void Backend::updatePopup(const QString &text, bool indeterminate)
+void Backend::updatePopupText(const QString &text, int timeout)
 {
-    emit popupTextChanged(text);
-    emit popupProgressIndeterminateChanged(indeterminate);
+    emit popupOpen();
+    emit popupChangeText(text, timeout);
+    emit popupProgressIndeterminateChanged(true);
+    QEventLoop().processEvents(QEventLoop::AllEvents, 1000);
+}
+
+void Backend::updatePopupProgress(const int progress)
+{
+    emit popupOpen();
+    emit popupProgressIndeterminateChanged(false);
+    emit popupChangeProgress(progress);
     QEventLoop().processEvents(QEventLoop::AllEvents, 1000);
 }
 
@@ -135,8 +144,6 @@ void Backend::initProjectManager()
                                   Qt::QueuedConnection,
                                   Q_ARG(QString, m_lastProjectSenderId));
     });
-
-    updatePopup("Initializing Project Manager...");
 }
 
 void Backend::initDsManager()
@@ -157,6 +164,7 @@ void Backend::initDsManager()
                 if (id == m_lastProjectSenderId) {
                     QMetaObject::invokeMethod(m_projectManager.get(), "stopProject");
                 }
+                emit popupClose();
             });
 
     connect(m_dsManager.get(), &DesignStudioManager::allDesignStudiosDisconnected, this, [this] {
@@ -164,9 +172,18 @@ void Backend::initDsManager()
         emit connectedChanged(false);
     });
 
-    connect(m_dsManager.get(), &DesignStudioManager::projectIncoming, this, [this] {
-        emit popupOpen("Receiving project...");
-    });
+    connect(m_dsManager.get(),
+            &DesignStudioManager::projectIncoming,
+            this,
+            [this](const int projectSize) {
+                qDebug() << "Project incoming with size" << projectSize;
+                emit updatePopupText("Receiving project...");
+            });
+
+    connect(m_dsManager.get(),
+            &DesignStudioManager::projectIncomingProgress,
+            this,
+            [this](const QString &id, const int percentage) { updatePopupProgress(percentage); });
 
     connect(m_dsManager.get(),
             &DesignStudioManager::projectStopRequested,
@@ -187,17 +204,16 @@ void Backend::connectDesignStudio(const QString &ipAddr)
                               "initDesignStudio",
                               Q_ARG(QString, ipAddr),
                               Q_ARG(QString, ""));
-    emit popupOpen("Connecting in the background...", 1500);
+    emit updatePopupText("Connecting in the background...", 1500);
 }
 
 void Backend::runProject(const QString &id, const QByteArray &projectData)
 {
-    emit popupOpen("Running project...");
+    emit updatePopupText("Running project...");
 
     // we'll use this to notify the correct DS when the project started/stopped
     m_lastProjectSenderId = id;
     QMetaObject::invokeMethod(m_dsManager.get(), "sendProjectRunning", Q_ARG(QString, id));
-
     bool retVal;
     QMetaObject::invokeMethod(m_projectManager.get(),
                               "runProject",
@@ -205,9 +221,9 @@ void Backend::runProject(const QString &id, const QByteArray &projectData)
                               Q_ARG(QByteArray, projectData),
                               Q_ARG(bool, autoScaleProject()));
 
-    if (!retVal) {
+    if (!retVal)
         QMetaObject::invokeMethod(m_dsManager.get(), "sendProjectStopped", Q_ARG(QString, id));
-    }
+
     emit popupClose();
 }
 
diff --git a/src/backend/backend.h b/src/backend/backend.h
index 2114e6e1b225433480684e2ba3fdb3339fd78217..072ce8da192270618cd657d978c3b89955f7898d 100644
--- a/src/backend/backend.h
+++ b/src/backend/backend.h
@@ -56,7 +56,8 @@ private:
     Settings m_settings;
 
     // member functions
-    void updatePopup(const QString &text, bool indeterminate = true);
+    void updatePopupText(const QString &text, int timeout = 0);
+    void updatePopupProgress(const int progress);
 
     void initDsManager();
     void initProjectManager();
@@ -67,8 +68,9 @@ private:
 signals:
     // UI signals - Popup
     void popupProgressIndeterminateChanged(bool indeterminate);
-    void popupTextChanged(QString text);
-    void popupOpen(const QString &text = {}, int timeout = 0);
+    void popupChangeText(QString text, int timeout = 0);
+    void popupChangeProgress(int progress);
+    void popupOpen();
     void popupClose();
 
     // UI signals - from DS Manager page
diff --git a/src/backend/dsconnector/ds.cpp b/src/backend/dsconnector/ds.cpp
index 6275546472ae2753a745c80a24241d4505bdc59f..bf94633e35fddcf41abf8bb7b1136f6694c76f83 100644
--- a/src/backend/dsconnector/ds.cpp
+++ b/src/backend/dsconnector/ds.cpp
@@ -59,10 +59,20 @@ void DesignStudio::initSocket()
             &QWebSocket::textMessageReceived,
             this,
             &DesignStudio::processTextMessage);
+
     connect(m_socket.data(),
-            &QWebSocket::binaryMessageReceived,
+            &QWebSocket::binaryFrameReceived,
             this,
-            &DesignStudio::processBinaryMessage);
+            [this](const QByteArray &frame, bool isLastFrame) {
+                qDebug() << "Binary frame received. Size:" << frame.size()
+                         << "is last: " << isLastFrame;
+                m_projectData.append(frame);
+                emit projectIncomingProgress(m_id,
+                                             m_projectData.size() * 100 / m_incomingProjectSize);
+                if (isLastFrame) {
+                    emit projectReceived(m_id, m_projectData);
+                }
+            });
 }
 
 QString DesignStudio::ipv4Addr() const
@@ -127,8 +137,10 @@ void DesignStudio::processTextMessage(const QString &message)
         sendDeviceInfo();
         emit idReceived(newDesignStudioId, ipv4Addr());
     } else if (dataType == PackageFromDesignStudio::projectData) {
-        qDebug() << "Project is expected";
-        emit projectIncoming();
+        m_incomingProjectSize = jsonObj.value("data").toInt();
+        qDebug() << "Project is expected with size" << m_incomingProjectSize;
+        m_projectData.clear();
+        emit projectIncoming(m_incomingProjectSize);
     } else if (dataType == PackageFromDesignStudio::stopRunningProject) {
         qDebug() << "Stop running project requested";
         emit projectStopRequested(m_id);
diff --git a/src/backend/dsconnector/ds.h b/src/backend/dsconnector/ds.h
index 316b9cd3a0c3f0e2ed8aad9b3feae3c414dbfde2..468381b77fbd5fc8d92f41691e5e008269249f67 100644
--- a/src/backend/dsconnector/ds.h
+++ b/src/backend/dsconnector/ds.h
@@ -50,6 +50,10 @@ private:
     QString m_id;
     QString m_deviceUuid;
 
+    // project
+    QByteArray m_projectData;
+    int m_incomingProjectSize;
+
     // DS comm
     void sendData(const QLatin1String &dataType, const QJsonValue &data = QJsonValue());
 
@@ -68,7 +72,8 @@ signals:
 
     // DS signals
     void idReceived(const QString &id, const QString &ipv4Addr);
-    void projectIncoming();
+    void projectIncoming(const int projectSize);
+    void projectIncomingProgress(const QString &id, const int percentage);
     void projectReceived(const QString &id, const QByteArray &data);
     void projectStopRequested(const QString &id);
 };
diff --git a/src/backend/dsconnector/dsmanager.cpp b/src/backend/dsconnector/dsmanager.cpp
index 7785c8fb7c997efbe32f7ce8c6672fb8373712f1..20cf38d012a6284677c452414d8e366c6d3dd440 100644
--- a/src/backend/dsconnector/dsmanager.cpp
+++ b/src/backend/dsconnector/dsmanager.cpp
@@ -66,9 +66,15 @@ void DesignStudioManager::incomingConnection()
             emit allDesignStudiosDisconnected();
     });
 
-    connect(designStudio.data(), &DesignStudio::projectIncoming, this, [this]() {
-        emit projectIncoming();
-    });
+    connect(designStudio.data(),
+            &DesignStudio::projectIncoming,
+            this,
+            &DesignStudioManager::projectIncoming);
+
+    connect(designStudio.data(),
+            &DesignStudio::projectIncomingProgress,
+            this,
+            &DesignStudioManager::projectIncomingProgress);
 
     connect(designStudio.data(),
             &DesignStudio::projectReceived,
diff --git a/src/backend/dsconnector/dsmanager.h b/src/backend/dsconnector/dsmanager.h
index 27e964b6730c071d0c38f9a4fff616a79b28a610..de381675d52c11c70bc7567b7f701ab3c0149260 100644
--- a/src/backend/dsconnector/dsmanager.h
+++ b/src/backend/dsconnector/dsmanager.h
@@ -35,7 +35,8 @@ private:
     void incomingConnection();
 
 signals:
-    void projectIncoming();
+    void projectIncoming(const int &projectSize);
+    void projectIncomingProgress(const QString &id, const int percentage);
     void projectReceived(const QString &id, const QByteArray &project);
     void designStudioConnected(const QString &id, const QString &ipAddr);
     void designStudioDisconnected(const QString &id, const QString &ipAddr);