diff --git a/pythonbindings/pyfluids-stubs/__init__.pyi b/pythonbindings/pyfluids-stubs/__init__.pyi
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/pythonbindings/pyfluids/py.typed b/pythonbindings/pyfluids/py.typed
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/pythonbindings/src/gpu/submodules/grid_generator.cpp b/pythonbindings/src/gpu/submodules/grid_generator.cpp
index 48e6ef68557ce7d5dbc5a8e5a601c2b9039de10c..d46938d081006daabec9bfa27cdc36db017a6bf9 100644
--- a/pythonbindings/src/gpu/submodules/grid_generator.cpp
+++ b/pythonbindings/src/gpu/submodules/grid_generator.cpp
@@ -41,11 +41,9 @@ namespace grid_generator
         .def_static("make", &TriangularMesh::make, py::return_value_policy::reference);
 
         py::class_<GridBuilder, std::shared_ptr<GridBuilder>>(gridGeneratorModule, "GridBuilder")
-        .def("get_number_of_grid_levels", &GridBuilder::getNumberOfGridLevels)
-        .def("get_grid", &GridBuilder::getGrid, py::arg("level"));
+        .def("get_number_of_grid_levels", &GridBuilder::getNumberOfGridLevels);
 
         py::class_<LevelGridBuilder, GridBuilder, std::shared_ptr<LevelGridBuilder>>(gridGeneratorModule, "LevelGridBuilder")
-        .def("get_grid", py::overload_cast<int, int>(&LevelGridBuilder::getGrid), py::arg("level"), py::arg("box"))
         .def("set_slip_boundary_condition", &LevelGridBuilder::setSlipBoundaryCondition, py::arg("side_type"), py::arg("normal_x"), py::arg("normal_y"), py::arg("normal_z"))
         .def("set_velocity_boundary_condition", &LevelGridBuilder::setVelocityBoundaryCondition, py::arg("side_type"), py::arg("vx"), py::arg("vy"), py::arg("vz"))
         .def("set_pressure_boundary_condition", &LevelGridBuilder::setPressureBoundaryCondition, py::arg("side_type"), py::arg("rho"))
diff --git a/setup.py b/setup.py
index 7c7a5580d02741a0f7a94df06aca1ec8832b2214..530431b3775970b5222bc87d32bfb407363f95d6 100644
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,6 @@
 import sys
 from pathlib import Path
+from typing import List
 
 import skbuild
 
@@ -24,11 +25,31 @@ or install via pip:
 package_name = "pyfluids"
 target = "python_bindings"
 src_dir = "pythonbindings"
+stub_package = package_name+"-stubs"
+
+stub_dir = Path(src_dir)/stub_package
+
+
+def add_subfiles(dir_path: Path, suffix: str, root_dir: Path) -> List[str]:
+    files = []
+    for f in dir_path.iterdir():
+        if f.is_dir():
+            files.extend(add_subfiles(f, suffix, root_dir))
+        if f.is_file():
+            if f.suffix != suffix:
+                continue
+            files.append(str(f.relative_to(root_dir)))
+    return files
+
+def add_directory(dir_path: Path, suffix: str):
+    return add_subfiles(dir_path, suffix, dir_path)
+
+stub_files = add_directory(stub_dir, ".pyi")
 
 # hack to get config-args for installation with pip>21
 cmake_args = []
-if("config_args" in locals()):
-    cmake_args.extend([f"{k}={v}" for k,v in locals()["config_args"].items()])
+if "config_args" in locals():
+    cmake_args.extend([f"{k}={v}" for k, v in locals()["config_args"].items()])
 
 cmake_args += [
         f"-DPython3_ROOT_DIR={Path(sys.prefix)}",
@@ -41,9 +62,11 @@ cmake_args += [
 
 skbuild.setup(
     name=package_name,
-    packages=[package_name, "pymuparser"],
+    packages=[package_name, "pymuparser", "pyfluids-stubs"],
     package_dir={"": src_dir},
-    cmake_args = cmake_args,
+    cmake_args=cmake_args,
     cmake_install_target=target,
+    package_data={  "pyfluids": ["py.typed"],
+                    "pyfluids-stubs": stub_files},
     include_package_data=True,
 )