diff --git a/CMakeLists.txt b/CMakeLists.txt
index 36700ea804660e98f190edf731aac678ad509d41..8bd01b18017cab6332097e3166a9c8647f48e342 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -64,5 +64,6 @@ target_link_libraries(
   pastis
   kokkos
   PastisUtils
+  PastisMesh
   PastisExperimental)
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index db8252e9645f511eb6f489052006426086f1833f..67787648a4c5e3eb711c7d744f377a75228f3ad4 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -12,7 +12,7 @@ include_directories(utils)
 include_directories(algebra)
 
 # Pastis mesh
-#add_subdirectory(mesh)
+add_subdirectory(mesh)
 include_directories(mesh)
 
 # Pastis mesh
diff --git a/src/main.cpp b/src/main.cpp
index dbf5164af581d42dbf88200a09b55900fca5fc3d..cd52860096e989d60bb046b5bced2e0ac7ba623f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -19,6 +19,8 @@
 #include <TinyVector.hpp>
 #include <TinyMatrix.hpp>
 
+#include <GmshReader.hpp>
+
 #include <CLI/CLI.hpp>
 #include <cassert>
 #include <limits>
@@ -27,12 +29,14 @@
 int main(int argc, char *argv[])
 {
   long unsigned number = 10;
-
+  std::string filename;
   {
     CLI::App app{"Pastis help"};
 
     app.add_option("number,-n,--number", number, "Number of cells");//->required();
 
+    app.add_option("filename,-f,--filename", filename, "gmsh file");//->required();
+
     int threads=-1;
     app.add_option("--threads", threads, "Number of Kokkos threads")->check(CLI::Range(1,std::numeric_limits<decltype(threads)>::max()));
 
@@ -116,7 +120,11 @@ int main(int argc, char *argv[])
   // }
 
 
-  { // class for acoustic solver test
+  if (filename != "") {
+    std::cout << "Reading (gmsh) " << rang::style::underline << filename << rang::style::reset << " ...\n";
+    GmshReader gmsh_reader(filename);
+  } else {
+    // class for acoustic solver test
     Kokkos::Timer timer;
     timer.reset();
     Connectivity1D connectivity(number);
diff --git a/src/mesh/CMakeLists.txt b/src/mesh/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f07bc30ba6e13173157a7ddc0b0664ea0920bf60
--- /dev/null
+++ b/src/mesh/CMakeLists.txt
@@ -0,0 +1,13 @@
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+# ------------------- Source files --------------------
+
+add_library(
+  PastisMesh
+  GmshReader.cpp)
+
+#include_directories(${PASTIS_SOURCE_DIR}/utils)
+
+# Additional dependencies
+#add_dependencies(PastisMesh)
diff --git a/src/mesh/GmshReader.cpp b/src/mesh/GmshReader.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9eaaea15fad8d0ea1f19b3a7f9bb037acbdb2eb3
--- /dev/null
+++ b/src/mesh/GmshReader.cpp
@@ -0,0 +1,13 @@
+#include <GmshReader.hpp>
+
+#include <iostream>
+#include <fstream>
+
+GmshReader::GmshReader(const std::string& filename)
+{
+  std::ifstream fin(filename);
+  if (not fin) {
+    std::cerr << "cannot read file '" << filename << "'\n";
+    std::exit(0);
+  }
+}
diff --git a/src/mesh/GmshReader.hpp b/src/mesh/GmshReader.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..eafacfeaceaf055f5344542165beec55f9473623
--- /dev/null
+++ b/src/mesh/GmshReader.hpp
@@ -0,0 +1,13 @@
+#ifndef GMSH_READER_HPP
+#define GMSH_READER_HPP
+
+#include <string>
+
+class GmshReader
+{
+public:
+  GmshReader(const std::string& filename);
+  ~GmshReader() = default;
+};
+
+#endif // GMSH_READER_HPP