diff --git a/contrib/src/dhtnet/package.json b/contrib/src/dhtnet/package.json
index 4a21ba2c212098d5b1c7dc103b290b68121b9b83..7f5af699eef16dcef3556003013c930d0e116904 100644
--- a/contrib/src/dhtnet/package.json
+++ b/contrib/src/dhtnet/package.json
@@ -1,6 +1,6 @@
 {
     "name": "dhtnet",
-    "version": "24cc01e3deacb1332745929840268af06ebe9068",
+    "version": "c453ca7f8115449d5c512948711b53ecc8410503",
     "url": "https://review.jami.net/plugins/gitiles/dhtnet/+archive/__VERSION__.tar.gz",
     "deps": [
         "opendht",
@@ -13,7 +13,8 @@
     "use_cmake" : true,
     "defines": [
         "BUILD_SHARED_LIBS=0",
-        "BUILD_TESTING=0"
+        "BUILD_TESTING=0",
+        "BUILD_BENCHMARKS=0"
     ],
     "patches": [],
     "win_patches": [],
diff --git a/contrib/src/dhtnet/rules.mak b/contrib/src/dhtnet/rules.mak
index 737645140ce272942c7ea0b66d2a721624e9b5c3..8f727df90b88c895f054658e3f0c98c30a07739b 100644
--- a/contrib/src/dhtnet/rules.mak
+++ b/contrib/src/dhtnet/rules.mak
@@ -1,12 +1,21 @@
 # DHTNET
-DHTNET_VERSION := 24cc01e3deacb1332745929840268af06ebe9068
+DHTNET_VERSION := f7abf971f0445d4add1fc33b2a3856f07eecf430
 DHTNET_URL := https://review.jami.net/plugins/gitiles/dhtnet/+archive/$(DHTNET_VERSION).tar.gz
 
 PKGS += dhtnet
 
-DEPS_dhtnet += opendht pjproject asio
+ifndef HAVE_WIN32
+ifndef HAVE_ANDROID
+ifndef HAVE_IOS
+DEPS_dhtnet += natpmp
+endif
+endif
+endif
+
+DEPS_dhtnet += opendht pjproject asio upnp
 
 DHTNET_CONF = -DBUILD_SHARED_LIBS=Off \
+	-DBUILD_BENCHMARKS=Off \
 	-DBUILD_TOOLS=Off \
 	-DBUILD_TESTING=Off
 
diff --git a/src/account.cpp b/src/account.cpp
index eba6f664fee3e018f7f53fb5d938286dc57aad1f..ded7046ca290eeddc60a575c5f715f30cf3b7c6d 100644
--- a/src/account.cpp
+++ b/src/account.cpp
@@ -162,7 +162,7 @@ Account::loadConfig() {
     ringtonePath_ = fileutils::getFullPath(ringtoneDir, config_->ringtonePath);
     // If the user defined a custom ringtone, the file may not exists
     // In this case, fallback on the default ringtone path
-    if (!fileutils::isFile(ringtonePath_)) {
+    if (not std::filesystem::is_regular_file(ringtonePath_)) {
         JAMI_WARNING("Ringtone {} is not a valid file", ringtonePath_);
         config_->ringtonePath = DEFAULT_RINGTONE_PATH;
         ringtonePath_ = fileutils::getFullPath(ringtoneDir, config_->ringtonePath);
diff --git a/src/archiver.cpp b/src/archiver.cpp
index 8c9d421c9d546066e2a1c7e517832d69e42c2b89..2a35deb7efddcc860b6e49893494b7e7d51ad559 100644
--- a/src/archiver.cpp
+++ b/src/archiver.cpp
@@ -59,7 +59,7 @@ std::map<std::string, std::string>
 jsonValueToAccount(Json::Value& value, const std::string& accountId)
 {
     auto idPath_ = fileutils::get_data_dir() + DIR_SEPARATOR_STR + accountId;
-    fileutils::check_dir(idPath_.c_str(), 0700);
+    dhtnet::fileutils::check_dir(idPath_.c_str(), 0700);
     auto detailsMap = libjami::getAccountTemplate(
         value[libjami::Account::ConfProperties::TYPE].asString());
 
@@ -280,7 +280,7 @@ uncompressArchive(const std::string& archivePath, const std::string& dir, const
     void* zip_handle = NULL;
     mz_zip_file* info = NULL;
 
-    fileutils::check_dir(dir.c_str());
+    dhtnet::fileutils::check_dir(dir.c_str());
 
     mz_zip_create(&zip_handle);
     auto status = mz_zip_reader_open_file(zip_handle, archivePath.c_str());
@@ -289,7 +289,7 @@ uncompressArchive(const std::string& archivePath, const std::string& dir, const
     while (status == MZ_OK) {
         status |= mz_zip_reader_entry_get_info(zip_handle, &info);
         if (status != MZ_OK) {
-            fileutils::removeAll(dir, true);
+            dhtnet::fileutils::removeAll(dir, true);
             break;
         }
         std::string_view filename(info->filename, (size_t) info->filename_size);
@@ -297,7 +297,7 @@ uncompressArchive(const std::string& archivePath, const std::string& dir, const
         if (fileMatchPair.first) {
             auto filePath = dir + DIR_SEPARATOR_STR + fileMatchPair.second;
             std::string directory = filePath.substr(0, filePath.find_last_of(DIR_SEPARATOR_CH));
-            fileutils::check_dir(directory.c_str());
+            dhtnet::fileutils::check_dir(directory.c_str());
             mz_zip_reader_entry_open(zip_handle);
             void* buffStream = NULL;
             buffStream = mz_stream_os_create(&buffStream);
@@ -313,14 +313,14 @@ uncompressArchive(const std::string& archivePath, const std::string& dir, const
                                                            chunkSize)) {
                     ret = mz_stream_os_write(buffStream, (void*) fileContent.data(), ret);
                     if (ret < 0) {
-                        fileutils::removeAll(dir, true);
+                        dhtnet::fileutils::removeAll(dir, true);
                         status = 1;
                     }
                 }
                 mz_stream_os_close(buffStream);
                 mz_stream_os_delete(&buffStream);
             } else {
-                fileutils::removeAll(dir, true);
+                dhtnet::fileutils::removeAll(dir, true);
                 status = 1;
             }
             mz_zip_reader_entry_close(zip_handle);
@@ -375,7 +375,7 @@ uncompressArchive(const std::string& archivePath, const std::string& dir, const
             r = archive_write_header(archiveDiskWriter.get(), entry);
             if (r != ARCHIVE_OK) {
                 // Rollback if failed at a write operation
-                fileutils::removeAll(dir);
+                dhtnet::fileutils::removeAll(dir);
                 throw std::runtime_error("Write file header: " + fileEntry + "\t"
                                          + archive_error_string(archiveDiskWriter.get()));
             } else {
@@ -398,7 +398,7 @@ uncompressArchive(const std::string& archivePath, const std::string& dir, const
 
                     if (r != ARCHIVE_OK) {
                         // Rollback if failed at a write operation
-                        fileutils::removeAll(dir);
+                        dhtnet::fileutils::removeAll(dir);
                         throw std::runtime_error("Write file data: " + fileEntry + "\t"
                                                  + archive_error_string(archiveDiskWriter.get()));
                     }
diff --git a/src/connectivity/security/tlsvalidator.cpp b/src/connectivity/security/tlsvalidator.cpp
index 4ec4481d29c5e9b837b1922f32327b0a1b2c9bc6..1b24afa1187fdb9e95175b121bfa019c8b5a4719 100644
--- a/src/connectivity/security/tlsvalidator.cpp
+++ b/src/connectivity/security/tlsvalidator.cpp
@@ -477,7 +477,7 @@ TlsValidator::compareToCa()
         JAMI_WARN("gnutls_x509_trust_list_add_cas failed: %s", gnutls_strerror(err));
 
     if (not caListPath_.empty()) {
-        if (fileutils::isDirectory(caListPath_))
+        if (std::filesystem::is_directory(caListPath_))
             gnutls_x509_trust_list_add_trust_dir(trust,
                                                  caListPath_.c_str(),
                                                  nullptr,
diff --git a/src/data_transfer.cpp b/src/data_transfer.cpp
index 6ede8cfe913df93d639b7e1ad195b6940dacad04..b26bbb9f82a86e096242be67989a0fa060bd5308 100644
--- a/src/data_transfer.cpp
+++ b/src/data_transfer.cpp
@@ -84,7 +84,7 @@ OutgoingFile::OutgoingFile(const std::shared_ptr<dhtnet::ChannelSocket>& channel
     , start_(start)
     , end_(end)
 {
-    if (!fileutils::isFile(info_.path)) {
+    if (!std::filesystem::is_regular_file(info_.path)) {
         channel_->shutdown();
         return;
     }
@@ -148,8 +148,8 @@ OutgoingFile::cancel()
     auto path = fileutils::get_data_dir() + DIR_SEPARATOR_STR + "conversation_data"
                 + DIR_SEPARATOR_STR + info_.accountId + DIR_SEPARATOR_STR + info_.conversationId
                 + DIR_SEPARATOR_STR + fileId_;
-    if (fileutils::isSymLink(path))
-        fileutils::remove(path);
+    if (std::filesystem::is_symlink(path))
+        dhtnet::fileutils::remove(path);
     isUserCancelled_ = true;
     emit(libjami::DataTransferEventCode::closed_by_host);
 }
@@ -211,7 +211,7 @@ IncomingFile::process()
             auto sha3Sum = fileutils::sha3File(shared->info_.path);
             if (shared->isUserCancelled_) {
                 JAMI_WARN() << "Remove file, invalid sha3sum detected for " << shared->info_.path;
-                fileutils::remove(shared->info_.path, true);
+                dhtnet::fileutils::remove(shared->info_.path, true);
             } else if (shared->sha3Sum_ == sha3Sum) {
                 JAMI_INFO() << "New file received: " << shared->info_.path;
                 correct = true;
@@ -219,7 +219,7 @@ IncomingFile::process()
                 JAMI_WARN() << "Invalid sha3sum detected, unfinished file: " << shared->info_.path;
                 if (shared->info_.totalSize != 0 && shared->info_.totalSize < shared->info_.bytesProgress) {
                     JAMI_WARN() << "Remove file, larger file than announced for " << shared->info_.path;
-                    fileutils::remove(shared->info_.path, true);
+                    dhtnet::fileutils::remove(shared->info_.path, true);
                 }
             }
         }
@@ -244,7 +244,7 @@ public:
             conversationDataPath_ = fileutils::get_data_dir() + DIR_SEPARATOR_STR + accountId_
                                     + DIR_SEPARATOR_STR + "conversation_data" + DIR_SEPARATOR_STR
                                     + to_;
-            fileutils::check_dir(conversationDataPath_.c_str());
+            dhtnet::fileutils::check_dir(conversationDataPath_.c_str());
             waitingPath_ = conversationDataPath_ + DIR_SEPARATOR_STR + "waiting";
         }
         profilesPath_ = fileutils::get_data_dir() + DIR_SEPARATOR_STR + accountId_
@@ -376,7 +376,7 @@ TransferManager::info(const std::string& fileId,
         total = itI->second->info().totalSize;
         progress = itI->second->info().bytesProgress;
         return true;
-    } else if (fileutils::isFile(path)) {
+    } else if (std::filesystem::is_regular_file(path)) {
         std::ifstream transfer(path, std::ios::binary);
         transfer.seekg(0, std::ios::end);
         progress = transfer.tellg();
@@ -524,7 +524,7 @@ TransferManager::onIncomingProfile(const std::shared_ptr<dhtnet::ChannelSocket>&
     info.conversationId = pimpl_->to_;
 
     auto recvDir = fmt::format("{:s}/{:s}/vcard/", fileutils::get_cache_dir(), pimpl_->accountId_);
-    fileutils::recursive_mkdir(recvDir);
+    dhtnet::fileutils::recursive_mkdir(recvDir);
     info.path =  fmt::format("{:s}{:s}_{:s}_{}", recvDir, deviceId, uri, tid);
 
     auto ifile = std::make_shared<IncomingFile>(std::move(channel), info, "profile.vcf", "", sha3Sum);
diff --git a/src/fileutils.cpp b/src/fileutils.cpp
index b941b9a693a8ccaa15b9e2aa317fbf17253dbcff..b0e57ad661d43d7610d02d1b63be3c43c421a765 100644
--- a/src/fileutils.cpp
+++ b/src/fileutils.cpp
@@ -1,23 +1,19 @@
 /*
  *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
  *
- *  Author: Rafaël Carré <rafael.carre@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
+ *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
+ *  the Free Software Foundation, either version 3 of the License, or
  *  (at your option) any later version.
  *
  *  This program 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
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ *  along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
-
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -127,28 +123,6 @@ winGetEnv(const wchar_t* name)
 namespace jami {
 namespace fileutils {
 
-// returns true if directory exists
-bool
-check_dir(const char* path, mode_t UNUSED dirmode, mode_t parentmode)
-{
-    DIR* dir = opendir(path);
-
-    if (!dir) { // doesn't exist
-        if (not recursive_mkdir(path, parentmode)) {
-            perror(path);
-            return false;
-        }
-#ifndef _WIN32
-        if (chmod(path, dirmode) < 0) {
-            JAMI_ERR("fileutils::check_dir(): chmod() failed on '%s', %s", path, strerror(errno));
-            return false;
-        }
-#endif
-    } else
-        closedir(dir);
-    return true;
-}
-
 std::string
 expand_path(const std::string& path)
 {
@@ -274,60 +248,6 @@ isSymLink(const std::string& path)
     return false;
 }
 
-std::chrono::system_clock::time_point
-writeTime(const std::string& path)
-{
-#ifndef _WIN32
-    struct stat s;
-    auto ret = stat(path.c_str(), &s);
-    if (ret)
-        throw std::runtime_error("Can't check write time for: " + path);
-    return std::chrono::system_clock::from_time_t(s.st_mtime);
-#else
-#if RING_UWP
-    _CREATEFILE2_EXTENDED_PARAMETERS ext_params = {0};
-    ext_params.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
-    ext_params.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
-    ext_params.dwFileFlags = FILE_FLAG_NO_BUFFERING;
-    ext_params.dwSecurityQosFlags = SECURITY_ANONYMOUS;
-    ext_params.lpSecurityAttributes = nullptr;
-    ext_params.hTemplateFile = nullptr;
-    HANDLE h = CreateFile2(jami::to_wstring(path).c_str(),
-                           GENERIC_READ,
-                           FILE_SHARE_READ,
-                           OPEN_EXISTING,
-                           &ext_params);
-#elif _WIN32
-    HANDLE h = CreateFileW(jami::to_wstring(path).c_str(),
-                           GENERIC_READ,
-                           FILE_SHARE_READ,
-                           nullptr,
-                           OPEN_EXISTING,
-                           FILE_ATTRIBUTE_NORMAL,
-                           nullptr);
-#endif
-    if (h == INVALID_HANDLE_VALUE)
-        throw std::runtime_error("Can't open: " + path);
-    FILETIME lastWriteTime;
-    if (!GetFileTime(h, nullptr, nullptr, &lastWriteTime))
-        throw std::runtime_error("Can't check write time for: " + path);
-    CloseHandle(h);
-    SYSTEMTIME sTime;
-    if (!FileTimeToSystemTime(&lastWriteTime, &sTime))
-        throw std::runtime_error("Can't check write time for: " + path);
-    struct tm tm
-    {};
-    tm.tm_year = sTime.wYear - 1900;
-    tm.tm_mon = sTime.wMonth - 1;
-    tm.tm_mday = sTime.wDay;
-    tm.tm_hour = sTime.wHour;
-    tm.tm_min = sTime.wMinute;
-    tm.tm_sec = sTime.wSecond;
-    tm.tm_isdst = -1;
-    return std::chrono::system_clock::from_time_t(mktime(&tm));
-#endif
-}
-
 bool
 createSymlink(const std::string& linkFile, const std::string& target)
 {
@@ -394,29 +314,17 @@ getCleanPath(const std::string& base, const std::string& path)
         return path;
 }
 
-std::string
-getFullPath(const std::string& base, const std::string& path)
+std::filesystem::path
+getFullPath(const std::filesystem::path& base, const std::string& path)
 {
     bool isRelative {not base.empty() and isPathRelative(path)};
-    return isRelative ? base + DIR_SEPARATOR_STR + path : path;
+    return isRelative ? base / path : std::filesystem::path(path);
 }
 
 std::vector<uint8_t>
 loadFile(const std::string& path, const std::string& default_dir)
 {
-    std::vector<uint8_t> buffer;
-    std::ifstream file = ifstream(getFullPath(default_dir, path), std::ios::binary);
-    if (!file)
-        throw std::runtime_error("Can't read file: " + path);
-    file.seekg(0, std::ios::end);
-    auto size = file.tellg();
-    if (size > std::numeric_limits<unsigned>::max())
-        throw std::runtime_error("File is too big: " + path);
-    buffer.resize(size);
-    file.seekg(0, std::ios::beg);
-    if (!file.read((char*) buffer.data(), size))
-        throw std::runtime_error("Can't load file: " + path);
-    return buffer;
+    return dhtnet::fileutils::loadFile(getFullPath(default_dir, path));
 }
 
 std::string
@@ -461,80 +369,29 @@ saveFile(const std::string& path, const uint8_t* data, size_t data_size, mode_t
 }
 
 std::vector<uint8_t>
-loadCacheFile(const std::string& path, std::chrono::system_clock::duration maxAge)
+loadCacheFile(const std::filesystem::path& path, std::chrono::system_clock::duration maxAge)
 {
-    // writeTime throws exception if file doesn't exist
-    auto duration = std::chrono::system_clock::now() - writeTime(path);
-    if (duration > maxAge)
+    // last_write_time throws exception if file doesn't exist
+    auto writeTime = std::filesystem::last_write_time(path);
+    if (decltype(writeTime)::clock::now() - writeTime > maxAge)
         throw std::runtime_error("file too old");
 
-    JAMI_DBG("Loading cache file '%.*s'", (int) path.size(), path.c_str());
-    return loadFile(path);
+    JAMI_LOG("Loading cache file '{}'", path);
+    return dhtnet::fileutils::loadFile(path);
 }
 
 std::string
-loadCacheTextFile(const std::string& path, std::chrono::system_clock::duration maxAge)
+loadCacheTextFile(const std::filesystem::path& path, std::chrono::system_clock::duration maxAge)
 {
-    // writeTime throws exception if file doesn't exist
-    auto duration = std::chrono::system_clock::now() - writeTime(path);
-    if (duration > maxAge)
+    // last_write_time throws exception if file doesn't exist
+    auto writeTime = std::filesystem::last_write_time(path);
+    if (decltype(writeTime)::clock::now() - writeTime > maxAge)
         throw std::runtime_error("file too old");
 
-    JAMI_DBG("Loading cache file '%.*s'", (int) path.size(), path.c_str());
+    JAMI_LOG("Loading cache file '{}'", path);
     return loadTextFile(path);
 }
 
-static size_t
-dirent_buf_size(UNUSED DIR* dirp)
-{
-    long name_max;
-#if defined(HAVE_FPATHCONF) && defined(HAVE_DIRFD) && defined(_PC_NAME_MAX)
-    name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX);
-    if (name_max == -1)
-#if defined(NAME_MAX)
-        name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
-#else
-        return (size_t) (-1);
-#endif
-#else
-#if defined(NAME_MAX)
-    name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
-#else
-#error "buffer size for readdir_r cannot be determined"
-#endif
-#endif
-    size_t name_end = (size_t) offsetof(struct dirent, d_name) + name_max + 1;
-    return name_end > sizeof(struct dirent) ? name_end : sizeof(struct dirent);
-}
-
-std::vector<std::string>
-readDirectory(const std::string& dir)
-{
-    DIR* dp = opendir(dir.c_str());
-    if (!dp)
-        return {};
-
-    size_t size = dirent_buf_size(dp);
-    if (size == (size_t) (-1))
-        return {};
-    std::vector<uint8_t> buf(size);
-    dirent* entry;
-
-    std::vector<std::string> files;
-#ifndef _WIN32
-    while (!readdir_r(dp, reinterpret_cast<dirent*>(buf.data()), &entry) && entry) {
-#else
-    while ((entry = readdir(dp)) != nullptr) {
-#endif
-        std::string fname {entry->d_name};
-        if (fname == "." || fname == "..")
-            continue;
-        files.emplace_back(std::move(fname));
-    }
-    closedir(dp);
-    return files;
-} // namespace fileutils
-
 std::vector<uint8_t>
 readArchive(const std::string& path, const std::string& pwd)
 {
@@ -561,7 +418,7 @@ readArchive(const std::string& path, const std::string& pwd)
     std::vector<uint8_t> data;
     // Read file
     try {
-        data = loadFile(path);
+        data = dhtnet::fileutils::loadFile(path);
     } catch (const std::exception& e) {
         JAMI_ERR("Error loading archive: %s", e.what());
         throw e;
@@ -808,7 +665,7 @@ get_config_dir(const char* pkg)
         configdir = fileutils::get_home_dir() + DIR_SEPARATOR_STR + ".config" + DIR_SEPARATOR_STR
                     + pkg;
 #endif
-    if (fileutils::recursive_mkdir(configdir.data(), 0700) != true) {
+    if (dhtnet::fileutils::recursive_mkdir(configdir.data(), 0700) != true) {
         // If directory creation failed
         if (errno != EEXIST)
             JAMI_DBG("Cannot create directory: %s!", configdir.c_str());
@@ -822,29 +679,6 @@ get_config_dir()
     return get_config_dir(PACKAGE);
 }
 
-bool
-recursive_mkdir(const std::string& path, mode_t mode)
-{
-#ifndef _WIN32
-    if (mkdir(path.data(), mode) != 0) {
-#else
-    if (_wmkdir(jami::to_wstring(path.data()).c_str()) != 0) {
-#endif
-        if (errno == ENOENT) {
-            recursive_mkdir(path.substr(0, path.find_last_of(DIR_SEPARATOR_CH)), mode);
-#ifndef _WIN32
-            if (mkdir(path.data(), mode) != 0) {
-#else
-            if (_wmkdir(jami::to_wstring(path.data()).c_str()) != 0) {
-#endif
-                JAMI_ERR("Could not create directory.");
-                return false;
-            }
-        }
-    } // namespace jami
-    return true;
-}
-
 #ifdef _WIN32
 bool
 eraseFile_win32(const std::string& path, bool dosync)
@@ -978,21 +812,6 @@ remove(const std::string& path, bool erase)
     return std::remove(path.c_str());
 }
 
-int
-removeAll(const std::string& path, bool erase)
-{
-    if (path.empty())
-        return -1;
-    if (isDirectory(path) and !isSymLink(path)) {
-        auto dir = path;
-        if (dir.back() != DIR_SEPARATOR_CH)
-            dir += DIR_SEPARATOR_CH;
-        for (auto& entry : fileutils::readDirectory(dir))
-            removeAll(dir + entry, erase);
-    }
-    return remove(path, erase);
-}
-
 void
 openStream(std::ifstream& file, const std::string& path, std::ios_base::openmode mode)
 {
@@ -1056,7 +875,7 @@ sha3File(const std::string& path)
 
     std::ifstream file;
     try {
-        if (!fileutils::isFile(path))
+        if (not std::filesystem::is_regular_file(path))
             return {};
         openStream(file, path, std::ios::binary | std::ios::in);
         if (!file)
diff --git a/src/fileutils.h b/src/fileutils.h
index e038abf33ac5ab164f32cdbbe49b718664d9418c..26cefec80683bc1ea3a28d0f2880ccab5e8fd93d 100644
--- a/src/fileutils.h
+++ b/src/fileutils.h
@@ -1,23 +1,19 @@
 /*
  *  Copyright (C) 2004-2023 Savoir-faire Linux Inc.
  *
- *  Author: Rafaël Carré <rafael.carre@savoirfairelinux.com>
- *
- *  This program is free software; you can redistribute it and/or modify
+ *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 3 of the License, or
+ *  the Free Software Foundation, either version 3 of the License, or
  *  (at your option) any later version.
  *
  *  This program 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
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ *  along with this program. If not, see <https://www.gnu.org/licenses/>.
  */
-
 #pragma once
 
 #include <string>
@@ -28,6 +24,7 @@
 #include <ios>
 
 #include "jami/def.h"
+#include <dhtnet/fileutils.h>
 
 #ifndef _WIN32
 #include <sys/stat.h>               // mode_t
@@ -59,12 +56,8 @@ std::string get_cache_dir();
  * @param dir last directory creation mode
  * @param parents default mode for all created directories except the last
  */
-bool check_dir(const char* path, mode_t dir = 0755, mode_t parents = 0755);
 LIBJAMI_PUBLIC void set_program_dir(char* program_path); // public because bin/main.cpp uses it
 std::string expand_path(const std::string& path);
-bool isDirectoryWritable(const std::string& directory);
-
-bool recursive_mkdir(const std::string& path, mode_t mode = 0755);
 
 bool isPathRelative(const std::string& path);
 /**
@@ -76,25 +69,13 @@ std::string getCleanPath(const std::string& base, const std::string& path);
 /**
  * If path is relative, it is appended to base.
  */
-std::string getFullPath(const std::string& base, const std::string& path);
-
-bool isFile(const std::string& path, bool resolveSymlink = true);
-bool isDirectory(const std::string& path);
-bool isSymLink(const std::string& path);
-bool hasHardLink(const std::string& path);
-
-std::chrono::system_clock::time_point writeTime(const std::string& path);
+std::filesystem::path getFullPath(const std::filesystem::path& base, const std::string& path);
 
 bool createFileLink(const std::string& src, const std::string& dest, bool hard = false);
 
 std::string_view getFileExtension(std::string_view filename);
 
-/**
- * Read content of the directory.
- * The result is a list of relative (to @param dir) paths of all entries
- * in the directory, without "." and "..".
- */
-std::vector<std::string> readDirectory(const std::string& dir);
+bool isDirectoryWritable(const std::string& directory);
 
 /**
  * Read the full content of a file at path.
@@ -112,29 +93,15 @@ saveFile(const std::string& path, const std::vector<uint8_t>& data, mode_t mode
     saveFile(path, data.data(), data.size(), mode);
 }
 
-std::vector<uint8_t> loadCacheFile(const std::string& path,
+std::vector<uint8_t> loadCacheFile(const std::filesystem::path& path,
                                    std::chrono::system_clock::duration maxAge);
-std::string loadCacheTextFile(const std::string& path, std::chrono::system_clock::duration maxAge);
+std::string loadCacheTextFile(const std::filesystem::path& path, std::chrono::system_clock::duration maxAge);
 
 std::vector<uint8_t> readArchive(const std::string& path, const std::string& password = {});
 void writeArchive(const std::string& data,
                   const std::string& path,
                   const std::string& password = {});
 
-std::mutex& getFileLock(const std::string& path);
-
-/**
- * Remove a file with optional erasing of content.
- * Return the same value as std::remove().
- */
-int remove(const std::string& path, bool erase = false);
-
-/**
- * Prune given directory's content and remove it, symlinks are not followed.
- * Return 0 if succeed, -1 if directory is not removed (content can be removed partially).
- */
-int removeAll(const std::string& path, bool erase = false);
-
 /**
  * Wrappers for fstream opening that will convert paths to wstring
  * on windows
diff --git a/src/im/message_engine.cpp b/src/im/message_engine.cpp
index 648e21b54cbab706b9c70b3f9e4366d1e02e41ad..1322a18c1334f922068b999e17a563728884d8ea 100644
--- a/src/im/message_engine.cpp
+++ b/src/im/message_engine.cpp
@@ -39,7 +39,7 @@ MessageEngine::MessageEngine(SIPAccountBase& acc, const std::string& path)
 {
     auto found = savePath_.find_last_of(DIR_SEPARATOR_CH);
     auto dir = savePath_.substr(0, found);
-    fileutils::check_dir(dir.c_str());
+    dhtnet::fileutils::check_dir(dir.c_str());
 }
 
 MessageToken
@@ -240,7 +240,7 @@ MessageEngine::load()
     try {
         Json::Value root;
         {
-            std::lock_guard<std::mutex> lock(fileutils::getFileLock(savePath_));
+            std::lock_guard<std::mutex> lock(dhtnet::fileutils::getFileLock(savePath_));
             std::ifstream file;
             file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
             fileutils::openStream(file, savePath_);
@@ -326,7 +326,7 @@ MessageEngine::save_() const
         dht::ThreadPool::computation().run([path = savePath_,
                                             root = std::move(root),
                                             accountID = account_.getAccountID()] {
-            std::lock_guard<std::mutex> lock(fileutils::getFileLock(path));
+            std::lock_guard<std::mutex> lock(dhtnet::fileutils::getFileLock(path));
             try {
                 Json::StreamWriterBuilder wbuilder;
                 wbuilder["commentStyle"] = "None";
diff --git a/src/jamidht/archive_account_manager.cpp b/src/jamidht/archive_account_manager.cpp
index b945fe8ee55c1643d3f094e8568b24d81c6332c7..91aa2777a049e2a42989e8a26d05eb6ef53377b6 100644
--- a/src/jamidht/archive_account_manager.cpp
+++ b/src/jamidht/archive_account_manager.cpp
@@ -76,7 +76,7 @@ ArchiveAccountManager::initAuthentication(const std::string& accountId,
             } else {
                 // Create/migrate local account
                 bool hasArchive = not ctx->credentials->uri.empty()
-                                    and fileutils::isFile(ctx->credentials->uri);
+                                    and std::filesystem::is_regular_file(ctx->credentials->uri);
                 if (hasArchive) {
                     // Create/migrate from local archive
                     if (ctx->credentials->updateIdentity.first
@@ -373,7 +373,7 @@ ArchiveAccountManager::onArchiveLoaded(AuthContext& ctx,
                                        AccountArchive&& a)
 {
     auto ethAccount = dev::KeyPair(dev::Secret(a.eth_key)).address().hex();
-    fileutils::check_dir(path_.c_str(), 0700);
+    dhtnet::fileutils::check_dir(path_.c_str(), 0700);
 
     auto path = fileutils::getFullPath(path_, archivePath_);
     a.save(path, ctx.credentials ? ctx.credentials->password : "");
diff --git a/src/jamidht/contact_list.cpp b/src/jamidht/contact_list.cpp
index 04fa532a5ea0d329b57ee83461c649bdfb506c0a..bbff34aa8598643e2e80ed6941ef99f484033c68 100644
--- a/src/jamidht/contact_list.cpp
+++ b/src/jamidht/contact_list.cpp
@@ -260,7 +260,7 @@ ContactList::saveTrustRequests() const
 void
 ContactList::loadTrustRequests()
 {
-    if (!fileutils::isFile(fileutils::getFullPath(path_, "incomingTrustRequests")))
+    if (!std::filesystem::is_regular_file(fileutils::getFullPath(path_, "incomingTrustRequests")))
         return;
     std::map<dht::InfoHash, TrustRequest> requests;
     try {
diff --git a/src/jamidht/conversation.cpp b/src/jamidht/conversation.cpp
index 6fcc4444c2538a4e013c02b3626ba6af43bd614c..55f46b9051651bfecfc38b51b79bd8b3fa3944f0 100644
--- a/src/jamidht/conversation.cpp
+++ b/src/jamidht/conversation.cpp
@@ -556,16 +556,16 @@ public:
     std::string_view bannedType(const std::string& uri) const
     {
         auto bannedMember = fmt::format("{}/banned/members/{}.crt", repoPath(), uri);
-        if (fileutils::isFile(bannedMember))
+        if (std::filesystem::is_regular_file(bannedMember))
             return "members"sv;
         auto bannedAdmin = fmt::format("{}/banned/admins/{}.crt", repoPath(), uri);
-        if (fileutils::isFile(bannedAdmin))
+        if (std::filesystem::is_regular_file(bannedAdmin))
             return "admins"sv;
         auto bannedInvited = fmt::format("{}/banned/invited/{}", repoPath(), uri);
-        if (fileutils::isFile(bannedInvited))
+        if (std::filesystem::is_regular_file(bannedInvited))
             return "invited"sv;
         auto bannedDevice = fmt::format("{}/banned/devices/{}.crt", repoPath(), uri);
-        if (fileutils::isFile(bannedDevice))
+        if (std::filesystem::is_regular_file(bannedDevice))
             return "devices"sv;
         return {};
     }
@@ -656,7 +656,7 @@ Conversation::Impl::isAdmin() const
     if (!cert->issuer)
         return false;
     auto uri = cert->issuer->getId().toString();
-    return fileutils::isFile(fileutils::getFullPath(adminsPath, uri + ".crt"));
+    return std::filesystem::is_regular_file(fileutils::getFullPath(adminsPath, uri + ".crt"));
 }
 
 std::vector<std::map<std::string, std::string>>
@@ -1062,7 +1062,7 @@ Conversation::isMember(const std::string& uri, bool includeInvited) const
     if (includeInvited)
         pathsToCheck.emplace_back(invitedPath);
     for (const auto& path : pathsToCheck) {
-        for (const auto& certificate : fileutils::readDirectory(path)) {
+        for (const auto& certificate : dhtnet::fileutils::readDirectory(path)) {
             std::string_view crtUri = certificate;
             auto crtIt = crtUri.find(".crt");
             if (path != invitedPath && crtIt == std::string_view::npos) {
@@ -1413,7 +1413,7 @@ void
 Conversation::erase()
 {
     if (pimpl_->conversationDataPath_ != "")
-        fileutils::removeAll(pimpl_->conversationDataPath_, true);
+        dhtnet::fileutils::removeAll(pimpl_->conversationDataPath_, true);
     if (!pimpl_->repository_)
         return;
     std::lock_guard<std::mutex> lk(pimpl_->writeMtx_);
@@ -1471,7 +1471,7 @@ Conversation::updatePreferences(const std::map<std::string, std::string>& map)
     auto prefs = map;
     auto itLast = prefs.find(LAST_MODIFIED);
     if (itLast != prefs.end()) {
-        if (fileutils::isFile(filePath)) {
+        if (std::filesystem::is_regular_file(filePath)) {
             auto lastModified = fileutils::lastWriteTimeInSeconds(filePath);
             try {
                 if (lastModified >= std::stoul(itLast->second))
@@ -1545,12 +1545,12 @@ Conversation::onFileChannelRequest(const std::string& member,
 
     auto path = dataTransfer()->path(fileId);
 
-    if (!fileutils::isFile(path)) {
+    if (!std::filesystem::is_regular_file(path)) {
         // Check if dangling symlink
-        if (fileutils::isSymLink(path)) {
-            fileutils::remove(path, true);
+        if (std::filesystem::is_symlink(path)) {
+            dhtnet::fileutils::remove(path, true);
         }
-        JAMI_DEBUG("[Account {:s}] {:s} asked for non existing file {:s} in {:s}",
+        JAMI_DEBUG("[Account {:s}] {:s} asked for non existing file {} in {:s}",
                    pimpl_->accountId_,
                    member,
                    fileId,
@@ -1684,7 +1684,7 @@ Conversation::updateLastDisplayed(const std::map<std::string, std::string>& map)
     auto prefs = map;
     auto itLast = prefs.find(LAST_MODIFIED);
     if (itLast != prefs.end()) {
-        if (fileutils::isFile(filePath)) {
+        if (std::filesystem::is_regular_file(filePath)) {
             auto lastModified = fileutils::lastWriteTimeInSeconds(filePath);
             try {
                 if (lastModified >= std::stoul(itLast->second))
diff --git a/src/jamidht/conversation_module.cpp b/src/jamidht/conversation_module.cpp
index 3fe005b4fa4f5a1e72c9a2be28ece1bdd6c05fc8..747c02de4ed30ad3b9e71a803a71dc4fd473958e 100644
--- a/src/jamidht/conversation_module.cpp
+++ b/src/jamidht/conversation_module.cpp
@@ -1144,7 +1144,7 @@ ConversationModule::saveConvRequestsToPath(
     const std::string& path, const std::map<std::string, ConversationRequest>& conversationsRequests)
 {
     std::lock_guard<std::mutex> lock(
-        fileutils::getFileLock(path + DIR_SEPARATOR_STR + "convRequests"));
+        dhtnet::fileutils::getFileLock(path + DIR_SEPARATOR_STR + "convRequests"));
     std::ofstream file(path + DIR_SEPARATOR_STR + "convRequests",
                        std::ios::trunc | std::ios::binary);
     msgpack::pack(file, conversationsRequests);
@@ -1205,7 +1205,7 @@ ConversationModule::loadConversations()
         return;
     auto uri = acc->getUsername();
     JAMI_LOG("[Account {}] Start loading conversations…", pimpl_->accountId_);
-    auto conversationsRepositories = fileutils::readDirectory(
+    auto conversationsRepositories = dhtnet::fileutils::readDirectory(
         fileutils::get_data_dir() + DIR_SEPARATOR_STR + pimpl_->accountId_ + DIR_SEPARATOR_STR
         + "conversations");
     std::unique_lock<std::mutex> lk(pimpl_->conversationsMtx_);
@@ -2720,7 +2720,7 @@ ConversationModule::convInfosFromPath(const std::string& path)
     try {
         // read file
         std::lock_guard<std::mutex> lock(
-            fileutils::getFileLock(path + DIR_SEPARATOR_STR + "convInfo"));
+            dhtnet::fileutils::getFileLock(path + DIR_SEPARATOR_STR + "convInfo"));
         auto file = fileutils::loadFile("convInfo", path);
         // load values
         msgpack::object_handle oh = msgpack::unpack((const char*) file.data(), file.size());
@@ -2745,7 +2745,7 @@ ConversationModule::convRequestsFromPath(const std::string& path)
     try {
         // read file
         std::lock_guard<std::mutex> lock(
-            fileutils::getFileLock(path + DIR_SEPARATOR_STR + "convRequests"));
+            dhtnet::fileutils::getFileLock(path + DIR_SEPARATOR_STR + "convRequests"));
         auto file = fileutils::loadFile("convRequests", path);
         // load values
         msgpack::object_handle oh = msgpack::unpack((const char*) file.data(), file.size());
diff --git a/src/jamidht/conversationrepository.cpp b/src/jamidht/conversationrepository.cpp
index d415373ffc4ba80126084b0e763329105e075a46..dc2bd41428a309d9c46de1cccc0ab5e20de06f50 100644
--- a/src/jamidht/conversationrepository.cpp
+++ b/src/jamidht/conversationrepository.cpp
@@ -195,7 +195,7 @@ public:
             return {};
         std::map<std::string, std::vector<DeviceId>> memberDevices;
         std::string deviceDir = fmt::format("{}devices/", git_repository_workdir(repo.get()));
-        for (const auto& file : fileutils::readDirectory(deviceDir)) {
+        for (const auto& file: dhtnet::fileutils::readDirectory(deviceDir)) {
             std::shared_ptr<dht::crypto::Certificate> cert;
             try {
                 cert = std::make_shared<dht::crypto::Certificate>(
@@ -209,7 +209,7 @@ public:
                     // Check that parentCert
                     auto memberFile = fmt::format("{}members/{}.crt", git_repository_workdir(repo.get()), issuerUid);
                     auto adminFile = fmt::format("{}admins/{}.crt", git_repository_workdir(repo.get()), issuerUid);
-                    auto parentCert = std::make_shared<dht::crypto::Certificate>(fileutils::loadFile(fileutils::isFile(memberFile) ? memberFile : adminFile));
+                    auto parentCert = std::make_shared<dht::crypto::Certificate>(dhtnet::fileutils::loadFile(std::filesystem::is_regular_file(memberFile) ? memberFile : adminFile));
                     if (parentCert && (ignoreExpired || parentCert->getExpiration() < std::chrono::system_clock::now()))
                         acc->certStore().pinCertificate(parentCert, true); // Pin certificate to local store if not already done
                 }
@@ -284,9 +284,8 @@ public:
         auto cert = acc->certStore().getCertificate(deviceId);
         if (!cert || !cert->issuer) {
             // Not pinned, so load certificate from repo
-            std::string deviceFile = git_repository_workdir(repo.get())
-                                     + fmt::format("devices/{}.crt", deviceId);
-            if (!fileutils::isFile(deviceFile))
+            auto deviceFile = std::filesystem::path(git_repository_workdir(repo.get())) / "devices" / fmt::format("{}.crt", deviceId);
+            if (!std::filesystem::is_regular_file(deviceFile))
                 return {};
             try {
                 cert = std::make_shared<dht::crypto::Certificate>(fileutils::loadFile(deviceFile));
@@ -426,7 +425,7 @@ add_initial_files(GitRepository& repo,
     std::string invitedPath = repoPath + "invited";
     std::string crlsPath = repoPath + "CRLs" + DIR_SEPARATOR_STR + deviceId;
 
-    if (!fileutils::recursive_mkdir(adminsPath, 0700)) {
+    if (!dhtnet::fileutils::recursive_mkdir(adminsPath, 0700)) {
         JAMI_ERROR("Error when creating %s. Abort create conversations", adminsPath.c_str());
         return false;
     }
@@ -449,7 +448,7 @@ add_initial_files(GitRepository& repo,
     file << parentCert->toString(true);
     file.close();
 
-    if (!fileutils::recursive_mkdir(devicesPath, 0700)) {
+    if (!dhtnet::fileutils::recursive_mkdir(devicesPath, 0700)) {
         JAMI_ERROR("Error when creating {}. Abort create conversations", devicesPath);
         return false;
     }
@@ -464,7 +463,7 @@ add_initial_files(GitRepository& repo,
     file << deviceCert;
     file.close();
 
-    if (!fileutils::recursive_mkdir(crlsPath, 0700)) {
+    if (!dhtnet::fileutils::recursive_mkdir(crlsPath, 0700)) {
         JAMI_ERROR("Error when creating {}. Abort create conversations", crlsPath);
         return false;
     }
@@ -486,12 +485,12 @@ add_initial_files(GitRepository& repo,
 
     // /invited for one to one
     if (mode == ConversationMode::ONE_TO_ONE) {
-        if (!fileutils::recursive_mkdir(invitedPath, 0700)) {
+        if (!dhtnet::fileutils::recursive_mkdir(invitedPath, 0700)) {
             JAMI_ERROR("Error when creating {}.", invitedPath);
             return false;
         }
         std::string invitedMemberPath = invitedPath + "/" + otherMember;
-        if (fileutils::isFile(invitedMemberPath)) {
+        if (std::filesystem::is_regular_file(invitedMemberPath)) {
             JAMI_WARNING("Member {} already present!", otherMember);
             return false;
         }
@@ -1420,7 +1419,7 @@ ConversationRepository::Impl::checkValidVoteResolution(const std::string& userDe
     auto nbAdmins = 0;
     auto nbVotes = 0;
     std::string repoPath = git_repository_workdir(repo.get());
-    for (const auto& certificate : fileutils::readDirectory(repoPath + "admins")) {
+    for (const auto& certificate : dhtnet::fileutils::readDirectory(repoPath + "admins")) {
         if (certificate.find(".crt") == std::string::npos) {
             JAMI_WARNING("Incorrect file found: {}", certificate);
             continue;
@@ -1667,7 +1666,7 @@ ConversationRepository::Impl::validateDevice()
     }
     auto path = fmt::format("devices/{}.crt", account->currentDeviceId());
     std::string devicePath = git_repository_workdir(repo.get()) + path;
-    if (!fileutils::isFile(devicePath)) {
+    if (!std::filesystem::is_regular_file(devicePath)) {
         JAMI_WARNING("Couldn't find file {}", devicePath);
         return false;
     }
@@ -1706,9 +1705,9 @@ ConversationRepository::Impl::validateDevice()
     auto memberPath = fmt::format("members/{}.crt", account->getUsername());
     std::string parentPath = git_repository_workdir(repo.get());
     std::string relativeParentPath;
-    if (fileutils::isFile(parentPath + adminPath))
+    if (std::filesystem::is_regular_file(parentPath + adminPath))
         relativeParentPath = adminPath;
-    else if (fileutils::isFile(parentPath + memberPath))
+    else if (std::filesystem::is_regular_file(parentPath + memberPath))
         relativeParentPath = memberPath;
     parentPath += relativeParentPath;
     if (relativeParentPath.empty()) {
@@ -1727,7 +1726,7 @@ ConversationRepository::Impl::validateDevice()
                   "current one.");
         auto cert = account->identity().second;
         auto newCert = cert->issuer;
-        if (newCert && fileutils::isFile(parentPath)) {
+        if (newCert && std::filesystem::is_regular_file(parentPath)) {
             auto file = fileutils::ofstream(parentPath, std::ios::trunc | std::ios::binary);
             if (!file.is_open()) {
                 JAMI_ERROR("Could not write data to {}", path);
@@ -2441,7 +2440,7 @@ ConversationRepository::Impl::initMembers()
 
     auto i = 0;
     for (const auto& p : paths) {
-        for (const auto& f : fileutils::readDirectory(p)) {
+        for (const auto& f : dhtnet::fileutils::readDirectory(p)) {
             auto pos = f.find(".crt");
             auto uri = f.substr(0, pos);
             auto it = std::find(uris.begin(), uris.end(), uri);
@@ -2555,13 +2554,13 @@ ConversationRepository::createConversation(const std::shared_ptr<JamiAccount>& a
     random_device rdev;
     auto conversationsPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + account->getAccountID()
                              + DIR_SEPARATOR_STR + "conversations";
-    fileutils::check_dir(conversationsPath.c_str());
+    dhtnet::fileutils::check_dir(conversationsPath.c_str());
     auto tmpPath = conversationsPath + DIR_SEPARATOR_STR + std::to_string(dist(rdev));
-    if (fileutils::isDirectory(tmpPath)) {
+    if (std::filesystem::is_directory(tmpPath)) {
         JAMI_ERROR("{} already exists. Abort create conversations", tmpPath);
         return {};
     }
-    if (!fileutils::recursive_mkdir(tmpPath, 0700)) {
+    if (!dhtnet::fileutils::recursive_mkdir(tmpPath, 0700)) {
         JAMI_ERROR("Error when creating {}. Abort create conversations", tmpPath);
         return {};
     }
@@ -2573,7 +2572,7 @@ ConversationRepository::createConversation(const std::shared_ptr<JamiAccount>& a
     // Add initial files
     if (!add_initial_files(repo, account, mode, otherMember)) {
         JAMI_ERROR("Error when adding initial files");
-        fileutils::removeAll(tmpPath, true);
+        dhtnet::fileutils::removeAll(tmpPath, true);
         return {};
     }
 
@@ -2581,7 +2580,7 @@ ConversationRepository::createConversation(const std::shared_ptr<JamiAccount>& a
     auto id = initial_commit(repo, account, mode, otherMember);
     if (id.empty()) {
         JAMI_ERROR("Couldn't create initial commit in {}", tmpPath);
-        fileutils::removeAll(tmpPath, true);
+        dhtnet::fileutils::removeAll(tmpPath, true);
         return {};
     }
 
@@ -2589,7 +2588,7 @@ ConversationRepository::createConversation(const std::shared_ptr<JamiAccount>& a
     auto newPath = conversationsPath + "/" + id;
     if (std::rename(tmpPath.c_str(), newPath.c_str())) {
         JAMI_ERROR("Couldn't move {} in {}", tmpPath, newPath);
-        fileutils::removeAll(tmpPath, true);
+        dhtnet::fileutils::removeAll(tmpPath, true);
         return {};
     }
 
@@ -2605,7 +2604,7 @@ ConversationRepository::cloneConversation(const std::shared_ptr<JamiAccount>& ac
 {
     auto conversationsPath = fileutils::get_data_dir() + "/" + account->getAccountID() + "/"
                              + "conversations";
-    fileutils::check_dir(conversationsPath.c_str());
+    dhtnet::fileutils::check_dir(conversationsPath.c_str());
     auto path = conversationsPath + "/" + conversationId;
     auto url = fmt::format("git://{}/{}", deviceId, conversationId);
 
@@ -2629,10 +2628,10 @@ ConversationRepository::cloneConversation(const std::shared_ptr<JamiAccount>& ac
         return 0;
     };
 
-    if (fileutils::isDirectory(path)) {
+    if (std::filesystem::is_directory(path)) {
         // If a crash occurs during a previous clone, just in case
         JAMI_WARNING("Removing existing directory {} (the dir exists and non empty)", path);
-        if (fileutils::removeAll(path, true) != 0)
+        if (dhtnet::fileutils::removeAll(path, true) != 0)
             return nullptr;
     }
 
@@ -2890,15 +2889,15 @@ ConversationRepository::addMember(const std::string& uri)
         name = deviceId;
 
     // First, we need to add the member file to the repository if not present
-    std::string repoPath = git_repository_workdir(repo.get());
+    std::filesystem::path repoPath = git_repository_workdir(repo.get());
 
-    std::string invitedPath = repoPath + "invited";
-    if (!fileutils::recursive_mkdir(invitedPath, 0700)) {
+    std::filesystem::path invitedPath = repoPath / "invited";
+    if (!dhtnet::fileutils::recursive_mkdir(invitedPath, 0700)) {
         JAMI_ERROR("Error when creating {}.", invitedPath);
         return {};
     }
-    std::string devicePath = invitedPath + "/" + uri;
-    if (fileutils::isFile(devicePath)) {
+    std::filesystem::path devicePath = invitedPath / uri;
+    if (std::filesystem::is_regular_file(devicePath)) {
         JAMI_WARNING("Member {} already present!", uri);
         return {};
     }
@@ -2909,7 +2908,7 @@ ConversationRepository::addMember(const std::string& uri)
         return {};
     }
     std::string path = "invited/" + uri;
-    if (!pimpl_->add(path.c_str()))
+    if (!pimpl_->add(path))
         return {};
 
     {
@@ -3085,7 +3084,7 @@ ConversationRepository::Impl::addUserDevice()
     // NOTE: libgit2 uses / for files
     std::string path = fmt::format("devices/{}.crt", account->currentDeviceId());
     std::string devicePath = git_repository_workdir(repo.get()) + path;
-    if (!fileutils::isFile(devicePath)) {
+    if (!std::filesystem::is_regular_file(devicePath)) {
         auto file = fileutils::ofstream(devicePath, std::ios::trunc | std::ios::binary);
         if (!file.is_open()) {
             JAMI_ERROR("Could not write data to {}", devicePath);
@@ -3308,15 +3307,15 @@ ConversationRepository::join()
     std::string membersPath = repoPath + "members" + DIR_SEPARATOR_STR;
     std::string memberFile = membersPath + DIR_SEPARATOR_STR + uri + ".crt";
     std::string adminsPath = repoPath + "admins" + DIR_SEPARATOR_STR + uri + ".crt";
-    if (fileutils::isFile(memberFile) or fileutils::isFile(adminsPath)) {
+    if (std::filesystem::is_regular_file(memberFile) or std::filesystem::is_regular_file(adminsPath)) {
         // Already member, nothing to commit
         return {};
     }
     // Remove invited/uri.crt
     std::string invitedPath = repoPath + "invited";
-    fileutils::remove(fileutils::getFullPath(invitedPath, uri));
+    dhtnet::fileutils::remove(fileutils::getFullPath(invitedPath, uri));
     // Add members/uri.crt
-    if (!fileutils::recursive_mkdir(membersPath, 0700)) {
+    if (!dhtnet::fileutils::recursive_mkdir(membersPath, 0700)) {
         JAMI_ERROR("Error when creating {}. Abort create conversations", membersPath);
         return {};
     }
@@ -3381,12 +3380,12 @@ ConversationRepository::leave()
     std::string memberFile = fmt::format("{}members/{}.crt", repoPath, uri);
     std::string crlsPath = fmt::format("{}CRLs", repoPath);
 
-    if (fileutils::isFile(adminFile)) {
-        fileutils::removeAll(adminFile, true);
+    if (std::filesystem::is_regular_file(adminFile)) {
+        dhtnet::fileutils::removeAll(adminFile, true);
     }
 
-    if (fileutils::isFile(memberFile)) {
-        fileutils::removeAll(memberFile, true);
+    if (std::filesystem::is_regular_file(memberFile)) {
+        dhtnet::fileutils::removeAll(memberFile, true);
     }
 
     // /CRLs
@@ -3394,16 +3393,16 @@ ConversationRepository::leave()
         if (!crl)
             continue;
         std::string crlPath = fmt::format("{}/{}/{}.crl", crlsPath, deviceId, dht::toHex(crl->getNumber()));
-        if (fileutils::isFile(crlPath)) {
-            fileutils::removeAll(crlPath, true);
+        if (std::filesystem::is_regular_file(crlPath)) {
+            dhtnet::fileutils::removeAll(crlPath, true);
         }
     }
 
     // Devices
     for (const auto& d : account->getKnownDevices()) {
         std::string deviceFile = fmt::format("{}devices/{}.crt", repoPath, d.first);
-        if (fileutils::isFile(deviceFile)) {
-            fileutils::removeAll(deviceFile, true);
+        if (std::filesystem::is_regular_file(deviceFile)) {
+            dhtnet::fileutils::removeAll(deviceFile, true);
         }
     }
 
@@ -3436,7 +3435,7 @@ ConversationRepository::erase()
     if (auto repo = pimpl_->repository()) {
         std::string repoPath = git_repository_workdir(repo.get());
         JAMI_LOG("Erasing {}", repoPath);
-        fileutils::removeAll(repoPath, true);
+        dhtnet::fileutils::removeAll(repoPath, true);
     }
 }
 
@@ -3463,7 +3462,7 @@ ConversationRepository::voteKick(const std::string& uri, const std::string& type
         return {};
     }
 
-    if (!fileutils::isFile(
+    if (!std::filesystem::is_regular_file(
             fmt::format("{}/{}/{}{}", repoPath, type, uri, (type != "invited" ? ".crt" : "")))) {
         JAMI_WARNING("Didn't found file for {} with type {}", uri, type);
         return {};
@@ -3471,7 +3470,7 @@ ConversationRepository::voteKick(const std::string& uri, const std::string& type
 
     auto relativeVotePath = fmt::format("votes/ban/{}/{}", type, uri);
     auto voteDirectory = repoPath + relativeVotePath;
-    if (!fileutils::recursive_mkdir(voteDirectory, 0700)) {
+    if (!dhtnet::fileutils::recursive_mkdir(voteDirectory, 0700)) {
         JAMI_ERROR("Error when creating {}. Abort vote", voteDirectory);
         return {};
     }
@@ -3511,7 +3510,7 @@ ConversationRepository::voteUnban(const std::string& uri, const std::string_view
 
     auto relativeVotePath = fmt::format("votes/unban/{}/{}", type, uri);
     auto voteDirectory = repoPath + DIR_SEPARATOR_STR + relativeVotePath;
-    if (!fileutils::recursive_mkdir(voteDirectory, 0700)) {
+    if (!dhtnet::fileutils::recursive_mkdir(voteDirectory, 0700)) {
         JAMI_ERROR("Error when creating {}. Abort vote", voteDirectory);
         return {};
     }
@@ -3549,7 +3548,7 @@ ConversationRepository::Impl::resolveBan(const std::string_view type, const std:
 
     auto destPath = bannedPath + DIR_SEPARATOR_STR + type;
     auto destFilePath = fmt::format("{}/{}{}", destPath, uri, crtStr);
-    if (!fileutils::recursive_mkdir(destPath, 0700)) {
+    if (!dhtnet::fileutils::recursive_mkdir(destPath, 0700)) {
         JAMI_ERROR("Error when creating {}. Abort resolving vote", destPath);
         return false;
     }
@@ -3563,13 +3562,13 @@ ConversationRepository::Impl::resolveBan(const std::string_view type, const std:
 
     // If members, remove related devices and mark as banned
     if (type != "devices") {
-        for (const auto& certificate : fileutils::readDirectory(devicesPath)) {
+        for (const auto& certificate : dhtnet::fileutils::readDirectory(devicesPath)) {
             auto certPath = fileutils::getFullPath(devicesPath, certificate);
             try {
                 crypto::Certificate cert(fileutils::loadFile(certPath));
                 if (auto issuer = cert.issuer)
                     if (issuer->toString() == uri)
-                        fileutils::remove(certPath, true);
+                        dhtnet::fileutils::remove(certPath, true);
             } catch (...) {
                 continue;
             }
@@ -3600,7 +3599,7 @@ ConversationRepository::Impl::resolveUnban(const std::string_view type, const st
     auto originFilePath = fmt::format("{}/{}/{}{}", bannedPath, type, uri, crtStr);
     auto destPath = repoPath + DIR_SEPARATOR_STR + type;
     auto destFilePath = fmt::format("{}/{}{}", destPath, uri, crtStr);
-    if (!fileutils::recursive_mkdir(destPath, 0700)) {
+    if (!dhtnet::fileutils::recursive_mkdir(destPath, 0700)) {
         JAMI_ERROR("Error when creating {}. Abort resolving vote", destPath);
         return false;
     }
@@ -3648,14 +3647,14 @@ ConversationRepository::resolveVote(const std::string& uri,
     auto votePath = fmt::format("{}/{}", voteType, type);
 
     auto voteDirectory = fmt::format("{}/votes/{}/{}", repoPath, votePath, uri);
-    for (const auto& certificate : fileutils::readDirectory(adminsPath)) {
+    for (const auto& certificate : dhtnet::fileutils::readDirectory(adminsPath)) {
         if (certificate.find(".crt") == std::string::npos) {
             JAMI_WARNING("Incorrect file found: {}/{}", adminsPath, certificate);
             continue;
         }
         auto adminUri = certificate.substr(0, certificate.size() - std::string(".crt").size());
         nbAdmins += 1;
-        if (fileutils::isFile(fileutils::getFullPath(voteDirectory, adminUri)))
+        if (std::filesystem::is_regular_file(fileutils::getFullPath(voteDirectory, adminUri)))
             nbVotes += 1;
     }
 
@@ -3663,7 +3662,7 @@ ConversationRepository::resolveVote(const std::string& uri,
         JAMI_WARNING("More than half of the admins voted to ban {}, apply the ban", uri);
 
         // Remove vote directory
-        fileutils::removeAll(voteDirectory, true);
+        dhtnet::fileutils::removeAll(voteDirectory, true);
 
         if (voteType == "ban") {
             if (!pimpl_->resolveBan(type, uri))
@@ -3885,7 +3884,7 @@ ConversationRepository::infos() const
             std::string repoPath = git_repository_workdir(repo.get());
             auto profilePath = repoPath + "profile.vcf";
             std::map<std::string, std::string> result;
-            if (fileutils::isFile(profilePath)) {
+            if (std::filesystem::is_regular_file(profilePath)) {
                 auto content = fileutils::loadFile(profilePath);
                 result = ConversationRepository::infosFromVCard(vCard::utils::toMap(
                     std::string_view {(const char*) content.data(), content.size()}));
diff --git a/src/jamidht/jamiaccount.cpp b/src/jamidht/jamiaccount.cpp
index a6c90ff35bc86b462061e1a5e77022d8c41edcf0..075306ecc64f8849bff15b3f10e047ecbe7011dc 100644
--- a/src/jamidht/jamiaccount.cpp
+++ b/src/jamidht/jamiaccount.cpp
@@ -271,7 +271,7 @@ JamiAccount::JamiAccount(const std::string& accountId)
     : SIPAccountBase(accountId)
     , idPath_(fileutils::get_data_dir() + DIR_SEPARATOR_STR + accountId)
     , cachePath_(fileutils::get_cache_dir() + DIR_SEPARATOR_STR + accountId)
-    , dataPath_(cachePath_ + DIR_SEPARATOR_STR "values")
+    , dataPath_(cachePath_ / "values")
     , certStore_ {std::make_unique<dhtnet::tls::CertificateStore>(idPath_, Logger::dhtLogger())}
     , dht_(new dht::DhtRunner)
     , connectionManager_ {}
@@ -317,9 +317,9 @@ JamiAccount::flush()
     // Class base method
     SIPAccountBase::flush();
 
-    fileutils::removeAll(cachePath_);
-    fileutils::removeAll(dataPath_);
-    fileutils::removeAll(idPath_, true);
+    dhtnet::fileutils::removeAll(cachePath_);
+    dhtnet::fileutils::removeAll(dataPath_);
+    dhtnet::fileutils::removeAll(idPath_, true);
 }
 
 std::shared_ptr<SIPCall>
@@ -864,7 +864,7 @@ JamiAccount::saveConfig() const
         YAML::Emitter accountOut;
         config().serialize(accountOut);
         auto accountConfig = config().path + DIR_SEPARATOR_STR + "config.yml";
-        std::lock_guard<std::mutex> lock(fileutils::getFileLock(accountConfig));
+        std::lock_guard<std::mutex> lock(dhtnet::fileutils::getFileLock(accountConfig));
         std::ofstream fout = fileutils::ofstream(accountConfig);
         fout.write(accountOut.c_str(), accountOut.size());
         JAMI_DBG("Saved account config to %s", accountConfig.c_str());
@@ -892,7 +892,7 @@ JamiAccount::loadConfig()
         }
     }
     try {
-        auto str = fileutils::loadCacheTextFile(cachePath_ + DIR_SEPARATOR_STR "dhtproxy",
+        auto str = fileutils::loadCacheTextFile(cachePath_ / "dhtproxy",
                                                 std::chrono::hours(24 * 7));
         std::string err;
         Json::Value root;
@@ -1154,9 +1154,8 @@ JamiAccount::loadAccount(const std::string& archive_password,
             dht::ThreadPool::io().run([w = weak(), convFromReq, uri] {
                 if (auto shared = w.lock()) {
                     // Remove cached payload if there is one
-                    auto requestPath = shared->cachePath_ + DIR_SEPARATOR_STR + "requests"
-                                       + DIR_SEPARATOR_STR + uri;
-                    fileutils::remove(requestPath);
+                    auto requestPath = shared->cachePath_ / "requests"/ uri;
+                    dhtnet::fileutils::remove(requestPath);
                     if (!convFromReq.empty()) {
                         auto oldConv = shared->convModule()->getOneToOneConversation(uri);
                         // If we previously removed the contact, and re-add it, we may
@@ -1237,7 +1236,7 @@ JamiAccount::loadAccount(const std::string& archive_password,
             if (conf.managerUri.empty()) {
                 auto acreds = std::make_unique<ArchiveAccountManager::ArchiveAccountCredentials>();
                 auto archivePath = fileutils::getFullPath(idPath_, conf.archivePath);
-                bool hasArchive = fileutils::isFile(archivePath);
+                bool hasArchive = std::filesystem::is_regular_file(archivePath);
 
                 if (not archive_path.empty()) {
                     // Importing external archive
@@ -1278,7 +1277,7 @@ JamiAccount::loadAccount(const std::string& archive_password,
                     if (not sthis) return;
                     JAMI_LOG("[Account {}] Auth success!", getAccountID());
 
-                    fileutils::check_dir(idPath_.c_str(), 0700);
+                    dhtnet::fileutils::check_dir(idPath_.c_str(), 0700);
 
                     auto id = info.identity;
                     editConfig([&](JamiAccountConfig& conf) {
@@ -1712,8 +1711,7 @@ JamiAccount::onTrackedBuddyOnline(const dht::InfoHash& contactId)
         std::lock_guard<std::recursive_mutex> lock(configurationMutex_);
         if (accountManager_) {
             // Retrieve cached payload for trust request.
-            auto requestPath = cachePath_ + DIR_SEPARATOR_STR + "requests" + DIR_SEPARATOR_STR
-                               + contactId.toString();
+            auto requestPath = cachePath_ / "requests" / contactId.toString();
             std::vector<uint8_t> payload;
             try {
                 payload = fileutils::loadFile(requestPath);
@@ -1794,7 +1792,7 @@ JamiAccount::doRegister_()
         dht::DhtRunner::Config config {};
         config.dht_config.node_config.network = 0;
         config.dht_config.node_config.maintain_storage = false;
-        config.dht_config.node_config.persist_path = cachePath_ + DIR_SEPARATOR_STR "dhtstate";
+        config.dht_config.node_config.persist_path = cachePath_ / "dhtstate";
         config.dht_config.id = id_;
         config.dht_config.cert_cache_all = true;
         config.push_node_id = getAccountID();
@@ -2476,7 +2474,7 @@ void
 JamiAccount::loadTreatedMessages()
 {
     std::lock_guard<std::mutex> lock(messageMutex_);
-    auto path = cachePath_ + DIR_SEPARATOR_STR "treatedMessages";
+    auto path = cachePath_ / "treatedMessages";
     treatedMessages_ = loadIdList<std::string>(path);
     if (treatedMessages_.empty()) {
         auto messages = loadIdList(path);
@@ -2492,9 +2490,8 @@ JamiAccount::saveTreatedMessages() const
         if (auto sthis = w.lock()) {
             auto& this_ = *sthis;
             std::lock_guard<std::mutex> lock(this_.messageMutex_);
-            fileutils::check_dir(this_.cachePath_.c_str());
-            saveIdList<decltype(this_.treatedMessages_)>(this_.cachePath_
-                                                             + DIR_SEPARATOR_STR "treatedMessages",
+            dhtnet::fileutils::check_dir(this_.cachePath_.c_str());
+            saveIdList<decltype(this_.treatedMessages_)>(this_.cachePath_ / "treatedMessages",
                                                          this_.treatedMessages_);
         }
     });
@@ -2537,7 +2534,7 @@ JamiAccount::loadCachedUrl(const std::string& url,
         try {
             std::vector<uint8_t> data;
             {
-                std::lock_guard<std::mutex> lk(fileutils::getFileLock(cachePath));
+                std::lock_guard<std::mutex> lk(dhtnet::fileutils::getFileLock(cachePath));
                 data = fileutils::loadCacheFile(cachePath, cacheDuration);
             }
             dht::http::Response ret;
@@ -2554,7 +2551,7 @@ JamiAccount::loadCachedUrl(const std::string& url,
                     [cb, cachePath, w](const dht::http::Response& response) {
                         if (response.status_code == 200) {
                             try {
-                                std::lock_guard<std::mutex> lk(fileutils::getFileLock(cachePath));
+                                std::lock_guard<std::mutex> lk(dhtnet::fileutils::getFileLock(cachePath));
                                 fileutils::saveFile(cachePath,
                                                     (const uint8_t*) response.body.data(),
                                                     response.body.size(),
@@ -2593,7 +2590,7 @@ JamiAccount::loadCachedProxyServer(std::function<void(const std::string& proxy)>
             cb(getDhtProxyServer(conf.proxyServer));
         } else {
             loadCachedUrl(conf.proxyListUrl,
-                          cachePath_ + DIR_SEPARATOR_STR "dhtproxylist",
+                          cachePath_ / "dhtproxylist",
                           std::chrono::hours(24 * 3),
                           [w = weak(), cb = std::move(cb)](const dht::http::Response& response) {
                               if (auto sthis = w.lock()) {
@@ -2641,8 +2638,8 @@ JamiAccount::getDhtProxyServer(const std::string& serverList)
                      std::uniform_int_distribution<unsigned long>(0, proxys.size() - 1)(rand));
         proxyServerCached_ = *randIt;
         // Cache it!
-        fileutils::check_dir(cachePath_.c_str(), 0700);
-        std::string proxyCachePath = cachePath_ + DIR_SEPARATOR_STR "dhtproxy";
+        dhtnet::fileutils::check_dir(cachePath_, 0700);
+        auto proxyCachePath = cachePath_ / "dhtproxy";
         std::ofstream file = fileutils::ofstream(proxyCachePath);
         JAMI_DEBUG("Cache DHT proxy server: {}", proxyServerCached_);
         Json::Value node(Json::objectValue);
@@ -2942,9 +2939,9 @@ void
 JamiAccount::sendTrustRequest(const std::string& to, const std::vector<uint8_t>& payload)
 {
     // Here we cache payload sent by the client
-    auto requestPath = cachePath_ + DIR_SEPARATOR_STR + "requests";
-    fileutils::recursive_mkdir(requestPath, 0700);
-    auto cachedFile = requestPath + DIR_SEPARATOR_STR + to;
+    auto requestPath = cachePath_ / "requests";
+    dhtnet::fileutils::recursive_mkdir(requestPath, 0700);
+    auto cachedFile = requestPath / to;
     std::ofstream req = fileutils::ofstream(cachedFile, std::ios::trunc | std::ios::binary);
     if (!req.is_open()) {
         JAMI_ERR("Could not write data to %s", cachedFile.c_str());
@@ -3663,7 +3660,7 @@ JamiAccount::sendProfile(const std::string& convId,
                          const std::string& peerUri,
                          const std::string& deviceId)
 {
-    if (not fileutils::isFile(profilePath()))
+    if (not std::filesystem::is_regular_file(profilePath()))
         return;
     auto currentSha3 = fileutils::sha3File(profilePath());
     // VCard sync for peerUri
@@ -3688,9 +3685,9 @@ JamiAccount::sendProfile(const std::string& convId,
                                                 accId,
                                                 peerUri);
                      auto path = fmt::format("{}/{}", sendDir, deviceId);
-                     fileutils::recursive_mkdir(sendDir);
-                     std::lock_guard<std::mutex> lock(fileutils::getFileLock(path));
-                     if (fileutils::isFile(path))
+                     dhtnet::fileutils::recursive_mkdir(sendDir);
+                     std::lock_guard<std::mutex> lock(dhtnet::fileutils::getFileLock(path));
+                     if (std::filesystem::is_regular_file(path))
                          return;
                      fileutils::ofstream(path);
                  });
@@ -3704,7 +3701,7 @@ JamiAccount::needToSendProfile(const std::string& peerUri,
     std::string previousSha3 {};
     auto vCardPath = fmt::format("{}/vcard", cachePath_);
     auto sha3Path = fmt::format("{}/sha3", vCardPath);
-    fileutils::check_dir(vCardPath.c_str(), 0700);
+    dhtnet::fileutils::check_dir(vCardPath, 0700);
     try {
         previousSha3 = fileutils::loadTextFile(sha3Path);
     } catch (...) {
@@ -3713,15 +3710,15 @@ JamiAccount::needToSendProfile(const std::string& peerUri,
     }
     if (sha3Sum != previousSha3) {
         // Incorrect sha3 stored. Update it
-        fileutils::removeAll(vCardPath, true);
-        fileutils::check_dir(vCardPath.c_str(), 0700);
-        fileutils::saveFile(sha3Path, {sha3Sum.begin(), sha3Sum.end()}, 0600);
+        dhtnet::fileutils::removeAll(vCardPath, true);
+        dhtnet::fileutils::check_dir(vCardPath.c_str(), 0700);
+        dhtnet::fileutils::saveFile(sha3Path, {sha3Sum.begin(), sha3Sum.end()}, 0600);
         return true;
     }
-    fileutils::recursive_mkdir(fmt::format("{}/{}/", vCardPath, peerUri));
+    dhtnet::fileutils::recursive_mkdir(fmt::format("{}/{}/", vCardPath, peerUri));
 
     auto path = fmt::format("{}/{}/{}", vCardPath, peerUri, deviceId);
-    auto res = not fileutils::isFile(path);
+    auto res = not std::filesystem::is_regular_file(path);
     return res;
 }
 
@@ -3818,13 +3815,13 @@ JamiAccount::sendSIPMessage(SipConnection& conn,
 void
 JamiAccount::clearProfileCache(const std::string& peerUri)
 {
-    fileutils::removeAll(fmt::format("{}/vcard/{}", cachePath_, peerUri));
+    dhtnet::fileutils::removeAll(fmt::format("{}/vcard/{}", cachePath_, peerUri));
 }
 
-std::string
+std::filesystem::path
 JamiAccount::profilePath() const
 {
-    return idPath_ + DIR_SEPARATOR_STR + "profile.vcf";
+    return idPath_ / "profile.vcf";
 }
 
 void
@@ -3987,7 +3984,7 @@ JamiAccount::sendFile(const std::string& conversationId,
                       const std::string& name,
                       const std::string& replyTo)
 {
-    if (!fileutils::isFile(path)) {
+    if (!std::filesystem::is_regular_file(path)) {
         JAMI_ERR() << "invalid filename '" << path << "'";
         return;
     }
@@ -4020,7 +4017,7 @@ JamiAccount::sendFile(const std::string& conversationId,
                     auto extension = fileutils::getFileExtension(path);
                     if (!extension.empty())
                         filelinkPath += "." + extension;
-                    if (path != filelinkPath && !fileutils::isSymLink(filelinkPath)) {
+                    if (path != filelinkPath && !std::filesystem::is_symlink(filelinkPath)) {
                         if (!fileutils::createFileLink(filelinkPath, path, true)) {
                             JAMI_WARNING(
                                 "Cannot create symlink for file transfer {} - {}. Copy file",
diff --git a/src/jamidht/jamiaccount.h b/src/jamidht/jamiaccount.h
index 919af7d415f4780e3faf5ec46b232872ce5da265..5179ba50bb0903caa8f66add92abc1862591982b 100644
--- a/src/jamidht/jamiaccount.h
+++ b/src/jamidht/jamiaccount.h
@@ -55,15 +55,16 @@
 #include <opendht/default_types.h>
 
 #include <pjsip/sip_types.h>
+#include <json/json.h>
 
 #include <chrono>
 #include <functional>
 #include <future>
-#include <json/json.h>
 #include <list>
 #include <map>
 #include <optional>
 #include <vector>
+#include <filesystem>
 
 #if HAVE_RINGNS
 #include "namedirectory.h"
@@ -121,7 +122,7 @@ public:
         return std::static_pointer_cast<JamiAccount const>(shared_from_this());
     }
 
-    const std::string& getPath() const { return idPath_; }
+    const std::filesystem::path& getPath() const { return idPath_; }
 
     const JamiAccountConfig& config() const
     {
@@ -529,7 +530,7 @@ public:
      */
     void clearProfileCache(const std::string& peerUri);
 
-    std::string profilePath() const;
+    std::filesystem::path profilePath() const;
 
     AccountManager* accountManager()
     {
@@ -698,9 +699,9 @@ private:
     void newSwarmOutgoingCallHelper(const std::shared_ptr<SIPCall>& call, const Uri& uri);
     std::shared_ptr<SIPCall> createSubCall(const std::shared_ptr<SIPCall>& mainCall);
 
-    std::string idPath_ {};
-    std::string cachePath_ {};
-    std::string dataPath_ {};
+    std::filesystem::path idPath_ {};
+    std::filesystem::path cachePath_ {};
+    std::filesystem::path dataPath_ {};
 
 #if HAVE_RINGNS
     std::string registeredName_;
diff --git a/src/jamidht/namedirectory.cpp b/src/jamidht/namedirectory.cpp
index f490a9f0a186a439bdbaf124f4835d3046510693..78de8afb6eba134e65fb23e9eb118f3a0eb028fa 100644
--- a/src/jamidht/namedirectory.cpp
+++ b/src/jamidht/namedirectory.cpp
@@ -449,8 +449,8 @@ NameDirectory::scheduleCacheSave()
 void
 NameDirectory::saveCache()
 {
-    fileutils::recursive_mkdir(fileutils::get_cache_dir() + DIR_SEPARATOR_STR + CACHE_DIRECTORY);
-    std::lock_guard<std::mutex> lock(fileutils::getFileLock(cachePath_));
+    dhtnet::fileutils::recursive_mkdir(fileutils::get_cache_dir() + DIR_SEPARATOR_STR + CACHE_DIRECTORY);
+    std::lock_guard<std::mutex> lock(dhtnet::fileutils::getFileLock(cachePath_));
     std::ofstream file = fileutils::ofstream(cachePath_, std::ios::trunc | std::ios::binary);
     {
         std::lock_guard<std::mutex> l(cacheLock_);
@@ -468,7 +468,7 @@ NameDirectory::loadCache()
 
     // read file
     {
-        std::lock_guard<std::mutex> lock(fileutils::getFileLock(cachePath_));
+        std::lock_guard<std::mutex> lock(dhtnet::fileutils::getFileLock(cachePath_));
         std::ifstream file = fileutils::ifstream(cachePath_);
         if (!file.is_open()) {
             JAMI_DBG("Could not load %s", cachePath_.c_str());
diff --git a/src/logger.cpp b/src/logger.cpp
index 01bda18cb871a53d8aa1a9a5d6961d208f4def18..878cdb7a047cd1cb260acacf8adbb1afbf325705 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -30,11 +30,6 @@
 #include <fmt/core.h>
 #include <fmt/format.h>
 #include <fmt/compile.h>
-#if __has_include(<fmt/std.h>)
-#include <fmt/std.h>
-#else
-#include <fmt/ostream.h>
-#endif
 
 #ifdef _MSC_VER
 #include <sys_time.h>
diff --git a/src/logger.h b/src/logger.h
index 00804b5b1f9d7e18e935fb420958e5e8dddf1733..c2e95609d0fdec1df8f61fe72558a447352a3b2a 100644
--- a/src/logger.h
+++ b/src/logger.h
@@ -28,6 +28,11 @@
 #include <fmt/format.h>
 #include <fmt/chrono.h>
 #include <fmt/printf.h>
+#if __has_include(<fmt/std.h>)
+#include <fmt/std.h>
+#else
+#include <fmt/ostream.h>
+#endif
 #include <opendht/logger.h>
 #include <cinttypes> // for PRIx64
 #include <cstdarg>
diff --git a/src/manager.cpp b/src/manager.cpp
index 1b5bc2716b33d1c542562ea345d7568fc4dc5c99..96d9d299b72d3a5ebb5b6ec348644ec61b8a120b 100644
--- a/src/manager.cpp
+++ b/src/manager.cpp
@@ -173,24 +173,24 @@ restore_backup(const std::string& path)
 void
 check_rename(const std::string& old_dir, const std::string& new_dir)
 {
-    if (old_dir == new_dir or not fileutils::isDirectory(old_dir))
+    if (old_dir == new_dir or not std::filesystem::is_directory(old_dir))
         return;
 
-    if (not fileutils::isDirectory(new_dir)) {
+    if (not std::filesystem::is_directory(new_dir)) {
         JAMI_WARN() << "Migrating " << old_dir << " to " << new_dir;
         std::rename(old_dir.c_str(), new_dir.c_str());
     } else {
-        for (const auto& file : fileutils::readDirectory(old_dir)) {
+        for (const auto& file : dhtnet::fileutils::readDirectory(old_dir)) {
             auto old_dest = fileutils::getFullPath(old_dir, file);
             auto new_dest = fileutils::getFullPath(new_dir, file);
-            if (fileutils::isDirectory(old_dest) and fileutils::isDirectory(new_dest)) {
+            if (std::filesystem::is_directory(old_dest) and std::filesystem::is_directory(new_dest)) {
                 check_rename(old_dest, new_dest);
             } else {
                 JAMI_WARN() << "Migrating " << old_dest << " to " << new_dest;
                 std::rename(old_dest.c_str(), new_dest.c_str());
             }
         }
-        fileutils::removeAll(old_dir);
+        dhtnet::fileutils::removeAll(old_dir);
     }
 }
 
@@ -944,7 +944,7 @@ Manager::monitor(bool continuous)
 #ifdef __linux__
 #if defined(__ANDROID__)
 #else
-    auto opened_files = fileutils::readDirectory("/proc/" + std::to_string(getpid()) + "/fd").size();
+    auto opened_files = dhtnet::fileutils::readDirectory("/proc/" + std::to_string(getpid()) + "/fd").size();
     JAMI_DBG("Opened files: %lu", opened_files);
 #endif
 #endif
@@ -1779,10 +1779,10 @@ Manager::saveConfig()
         out << YAML::Value << YAML::BeginSeq;
 
         for (const auto& account : accountFactory.getAllAccounts()) {
-            if (auto ringAccount = std::dynamic_pointer_cast<JamiAccount>(account)) {
-                auto accountConfig = ringAccount->getPath() + DIR_SEPARATOR_STR + "config.yml";
-                if (not fileutils::isFile(accountConfig)) {
-                    saveConfig(ringAccount);
+            if (auto jamiAccount = std::dynamic_pointer_cast<JamiAccount>(account)) {
+                auto accountConfig = jamiAccount->getPath() / "config.yml";
+                if (not std::filesystem::is_regular_file(accountConfig)) {
+                    saveConfig(jamiAccount);
                 }
             } else {
                 account->config().serialize(out);
@@ -1802,7 +1802,7 @@ Manager::saveConfig()
         pluginPreferences.serialize(out);
 #endif
 
-        std::lock_guard<std::mutex> lock(fileutils::getFileLock(pimpl_->path_));
+        std::lock_guard<std::mutex> lock(dhtnet::fileutils::getFileLock(pimpl_->path_));
         std::ofstream fout = fileutils::ofstream(pimpl_->path_);
         fout.write(out.c_str(), out.size());
     } catch (const YAML::Exception& e) {
@@ -2867,7 +2867,7 @@ Manager::loadAccountMap(const YAML::Node& node)
     }
 
     auto accountBaseDir = fileutils::get_data_dir();
-    auto dirs = fileutils::readDirectory(accountBaseDir);
+    auto dirs = dhtnet::fileutils::readDirectory(accountBaseDir);
 
     std::condition_variable cv;
     std::mutex lock;
@@ -2885,7 +2885,7 @@ Manager::loadAccountMap(const YAML::Node& node)
                                             &lock,
                                             configFile = accountBaseDir + DIR_SEPARATOR_STR + dir
                                                          + DIR_SEPARATOR_STR + "config.yml"] {
-            if (fileutils::isFile(configFile)) {
+            if (std::filesystem::is_regular_file(configFile)) {
                 try {
                     auto configNode = YAML::LoadFile(configFile);
                     if (auto a = accountFactory.createAccount(JamiAccount::ACCOUNT_TYPE, dir)) {
diff --git a/src/media/media_encoder.cpp b/src/media/media_encoder.cpp
index 2858b5945f4504a6622ea9cf8700f5085400e4e2..6fa3c64528fd6d8252dcf2cb894252afa13d2b4b 100644
--- a/src/media/media_encoder.cpp
+++ b/src/media/media_encoder.cpp
@@ -1139,7 +1139,7 @@ MediaEncoder::readConfig(AVCodecContext* encoderCtx)
 {
     std::string path = fileutils::get_config_dir() + DIR_SEPARATOR_STR + "encoder.json";
     std::string name = encoderCtx->codec->name;
-    if (fileutils::isFile(path)) {
+    if (std::filesystem::is_regular_file(path)) {
         JAMI_WARN("encoder.json file found, default settings will be erased");
         try {
             Json::Value root;
diff --git a/src/media/recordable.cpp b/src/media/recordable.cpp
index 6124fb3c95dda2bc6f089ed45b43d95bc34fb685..6760200b95814e13287c055b66c73c1c0740a132 100644
--- a/src/media/recordable.cpp
+++ b/src/media/recordable.cpp
@@ -62,7 +62,7 @@ Recordable::toggleRecording()
         if (dir.empty())
             dir = fileutils::get_home_dir();
         // Check if dir exists, create if if it does not
-        fileutils::check_dir(dir.c_str());
+        dhtnet::fileutils::check_dir(dir.c_str());
         ss << dir;
         if (dir.back() != DIR_SEPARATOR_CH)
             ss << DIR_SEPARATOR_CH;
diff --git a/src/plugin/jamipluginmanager.cpp b/src/plugin/jamipluginmanager.cpp
index b2566af0223d644bd8bb9969510ce6505a8eceab..fdba70d874f2751cfd0eceea28ca7aa5757c4dcb 100644
--- a/src/plugin/jamipluginmanager.cpp
+++ b/src/plugin/jamipluginmanager.cpp
@@ -96,7 +96,7 @@ JamiPluginManager::getInstalledPlugins()
 {
     // Gets all plugins in standard path
     std::string pluginsPath = fileutils::get_data_dir() + DIR_SEPARATOR_CH + "plugins";
-    std::vector<std::string> pluginsPaths = fileutils::readDirectory(pluginsPath);
+    std::vector<std::string> pluginsPaths = dhtnet::fileutils::readDirectory(pluginsPath);
     std::for_each(pluginsPaths.begin(), pluginsPaths.end(), [&pluginsPath](std::string& x) {
         x = pluginsPath + DIR_SEPARATOR_CH + x;
     });
@@ -135,7 +135,7 @@ bool
 JamiPluginManager::checkPluginSignatureFile(const std::string& jplPath)
 {
     // check if the file exists
-    if (!fileutils::isFile(jplPath)){
+    if (!std::filesystem::is_regular_file(jplPath)){
         return false;
     }
     try {
@@ -164,7 +164,7 @@ JamiPluginManager::checkPluginSignatureFile(const std::string& jplPath)
 bool
 JamiPluginManager::checkPluginSignatureValidity(const std::string& jplPath, dht::crypto::Certificate* cert)
 {
-    if (!fileutils::isFile(jplPath))
+    if (!std::filesystem::is_regular_file(jplPath))
         return false;
     try{
         const auto& pk = cert->getPublicKey();
@@ -190,7 +190,7 @@ JamiPluginManager::checkPluginSignatureValidity(const std::string& jplPath, dht:
 bool
 JamiPluginManager::checkPluginSignature(const std::string& jplPath, dht::crypto::Certificate* cert)
 {
-    if (!fileutils::isFile(jplPath) || !cert || !*cert)
+    if (!std::filesystem::is_regular_file(jplPath) || !cert || !*cert)
         return false;
     try {
         return  checkPluginSignatureValidity(jplPath, cert) &&
@@ -203,7 +203,7 @@ JamiPluginManager::checkPluginSignature(const std::string& jplPath, dht::crypto:
 std::unique_ptr<dht::crypto::Certificate>
 JamiPluginManager::checkPluginCertificate(const std::string& jplPath, bool force)
 {
-    if (!fileutils::isFile(jplPath))
+    if (!std::filesystem::is_regular_file(jplPath))
         return {};
     try {
         auto cert = PluginUtils::readPluginCertificateFromArchive(jplPath);
@@ -220,7 +220,7 @@ int
 JamiPluginManager::installPlugin(const std::string& jplPath, bool force)
 {
     int r {SUCCESS};
-    if (fileutils::isFile(jplPath)) {
+    if (std::filesystem::is_regular_file(jplPath)) {
         try {
             auto manifestMap = PluginUtils::readPluginManifestFromArchive(jplPath);
             const std::string& name = manifestMap["name"];
@@ -290,12 +290,12 @@ JamiPluginManager::uninstallPlugin(const std::string& rootPath)
                 }
             }
             for (const auto& accId : jami::Manager::instance().getAccountList())
-                fileutils::removeAll(fileutils::get_data_dir() + DIR_SEPARATOR_CH + accId
+                dhtnet::fileutils::removeAll(fileutils::get_data_dir() + DIR_SEPARATOR_CH + accId
                                      + DIR_SEPARATOR_CH + "plugins" + DIR_SEPARATOR_CH
                                      + detailsIt->second.at("name"));
             pluginDetailsMap_.erase(detailsIt);
         }
-        return fileutils::removeAll(rootPath);
+        return dhtnet::fileutils::removeAll(rootPath);
     } else {
         JAMI_INFO() << "PLUGIN: not installed.";
         return -1;
@@ -405,7 +405,7 @@ JamiPluginManager::setPluginPreference(const std::string& rootPath,
         pluginUserPreferencesMap[key] = value;
         const std::string preferencesValuesFilePath
             = PluginPreferencesUtils::valuesFilePath(rootPath, acc);
-        std::lock_guard<std::mutex> guard(fileutils::getFileLock(preferencesValuesFilePath));
+        std::lock_guard<std::mutex> guard(dhtnet::fileutils::getFileLock(preferencesValuesFilePath));
         std::ofstream fs(preferencesValuesFilePath, std::ios::binary);
         if (!fs.good()) {
             if (force) {
diff --git a/src/plugin/pluginpreferencesutils.cpp b/src/plugin/pluginpreferencesutils.cpp
index a60a9cef8b3a4c24df9aaf327888c128c7169323..a4dc68b701ff078247e1e5336c116efa83e74750 100644
--- a/src/plugin/pluginpreferencesutils.cpp
+++ b/src/plugin/pluginpreferencesutils.cpp
@@ -50,7 +50,7 @@ PluginPreferencesUtils::valuesFilePath(const std::string& rootPath, const std::s
     auto pluginName = rootPath.substr(rootPath.find_last_of(DIR_SEPARATOR_CH) + 1);
     auto dir = fileutils::get_data_dir() + DIR_SEPARATOR_CH + accountId + DIR_SEPARATOR_CH
                + "plugins" + DIR_SEPARATOR_CH + pluginName;
-    fileutils::check_dir(dir.c_str());
+    dhtnet::fileutils::check_dir(dir.c_str());
     return dir + DIR_SEPARATOR_CH + "preferences.msgpack";
 }
 
@@ -105,7 +105,7 @@ std::vector<std::map<std::string, std::string>>
 PluginPreferencesUtils::getPreferences(const std::string& rootPath, const std::string& accountId)
 {
     std::string preferenceFilePath = getPreferencesConfigFilePath(rootPath, accountId);
-    std::lock_guard<std::mutex> guard(fileutils::getFileLock(preferenceFilePath));
+    std::lock_guard<std::mutex> guard(dhtnet::fileutils::getFileLock(preferenceFilePath));
     std::ifstream file(preferenceFilePath);
     Json::Value root;
     Json::CharReaderBuilder rbuilder;
@@ -170,7 +170,7 @@ PluginPreferencesUtils::getUserPreferencesValuesMap(const std::string& rootPath,
                                                     const std::string& accountId)
 {
     const std::string preferencesValuesFilePath = valuesFilePath(rootPath, accountId);
-    std::lock_guard<std::mutex> guard(fileutils::getFileLock(preferencesValuesFilePath));
+    std::lock_guard<std::mutex> guard(dhtnet::fileutils::getFileLock(preferencesValuesFilePath));
     std::ifstream file(preferencesValuesFilePath, std::ios::binary);
     std::map<std::string, std::string> rmap;
 
@@ -240,7 +240,7 @@ PluginPreferencesUtils::resetPreferencesValuesMap(const std::string& rootPath,
     std::map<std::string, std::string> pluginPreferencesMap {};
 
     const std::string preferencesValuesFilePath = valuesFilePath(rootPath, accountId);
-    std::lock_guard<std::mutex> guard(fileutils::getFileLock(preferencesValuesFilePath));
+    std::lock_guard<std::mutex> guard(dhtnet::fileutils::getFileLock(preferencesValuesFilePath));
     std::ofstream fs(preferencesValuesFilePath, std::ios::binary);
     if (!fs.good()) {
         return false;
@@ -259,7 +259,7 @@ void
 PluginPreferencesUtils::setAllowDenyListPreferences(const ChatHandlerList& list)
 {
     std::string filePath = getAllowDenyListsPath();
-    std::lock_guard<std::mutex> guard(fileutils::getFileLock(filePath));
+    std::lock_guard<std::mutex> guard(dhtnet::fileutils::getFileLock(filePath));
     std::ofstream fs(filePath, std::ios::binary);
     if (!fs.good()) {
         return;
@@ -275,7 +275,7 @@ void
 PluginPreferencesUtils::getAllowDenyListPreferences(ChatHandlerList& list)
 {
     const std::string filePath = getAllowDenyListsPath();
-    std::lock_guard<std::mutex> guard(fileutils::getFileLock(filePath));
+    std::lock_guard<std::mutex> guard(dhtnet::fileutils::getFileLock(filePath));
     std::ifstream file(filePath, std::ios::binary);
 
     // If file is accessible
@@ -312,7 +312,7 @@ PluginPreferencesUtils::addAlwaysHandlerPreference(const std::string& handlerNam
         std::string filePath = getPreferencesConfigFilePath(rootPath);
         Json::Value root;
 
-        std::lock_guard<std::mutex> guard(fileutils::getFileLock(filePath));
+        std::lock_guard<std::mutex> guard(dhtnet::fileutils::getFileLock(filePath));
         std::ifstream file(filePath);
         Json::CharReaderBuilder rbuilder;
         Json::Value preference;
@@ -332,7 +332,7 @@ PluginPreferencesUtils::addAlwaysHandlerPreference(const std::string& handlerNam
     std::string filePath = getPreferencesConfigFilePath(rootPath, "acc");
     Json::Value root;
     {
-        std::lock_guard<std::mutex> guard(fileutils::getFileLock(filePath));
+        std::lock_guard<std::mutex> guard(dhtnet::fileutils::getFileLock(filePath));
         std::ifstream file(filePath);
         Json::CharReaderBuilder rbuilder;
         Json::Value preference;
@@ -356,7 +356,7 @@ PluginPreferencesUtils::addAlwaysHandlerPreference(const std::string& handlerNam
         preference["scope"] = "accountId";
         root.append(preference);
     }
-    std::lock_guard<std::mutex> guard(fileutils::getFileLock(filePath));
+    std::lock_guard<std::mutex> guard(dhtnet::fileutils::getFileLock(filePath));
     std::ofstream outFile(filePath);
     if (outFile) {
         // Save preference.json file with new "always preference"
diff --git a/src/plugin/pluginsutils.cpp b/src/plugin/pluginsutils.cpp
index 9ab00890f679c89c51dd54d68393876d17ebc2b7..707eb01d6904fe135a093ff2d99f61151150bdf7 100644
--- a/src/plugin/pluginsutils.cpp
+++ b/src/plugin/pluginsutils.cpp
@@ -155,7 +155,7 @@ checkManifestValidity(const std::vector<uint8_t>& vec)
 std::map<std::string, std::string>
 parseManifestFile(const std::string& manifestFilePath, const std::string& rootPath)
 {
-    std::lock_guard<std::mutex> guard(fileutils::getFileLock(manifestFilePath));
+    std::lock_guard<std::mutex> guard(dhtnet::fileutils::getFileLock(manifestFilePath));
     std::ifstream file(manifestFilePath);
     if (file) {
         try {
@@ -350,7 +350,7 @@ getLocales(const std::string& rootPath, const std::string& lang)
 std::map<std::string, std::string>
 processLocaleFile(const std::string& preferenceLocaleFilePath)
 {
-    if (!fileutils::isFile(preferenceLocaleFilePath)) {
+    if (!std::filesystem::is_regular_file(preferenceLocaleFilePath)) {
         return {};
     }
     std::ifstream file(preferenceLocaleFilePath);
diff --git a/src/sip/sipaccountbase.cpp b/src/sip/sipaccountbase.cpp
index 651bfde4ecb28e5680bc62ae0d7d4fb112acb959..8a518862d1891c30b5d7740a6b638fe19289fe12 100644
--- a/src/sip/sipaccountbase.cpp
+++ b/src/sip/sipaccountbase.cpp
@@ -130,7 +130,7 @@ SIPAccountBase::flush()
 {
     // Class base method
     Account::flush();
-    fileutils::remove(fileutils::get_cache_dir() + DIR_SEPARATOR_STR + getAccountID()
+    dhtnet::fileutils::remove(fileutils::get_cache_dir() + DIR_SEPARATOR_STR + getAccountID()
                       + DIR_SEPARATOR_STR "messages");
 }
 
diff --git a/test/unitTest/account_archive/migration.cpp b/test/unitTest/account_archive/migration.cpp
index e01bcb107b0d414431b60e334c52ea8a8ad72e73..7591341aa3ecdc6d27491342c3d4083d34955e66 100644
--- a/test/unitTest/account_archive/migration.cpp
+++ b/test/unitTest/account_archive/migration.cpp
@@ -330,7 +330,7 @@ MigrationTest::testExpiredDeviceInSwarm()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     // Wait that alice sees Bob
     cv.wait_for(lk, 20s, [&]() { return messageAliceReceived == 1; });
 
@@ -348,7 +348,7 @@ MigrationTest::testExpiredDeviceInSwarm()
 
     // check that certificate in conversation is expired
     auto devicePath = fmt::format("{}/devices/{}.crt", repoPath, aliceAccount->currentDeviceId());
-    CPPUNIT_ASSERT(fileutils::isFile(devicePath));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(devicePath));
     auto cert = dht::crypto::Certificate(fileutils::loadFile(devicePath));
     now = std::chrono::system_clock::now();
     CPPUNIT_ASSERT(cert.getExpiration() < now);
@@ -362,7 +362,7 @@ MigrationTest::testExpiredDeviceInSwarm()
     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]() { return messageAliceReceived == 1; }));
 
     // check that certificate in conversation is updated
-    CPPUNIT_ASSERT(fileutils::isFile(devicePath));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(devicePath));
     cert = dht::crypto::Certificate(fileutils::loadFile(devicePath));
     now = std::chrono::system_clock::now();
     CPPUNIT_ASSERT(cert.getExpiration() > now);
diff --git a/test/unitTest/call/recorder.cpp b/test/unitTest/call/recorder.cpp
index a101c68f85551b1a154c9cdb3de0b28a7766384f..05042c5e27e09ddca710781f3e9f787cc979500a 100644
--- a/test/unitTest/call/recorder.cpp
+++ b/test/unitTest/call/recorder.cpp
@@ -111,8 +111,8 @@ RecorderTest::setUp()
 {
     // Generate a temporary directory with a file inside
     recordDir = "records";
-    fileutils::recursive_mkdir(recordDir.c_str());
-    CPPUNIT_ASSERT(fileutils::isDirectory(recordDir));
+    dhtnet::fileutils::recursive_mkdir(recordDir.c_str());
+    CPPUNIT_ASSERT(std::filesystem::is_directory(recordDir));
 
     auto actors = load_actors_and_wait_for_announcement("actors/alice-bob.yml");
     aliceId = actors["alice"];
@@ -126,7 +126,7 @@ void
 RecorderTest::tearDown()
 {
     libjami::setIsAlwaysRecording(false);
-    fileutils::removeAll(recordDir);
+    dhtnet::fileutils::removeAll(recordDir);
 
     wait_for_removal_of({aliceId, bobId});
 }
diff --git a/test/unitTest/conversation/conversation.cpp b/test/unitTest/conversation/conversation.cpp
index 8630f17ac5e7d3faf7e6bf9c41ce63356d69de09..92a37f12e714fd7b4548b3c9f69b080a8d77fb92 100644
--- a/test/unitTest/conversation/conversation.cpp
+++ b/test/unitTest/conversation/conversation.cpp
@@ -254,10 +254,10 @@ ConversationTest::testCreateConversation()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     // Check created files
     auto adminCrt = repoPath + DIR_SEPARATOR_STR + "admins" + DIR_SEPARATOR_STR + uri + ".crt";
-    CPPUNIT_ASSERT(fileutils::isFile(adminCrt));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(adminCrt));
     auto crt = std::ifstream(adminCrt);
     std::string adminCrtStr((std::istreambuf_iterator<char>(crt)), std::istreambuf_iterator<char>());
     auto cert = aliceAccount->identity().second;
@@ -266,7 +266,7 @@ ConversationTest::testCreateConversation()
     CPPUNIT_ASSERT(adminCrtStr == parentCert);
     auto deviceCrt = repoPath + DIR_SEPARATOR_STR + "devices" + DIR_SEPARATOR_STR + aliceDeviceId
                      + ".crt";
-    CPPUNIT_ASSERT(fileutils::isFile(deviceCrt));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(deviceCrt));
     crt = std::ifstream(deviceCrt);
     std::string deviceCrtStr((std::istreambuf_iterator<char>(crt)),
                              std::istreambuf_iterator<char>());
@@ -452,7 +452,7 @@ ConversationTest::testSendMessage()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     // Wait that alice sees Bob
     cv.wait_for(lk, 30s, [&]() { return messageAliceReceived == 2; });
 
@@ -528,7 +528,7 @@ ConversationTest::testSendMessageWithBadDisplayName()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     // Wait that alice sees Bob
     cv.wait_for(lk, 30s, [&]() { return messageAliceReceived == 2; });
 
@@ -786,7 +786,7 @@ ConversationTest::testMergeAfterMigration()
     auto repoPathCarla = fileutils::get_data_dir() + DIR_SEPARATOR_STR
                          + carlaAccount->getAccountID() + DIR_SEPARATOR_STR + "conversations";
     auto p = std::filesystem::path(repoPathCarla);
-    fileutils::recursive_mkdir(p.parent_path());
+    dhtnet::fileutils::recursive_mkdir(p.parent_path());
     std::filesystem::copy(repoPathAlice, repoPathCarla, std::filesystem::copy_options::recursive);
     auto ciPathAlice = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                        + DIR_SEPARATOR_STR + "convInfo";
@@ -801,11 +801,11 @@ ConversationTest::testMergeAfterMigration()
 
     std::filesystem::remove_all(repoPathAlice);
     p = std::filesystem::path(repoPathAlice);
-    fileutils::recursive_mkdir(p.parent_path());
+    dhtnet::fileutils::recursive_mkdir(p.parent_path());
     std::filesystem::copy(repoPathCarla, repoPathAlice, std::filesystem::copy_options::recursive);
 
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPathAlice));
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPathAlice + "/" + convId));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPathAlice));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPathAlice + "/" + convId));
 
     // Makes different heads
     carlaAccount->convModule()->loadConversations(); // necessary to load conversation
@@ -925,10 +925,10 @@ ConversationTest::testSendMessageToMultipleParticipants()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + carlaAccount->getAccountID()
                + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
 
     libjami::sendMessage(aliceId, convId, "hi"s, "");
     CPPUNIT_ASSERT(cv.wait_for(lk, 60s, [&]() {
@@ -985,7 +985,7 @@ ConversationTest::testPingPongMessages()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     messageBobReceived = 0;
     messageAliceReceived = 0;
     libjami::sendMessage(aliceId, convId, "ping"s, "");
@@ -1061,10 +1061,10 @@ ConversationTest::testIsComposing()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     // Check created files
     auto bobInvited = repoPath + DIR_SEPARATOR_STR + "invited" + DIR_SEPARATOR_STR + bobUri;
-    CPPUNIT_ASSERT(fileutils::isFile(bobInvited));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(bobInvited));
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
     memberMessageGenerated = false;
     libjami::acceptConversationRequest(bobId, convId);
@@ -1136,10 +1136,10 @@ ConversationTest::testMessageStatus()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     // Check created files
     auto bobInvited = repoPath + DIR_SEPARATOR_STR + "invited" + DIR_SEPARATOR_STR + bobUri;
-    CPPUNIT_ASSERT(fileutils::isFile(bobInvited));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(bobInvited));
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
     memberMessageGenerated = false;
     libjami::acceptConversationRequest(bobId, convId);
@@ -1215,10 +1215,10 @@ ConversationTest::testSetMessageDisplayed()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     // Check created files
     auto bobInvited = repoPath + DIR_SEPARATOR_STR + "invited" + DIR_SEPARATOR_STR + bobUri;
-    CPPUNIT_ASSERT(fileutils::isFile(bobInvited));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(bobInvited));
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
     memberMessageGenerated = false;
     libjami::acceptConversationRequest(bobId, convId);
@@ -1328,10 +1328,10 @@ ConversationTest::testSetMessageDisplayedTwice()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     // Check created files
     auto bobInvited = repoPath + DIR_SEPARATOR_STR + "invited" + DIR_SEPARATOR_STR + bobUri;
-    CPPUNIT_ASSERT(fileutils::isFile(bobInvited));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(bobInvited));
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
     memberMessageGenerated = false;
     libjami::acceptConversationRequest(bobId, convId);
@@ -1590,7 +1590,7 @@ ConversationTest::createFakeConversation(std::shared_ptr<JamiAccount> account,
     std::string devicesPath = repoPath + "devices";
     std::string crlsPath = repoPath + "CRLs" + DIR_SEPARATOR_STR + deviceId;
 
-    if (!fileutils::recursive_mkdir(adminsPath, 0700)) {
+    if (!dhtnet::fileutils::recursive_mkdir(adminsPath, 0700)) {
         JAMI_ERR("Error when creating %s. Abort create conversations", adminsPath.c_str());
     }
 
@@ -1611,7 +1611,7 @@ ConversationTest::createFakeConversation(std::shared_ptr<JamiAccount> account,
     file << parentCert->toString(true);
     file.close();
 
-    if (!fileutils::recursive_mkdir(devicesPath, 0700)) {
+    if (!dhtnet::fileutils::recursive_mkdir(devicesPath, 0700)) {
         JAMI_ERR("Error when creating %s. Abort create conversations", devicesPath.c_str());
     }
 
@@ -1624,7 +1624,7 @@ ConversationTest::createFakeConversation(std::shared_ptr<JamiAccount> account,
     file << (fakeCert.empty() ? deviceCert : fakeCert);
     file.close();
 
-    if (!fileutils::recursive_mkdir(crlsPath, 0700)) {
+    if (!dhtnet::fileutils::recursive_mkdir(crlsPath, 0700)) {
         JAMI_ERR("Error when creating %s. Abort create conversations", crlsPath.c_str());
     }
 
@@ -2828,7 +2828,7 @@ ConversationTest::testDoNotLoadIncorrectConversation()
     auto repoGitPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                        + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId
                        + DIR_SEPARATOR_STR + ".git";
-    fileutils::removeAll(repoGitPath, true); // This make the repository not usable
+    dhtnet::fileutils::removeAll(repoGitPath, true); // This make the repository not usable
 
     aliceAccount->convModule()
         ->loadConversations(); // Refresh. This should detect the incorrect conversations.
@@ -3164,7 +3164,7 @@ END:VCARD";
     auto vCardPath = fmt::format("{}/{}/profile.vcf", fileutils::get_data_dir(), aliceId);
     // Add file
     auto p = std::filesystem::path(vCardPath);
-    fileutils::recursive_mkdir(p.parent_path());
+    dhtnet::fileutils::recursive_mkdir(p.parent_path());
     std::ofstream file(p);
     if (file.is_open()) {
         file << vcard;
@@ -3462,7 +3462,7 @@ ConversationTest::testSendReply()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     // Wait that alice sees Bob
     cv.wait_for(lk, 30s, [&]() { return messageAliceReceived.size() == 2; });
 
@@ -3881,7 +3881,7 @@ ConversationTest::testRemoveOneToOneNotInDetails()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + secondConv;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
 
     aliceAccount->convModule()->loadConversations();
 
@@ -4082,9 +4082,9 @@ ConversationTest::testLoadPartiallyRemovedConversation()
     std::filesystem::remove_all(fmt::format("./{}", convId));
 
     // Reloading conversation should remove directory
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPathAlice));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPathAlice));
     aliceAccount->convModule()->loadConversations();
-    CPPUNIT_ASSERT(!fileutils::isDirectory(repoPathAlice));
+    CPPUNIT_ASSERT(!std::filesystem::is_directory(repoPathAlice));
 }
 
 } // namespace test
diff --git a/test/unitTest/conversation/conversationMembersEvent.cpp b/test/unitTest/conversation/conversationMembersEvent.cpp
index ca636280815397d52809f4d60ec925932e487c31..ed57a95562803c654d4e56e10eaabfa2e01e3441 100644
--- a/test/unitTest/conversation/conversationMembersEvent.cpp
+++ b/test/unitTest/conversation/conversationMembersEvent.cpp
@@ -242,8 +242,8 @@ ConversationMembersEventTest::testRemoveConversationNoMember()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
     auto dataPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversation_data" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
-    CPPUNIT_ASSERT(fileutils::isDirectory(dataPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(dataPath));
 
     auto conversations = libjami::getConversations(aliceId);
     CPPUNIT_ASSERT(conversations.size() == 1);
@@ -251,8 +251,8 @@ ConversationMembersEventTest::testRemoveConversationNoMember()
     CPPUNIT_ASSERT(libjami::removeConversation(aliceId, convId));
     conversations = libjami::getConversations(aliceId);
     CPPUNIT_ASSERT(conversations.size() == 0);
-    CPPUNIT_ASSERT(!fileutils::isDirectory(repoPath));
-    CPPUNIT_ASSERT(!fileutils::isDirectory(dataPath));
+    CPPUNIT_ASSERT(!std::filesystem::is_directory(repoPath));
+    CPPUNIT_ASSERT(!std::filesystem::is_directory(dataPath));
 }
 
 void
@@ -305,10 +305,10 @@ ConversationMembersEventTest::testRemoveConversationWithMember()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     // Check created files
     auto bobInvitedFile = repoPath + DIR_SEPARATOR_STR + "invited" + DIR_SEPARATOR_STR + bobUri;
-    CPPUNIT_ASSERT(fileutils::isFile(bobInvitedFile));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(bobInvitedFile));
 
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
     memberMessageGenerated = false;
@@ -316,9 +316,9 @@ ConversationMembersEventTest::testRemoveConversationWithMember()
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return conversationReady; }));
     auto clonedPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID()
                       + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(clonedPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(clonedPath));
     bobInvitedFile = clonedPath + DIR_SEPARATOR_STR + "invited" + DIR_SEPARATOR_STR + bobUri;
-    CPPUNIT_ASSERT(!fileutils::isFile(bobInvitedFile));
+    CPPUNIT_ASSERT(!std::filesystem::is_regular_file(bobInvitedFile));
     // Remove conversation from alice once member confirmed
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return memberMessageGenerated; }));
 
@@ -326,7 +326,7 @@ ConversationMembersEventTest::testRemoveConversationWithMember()
     libjami::removeConversation(aliceId, convId);
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return bobSeeAliceRemoved; }));
     std::this_thread::sleep_for(3s);
-    CPPUNIT_ASSERT(!fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(!std::filesystem::is_directory(repoPath));
 }
 
 void
@@ -368,21 +368,21 @@ ConversationMembersEventTest::testAddMember()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     // Check created files
     auto bobInvited = repoPath + DIR_SEPARATOR_STR + "invited" + DIR_SEPARATOR_STR + bobUri;
-    CPPUNIT_ASSERT(fileutils::isFile(bobInvited));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(bobInvited));
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
     libjami::acceptConversationRequest(bobId, convId);
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return conversationReady; }));
     auto clonedPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID()
                       + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(clonedPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(clonedPath));
     bobInvited = clonedPath + DIR_SEPARATOR_STR + "invited" + DIR_SEPARATOR_STR + bobUri;
-    CPPUNIT_ASSERT(!fileutils::isFile(bobInvited));
+    CPPUNIT_ASSERT(!std::filesystem::is_regular_file(bobInvited));
     auto bobMember = clonedPath + DIR_SEPARATOR_STR + "members" + DIR_SEPARATOR_STR + bobUri
                      + ".crt";
-    CPPUNIT_ASSERT(fileutils::isFile(bobMember));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(bobMember));
 }
 
 void
@@ -472,7 +472,7 @@ ConversationMembersEventTest::testAddOfflineMemberThenConnects()
     cv.wait_for(lk, 30s, [&]() { return conversationReady; });
     auto clonedPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + carlaAccount->getAccountID()
                       + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(clonedPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(clonedPath));
     libjami::unregisterSignalHandlers();
 }
 
@@ -522,7 +522,7 @@ ConversationMembersEventTest::testGetMembers()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
 
     auto members = libjami::getConversationMembers(aliceId, convId);
     CPPUNIT_ASSERT(members.size() == 2);
@@ -1450,7 +1450,7 @@ ConversationMembersEventTest::testCommitUnauthorizedUser()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     // Wait that alice sees Bob
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return messageAliceReceived == 2; }));
 
@@ -1547,13 +1547,13 @@ ConversationMembersEventTest::testMemberJoinsNoBadFile()
     std::string devicesPath = fmt::format("{}/{}/devices/", repoPathCarla, convId);
     std::string memberFile = fmt::format("{}{}.crt", membersPath, carlaUri);
     // Add members/uri.crt
-    fileutils::recursive_mkdir(membersPath, 0700);
-    fileutils::recursive_mkdir(devicesPath, 0700);
+    dhtnet::fileutils::recursive_mkdir(membersPath, 0700);
+    dhtnet::fileutils::recursive_mkdir(devicesPath, 0700);
     auto file = fileutils::ofstream(memberFile, std::ios::trunc | std::ios::binary);
     file << parentCert->toString(true);
     file.close();
     std::string invitedPath = fmt::format("{}/{}/invited/{}", repoPathCarla, convId, carlaUri);
-    fileutils::remove(invitedPath);
+    dhtnet::fileutils::remove(invitedPath);
     std::string devicePath = fmt::format("{}{}.crt", devicesPath, carlaAccount->currentDeviceId());
     file = fileutils::ofstream(devicePath, std::ios::trunc | std::ios::binary);
     file << cert->toString(false);
@@ -1641,7 +1641,7 @@ ConversationMembersEventTest::testMemberAddedNoCertificate()
 
     // Remove invite but do not add member certificate
     std::string invitedPath = repoPathCarla + "invited";
-    fileutils::remove(fileutils::getFullPath(invitedPath, carlaUri));
+    dhtnet::fileutils::remove(fileutils::getFullPath(invitedPath, carlaUri));
 
     Json::Value json;
     json["action"] = "join";
@@ -1740,8 +1740,8 @@ ConversationMembersEventTest::testMemberJoinsInviteRemoved()
     std::string devicesPath = fmt::format("{}/{}/devices/", repoPathCarla, convId);
     std::string memberFile = fmt::format("{}{}.crt", membersPath, carlaUri);
     // Add members/uri.crt
-    fileutils::recursive_mkdir(membersPath, 0700);
-    fileutils::recursive_mkdir(devicesPath, 0700);
+    dhtnet::fileutils::recursive_mkdir(membersPath, 0700);
+    dhtnet::fileutils::recursive_mkdir(devicesPath, 0700);
     auto file = fileutils::ofstream(memberFile, std::ios::trunc | std::ios::binary);
     file << parentCert->toString(true);
     file.close();
@@ -1930,21 +1930,21 @@ ConversationMembersEventTest::testConversationMemberEvent()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     // Check created files
     auto bobInvited = repoPath + DIR_SEPARATOR_STR + "invited" + DIR_SEPARATOR_STR + bobUri;
-    CPPUNIT_ASSERT(fileutils::isFile(bobInvited));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(bobInvited));
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
     libjami::acceptConversationRequest(bobId, convId);
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return conversationReady; }));
     auto clonedPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID()
                       + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(clonedPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(clonedPath));
     bobInvited = clonedPath + DIR_SEPARATOR_STR + "invited" + DIR_SEPARATOR_STR + bobUri;
-    CPPUNIT_ASSERT(!fileutils::isFile(bobInvited));
+    CPPUNIT_ASSERT(!std::filesystem::is_regular_file(bobInvited));
     auto bobMember = clonedPath + DIR_SEPARATOR_STR + "members" + DIR_SEPARATOR_STR + bobUri
                      + ".crt";
-    CPPUNIT_ASSERT(fileutils::isFile(bobMember));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(bobMember));
 }
 
 void
diff --git a/test/unitTest/conversation/conversationRequest.cpp b/test/unitTest/conversation/conversationRequest.cpp
index 09b7fee5806bd3ef40b4f3efdd65bfcc78620169..c653deb955954dcb5e01b0d8ee585376fb0d1305 100644
--- a/test/unitTest/conversation/conversationRequest.cpp
+++ b/test/unitTest/conversation/conversationRequest.cpp
@@ -355,17 +355,17 @@ ConversationRequestTest::testAddContact()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
     CPPUNIT_ASSERT(bobAccount->acceptTrustRequest(aliceUri));
     CPPUNIT_ASSERT(
         cv.wait_for(lk, 30s, [&]() { return conversationReady && memberMessageGenerated; }));
     auto clonedPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID()
                       + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(clonedPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(clonedPath));
     auto bobMember = clonedPath + DIR_SEPARATOR_STR + "members" + DIR_SEPARATOR_STR + bobUri
                      + ".crt";
-    CPPUNIT_ASSERT(fileutils::isFile(bobMember));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(bobMember));
 }
 
 void
@@ -711,11 +711,11 @@ ConversationRequestTest::testRemoveContact()
 
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(!fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(!std::filesystem::is_directory(repoPath));
 
     repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID()
                + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(!fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(!std::filesystem::is_directory(repoPath));
 }
 
 void
@@ -853,7 +853,7 @@ ConversationRequestTest::testRemoveSelfDoesntRemoveConversation()
     CPPUNIT_ASSERT(!cv.wait_for(lk, 10s, [&]() { return conversationRemoved; }));
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
 }
 
 void
@@ -982,7 +982,7 @@ ConversationRequestTest::testBanContact()
     CPPUNIT_ASSERT(!cv.wait_for(lk, 30s, [&]() { return memberMessageGenerated; }));
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
 }
 
 void
@@ -1335,13 +1335,13 @@ ConversationRequestTest::testCacheRequestFromClient()
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return requestReceived; }));
     auto cachedPath = fileutils::get_cache_dir() + DIR_SEPARATOR_CH + aliceAccount->getAccountID()
                       + DIR_SEPARATOR_CH + "requests" + DIR_SEPARATOR_CH + bobUri;
-    CPPUNIT_ASSERT(fileutils::isFile(cachedPath));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(cachedPath));
     CPPUNIT_ASSERT(fileutils::loadFile(cachedPath) == payload);
 
     CPPUNIT_ASSERT(bobAccount->getTrustRequests().size() == 1);
     libjami::acceptConversationRequest(bobId, convId);
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return conversationReady; }));
-    CPPUNIT_ASSERT(!fileutils::isFile(cachedPath));
+    CPPUNIT_ASSERT(!std::filesystem::is_regular_file(cachedPath));
 }
 
 void
diff --git a/test/unitTest/conversation/conversationcommon.cpp b/test/unitTest/conversation/conversationcommon.cpp
index d9d030a093dcd22801b559657a7b774e81598bd6..43cba71066263d32770ca6e1a2bbc6542213f88e 100644
--- a/test/unitTest/conversation/conversationcommon.cpp
+++ b/test/unitTest/conversation/conversationcommon.cpp
@@ -55,7 +55,7 @@ addVote(std::shared_ptr<JamiAccount> account,
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
     auto voteDirectory = repoPath + DIR_SEPARATOR_STR + "votes" + DIR_SEPARATOR_STR + "members";
     auto voteFile = voteDirectory + DIR_SEPARATOR_STR + votedUri;
-    if (!fileutils::recursive_mkdir(voteDirectory, 0700)) {
+    if (!dhtnet::fileutils::recursive_mkdir(voteDirectory, 0700)) {
         return;
     }
 
@@ -130,7 +130,7 @@ addFile(std::shared_ptr<JamiAccount> account,
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
     // Add file
     auto p = std::filesystem::path(fileutils::getFullPath(repoPath, relativePath));
-    fileutils::recursive_mkdir(p.parent_path());
+    dhtnet::fileutils::recursive_mkdir(p.parent_path());
     std::ofstream file(p);
     if (file.is_open()) {
         file << content;
diff --git a/test/unitTest/conversationRepository/conversationRepository.cpp b/test/unitTest/conversationRepository/conversationRepository.cpp
index dd846e200ceabd52d9a63f902393debc0927d7e9..4ce5a60c896157a959e8253f56df95b5bbded463 100644
--- a/test/unitTest/conversationRepository/conversationRepository.cpp
+++ b/test/unitTest/conversationRepository/conversationRepository.cpp
@@ -127,7 +127,7 @@ ConversationRepositoryTest::testCreateRepository()
     CPPUNIT_ASSERT(repository != nullptr);
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + repository->id();
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
 
     // Assert that first commit is signed by alice
     git_repository* repo;
@@ -148,10 +148,10 @@ ConversationRepositoryTest::testCreateRepository()
     // 2. Check created files
     auto CRLsPath = repoPath + DIR_SEPARATOR_STR + "CRLs" + DIR_SEPARATOR_STR
                     + aliceDeviceId.toString();
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
 
     auto adminCrt = repoPath + DIR_SEPARATOR_STR + "admins" + DIR_SEPARATOR_STR + uri + ".crt";
-    CPPUNIT_ASSERT(fileutils::isFile(adminCrt));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(adminCrt));
 
     auto crt = std::ifstream(adminCrt);
     std::string adminCrtStr((std::istreambuf_iterator<char>(crt)), std::istreambuf_iterator<char>());
@@ -164,7 +164,7 @@ ConversationRepositoryTest::testCreateRepository()
 
     auto deviceCrt = repoPath + DIR_SEPARATOR_STR + "devices" + DIR_SEPARATOR_STR
                      + aliceDeviceId.toString() + ".crt";
-    CPPUNIT_ASSERT(fileutils::isFile(deviceCrt));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(deviceCrt));
 
     crt = std::ifstream(deviceCrt);
     std::string deviceCrtStr((std::istreambuf_iterator<char>(crt)),
@@ -364,7 +364,7 @@ ConversationRepositoryTest::testMerge()
     CPPUNIT_ASSERT(repository != nullptr);
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + repository->id();
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
 
     // Assert that first commit is signed by alice
     git_repository* repo;
@@ -399,7 +399,7 @@ ConversationRepositoryTest::testFFMerge()
     CPPUNIT_ASSERT(repository != nullptr);
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + repository->id();
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
 
     // Assert that first commit is signed by alice
     git_repository* repo;
@@ -455,7 +455,7 @@ ConversationRepositoryTest::testMergeProfileWithConflict()
     CPPUNIT_ASSERT(repository != nullptr);
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + aliceAccount->getAccountID()
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + repository->id();
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
 
     // Assert that first commit is signed by alice
     git_repository* repo;
diff --git a/test/unitTest/fileTransfer/fileTransfer.cpp b/test/unitTest/fileTransfer/fileTransfer.cpp
index 236631bfd9b251f863abf5c4db2ff57f96f7a023..4d36846ad7b556f20d950fa2bf25e4a084359220 100644
--- a/test/unitTest/fileTransfer/fileTransfer.cpp
+++ b/test/unitTest/fileTransfer/fileTransfer.cpp
@@ -736,12 +736,12 @@ FileTransferTest::testAskToMultipleParticipants()
     transferCFinished = false;
     libjami::downloadFile(carlaId, convId, iidCarla, carlaTid, recv2Path);
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return transferCFinished; }));
-    CPPUNIT_ASSERT(fileutils::isFile(recv2Path));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(recv2Path));
 
     transferBFinished = false;
     libjami::downloadFile(bobId, convId, iidBob, bobTid, recvPath);
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return transferBFinished; }));
-    CPPUNIT_ASSERT(fileutils::isFile(recvPath));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(recvPath));
 
     libjami::unregisterSignalHandlers();
 }
@@ -833,7 +833,7 @@ FileTransferTest::testCancelInTransfer()
     transferBCancelled = false;
     libjami::cancelDataTransfer(bobId, convId, tidBob);
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() { return transferBCancelled; }));
-    CPPUNIT_ASSERT(!fileutils::isFile(recvPath));
+    CPPUNIT_ASSERT(!std::filesystem::is_regular_file(recvPath));
     CPPUNIT_ASSERT(!bobAccount->dataTransfer(convId)->isWaiting(tidBob));
 
     libjami::unregisterSignalHandlers();
@@ -922,7 +922,7 @@ FileTransferTest::testTransferInfo()
     CPPUNIT_ASSERT(libjami::fileTransferInfo(bobId, convId, tidBob, path, totalSize, bytesProgress)
                    == libjami::DataTransferError::invalid_argument);
     CPPUNIT_ASSERT(bytesProgress == 0);
-    CPPUNIT_ASSERT(!fileutils::isFile(path));
+    CPPUNIT_ASSERT(!std::filesystem::is_regular_file(path));
     // No check for total as not started
 
     transferAFinished = false;
@@ -934,7 +934,7 @@ FileTransferTest::testTransferInfo()
 
     CPPUNIT_ASSERT(bytesProgress == 64000);
     CPPUNIT_ASSERT(totalSize == 64000);
-    CPPUNIT_ASSERT(fileutils::isFile(path));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(path));
 
     libjami::unregisterSignalHandlers();
     std::this_thread::sleep_for(5s);
@@ -1080,7 +1080,7 @@ FileTransferTest::testTooLarge()
     libjami::downloadFile(bobId, convId, iidBob, tidBob, recvPath);
 
     CPPUNIT_ASSERT(cv.wait_for(lk, 20s, [&]() { return cancelled; }));
-    CPPUNIT_ASSERT(!fileutils::isFile(recvPath));
+    CPPUNIT_ASSERT(!std::filesystem::is_regular_file(recvPath));
 
     libjami::unregisterSignalHandlers();
 }
diff --git a/test/unitTest/fileutils/testFileutils.cpp b/test/unitTest/fileutils/testFileutils.cpp
index c2b5129d71961f558bbfcbc0177a1a9f0620adbf..c0d622c78a145bb4f2a5287e4988b134b8346067 100644
--- a/test/unitTest/fileutils/testFileutils.cpp
+++ b/test/unitTest/fileutils/testFileutils.cpp
@@ -93,42 +93,13 @@ FileutilsTest::tearDown()
     rmdir(TEST_PATH.c_str());
 }
 
-void
-FileutilsTest::testCheckDir()
-{
-    // check existed directory
-    CPPUNIT_ASSERT(check_dir(TEST_PATH.c_str()));
-    CPPUNIT_ASSERT(isDirectory(TEST_PATH.c_str()));
-    // check non-existent directory
-    CPPUNIT_ASSERT(!isDirectory(NON_EXISTANT_PATH));
-    CPPUNIT_ASSERT(check_dir(NON_EXISTANT_PATH.c_str()));
-    CPPUNIT_ASSERT(isDirectory(NON_EXISTANT_PATH));
-    CPPUNIT_ASSERT(removeAll(NON_EXISTANT_PATH_BASE) == 0);
-    CPPUNIT_ASSERT(!isDirectory(NON_EXISTANT_PATH_BASE));
-    //remove an non existent directory
-    CPPUNIT_ASSERT(removeAll(NON_EXISTANT_PATH_BASE) == -1);
-}
-
 void
 FileutilsTest::testPath()
 {
     CPPUNIT_ASSERT(isPathRelative("relativePath"));
-    CPPUNIT_ASSERT(isFile(EXISTANT_FILE));
-    CPPUNIT_ASSERT(!isDirectory(EXISTANT_FILE));
-    CPPUNIT_ASSERT(isDirectory(TEST_PATH));
-}
-
-void
-FileutilsTest::testReadDirectory()
-{
-    CPPUNIT_ASSERT(recursive_mkdir(TEST_PATH + DIR_SEPARATOR_STR + "readDirectory" + DIR_SEPARATOR_STR + "test1"));
-    CPPUNIT_ASSERT(recursive_mkdir(TEST_PATH + DIR_SEPARATOR_STR + "readDirectory" + DIR_SEPARATOR_STR + "test2"));
-    auto dirs = readDirectory(TEST_PATH + DIR_SEPARATOR_STR + "readDirectory");
-    CPPUNIT_ASSERT(dirs.size() == 2);
-    CPPUNIT_ASSERT(
-        (dirs.at(0).compare("test1") == 0 && dirs.at(1).compare("test2") == 0)
-        || (dirs.at(1).compare("test1") == 0 && dirs.at(0).compare("test2") == 0));
-    CPPUNIT_ASSERT(removeAll(TEST_PATH + DIR_SEPARATOR_STR + "readDirectory") == 0);
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(EXISTANT_FILE));
+    CPPUNIT_ASSERT(!std::filesystem::is_directory(EXISTANT_FILE));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(TEST_PATH));
 }
 
 void
@@ -145,13 +116,13 @@ FileutilsTest::testLoadFile()
 void
 FileutilsTest::testIsDirectoryWritable()
 {
-    CPPUNIT_ASSERT(recursive_mkdir(NON_EXISTANT_PATH_BASE));
+    CPPUNIT_ASSERT(dhtnet::fileutils::recursive_mkdir(NON_EXISTANT_PATH_BASE));
     CPPUNIT_ASSERT(isDirectoryWritable(NON_EXISTANT_PATH_BASE));
-    CPPUNIT_ASSERT(removeAll(NON_EXISTANT_PATH_BASE) == 0);
+    CPPUNIT_ASSERT(dhtnet::fileutils::removeAll(NON_EXISTANT_PATH_BASE) == 0);
     // Create directory with permission: read by owner
-    CPPUNIT_ASSERT(recursive_mkdir(NON_EXISTANT_PATH_BASE, 0400));
+    CPPUNIT_ASSERT(dhtnet::fileutils::recursive_mkdir(NON_EXISTANT_PATH_BASE, 0400));
     CPPUNIT_ASSERT(!isDirectoryWritable(NON_EXISTANT_PATH_BASE));
-    CPPUNIT_ASSERT(removeAll(NON_EXISTANT_PATH_BASE) == 0);
+    CPPUNIT_ASSERT(dhtnet::fileutils::removeAll(NON_EXISTANT_PATH_BASE) == 0);
 }
 
 void
@@ -179,11 +150,11 @@ FileutilsTest::testFullPath()
 void
 FileutilsTest::testCopy()
 {
-    CPPUNIT_ASSERT(isFile(EXISTANT_FILE));
-    CPPUNIT_ASSERT(!isFile(NON_EXISTANT_PATH_BASE));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(EXISTANT_FILE));
+    CPPUNIT_ASSERT(!std::filesystem::is_regular_file(NON_EXISTANT_PATH_BASE));
     CPPUNIT_ASSERT(copy(EXISTANT_FILE, NON_EXISTANT_PATH_BASE));
-    CPPUNIT_ASSERT(isFile(NON_EXISTANT_PATH_BASE));
-    CPPUNIT_ASSERT(removeAll(NON_EXISTANT_PATH_BASE) == 0);
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(NON_EXISTANT_PATH_BASE));
+    CPPUNIT_ASSERT(dhtnet::fileutils::removeAll(NON_EXISTANT_PATH_BASE) == 0);
 }
 
 }}} // namespace jami::test::fileutils
diff --git a/test/unitTest/media/test_media_decoder.cpp b/test/unitTest/media/test_media_decoder.cpp
index 24a238bdc40fcf795a7edb942bb11f70a8c5b05b..1904035bafde8da2c2764f13caf8a1f87d5fb8c2 100644
--- a/test/unitTest/media/test_media_decoder.cpp
+++ b/test/unitTest/media/test_media_decoder.cpp
@@ -66,7 +66,7 @@ MediaDecoderTest::setUp()
 void
 MediaDecoderTest::tearDown()
 {
-    fileutils::remove(filename_);
+    dhtnet::fileutils::remove(filename_);
     libjami::fini();
 }
 
diff --git a/test/unitTest/media/test_media_encoder.cpp b/test/unitTest/media/test_media_encoder.cpp
index 8438db576140dc7c40f265100e48f8c2acb6506e..fae0ea03cfd4fbe661181d703822b63ab10e22dd 100644
--- a/test/unitTest/media/test_media_encoder.cpp
+++ b/test/unitTest/media/test_media_encoder.cpp
@@ -67,7 +67,7 @@ MediaEncoderTest::tearDown()
 {
     // clean up behind ourselves
     for (const auto& file : files_)
-        fileutils::remove(file);
+        dhtnet::fileutils::remove(file);
     libjami::fini();
 }
 
diff --git a/test/unitTest/plugins/plugins.cpp b/test/unitTest/plugins/plugins.cpp
index 8ccf47b448b53b7a1d9bca16c0a62e0e2249f69e..25ab6d9941dd8377d99bd131d6e216a6833bf245 100644
--- a/test/unitTest/plugins/plugins.cpp
+++ b/test/unitTest/plugins/plugins.cpp
@@ -720,7 +720,7 @@ PluginsTest::testMessage()
     // Assert that repository exists
     auto repoPath = fileutils::get_data_dir() + DIR_SEPARATOR_STR + bobData.accountId_
                     + DIR_SEPARATOR_STR + "conversations" + DIR_SEPARATOR_STR + convId;
-    CPPUNIT_ASSERT(fileutils::isDirectory(repoPath));
+    CPPUNIT_ASSERT(std::filesystem::is_directory(repoPath));
     // Wait that alice sees Bob
     cv.wait_for(lk, 30s, [&]() { return messageAliceReceived == 2; });
 
diff --git a/test/unitTest/syncHistory/syncHistory.cpp b/test/unitTest/syncHistory/syncHistory.cpp
index b8b800e5d124e4286f6d647c3e0d6eae9e5c5ccf..21e3d9c78024bfecf3163e50f621a5855636dc07 100644
--- a/test/unitTest/syncHistory/syncHistory.cpp
+++ b/test/unitTest/syncHistory/syncHistory.cpp
@@ -952,14 +952,14 @@ END:VCARD";
                    + DIR_SEPARATOR_STR + "profile.vcf";
     // Save VCard
     auto p = std::filesystem::path(alicePath);
-    fileutils::recursive_mkdir(p.parent_path());
+    dhtnet::fileutils::recursive_mkdir(p.parent_path());
     std::ofstream aliceFile(alicePath);
     if (aliceFile.is_open()) {
         aliceFile << vcard;
         aliceFile.close();
     }
     p = std::filesystem::path(bobPath);
-    fileutils::recursive_mkdir(p.parent_path());
+    dhtnet::fileutils::recursive_mkdir(p.parent_path());
     std::ofstream bobFile(bobPath);
     if (bobFile.is_open()) {
         bobFile << vcard;
@@ -998,7 +998,7 @@ END:VCARD";
             if (accountId == aliceId && peerId == bobUri) {
                 bobProfileReceived = true;
                 auto p = std::filesystem::path(bobDest);
-                fileutils::recursive_mkdir(p.parent_path());
+                dhtnet::fileutils::recursive_mkdir(p.parent_path());
                 std::rename(path.c_str(), bobDest.c_str());
             } else if (accountId == bobId && peerId == aliceUri) {
                 aliceProfileReceived = true;
@@ -1018,7 +1018,7 @@ END:VCARD";
     CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]() {
         return conversationReady && bobProfileReceived && aliceProfileReceived;
     }));
-    CPPUNIT_ASSERT(fileutils::isFile(bobDest));
+    CPPUNIT_ASSERT(std::filesystem::is_regular_file(bobDest));
 
     // Now create alice2
     std::map<std::string, std::string> details = libjami::getAccountTemplate("RING");