diff --git a/liblava/app/app.cpp b/liblava/app/app.cpp
index f047d2ac349500d7167a9e163f2b101af14e71ea..eccf9d6b18028de53e6080229fd7fba911727285 100644
--- a/liblava/app/app.cpp
+++ b/liblava/app/app.cpp
@@ -13,7 +13,7 @@ app::app(frame_config config_)
     : frame(config_), window(config_.app) {}
 
 app::app(name config_app, argh::parser cmd_line)
-    : frame(frame_config(config_app, cmd_line, true)), window(config_app) {}
+    : frame(frame_config(config_app, cmd_line)), window(config_app) {}
 
 void to_json(json& j, window::state const& w) {
 
@@ -46,18 +46,16 @@ void from_json(json const& j, window::state& w) {
 
 bool has_window_file() {
 
-    std::ifstream i(_window_file_);
-    return i.is_open();
+    return file_system::exists(_window_file_);
 }
 
 bool load_window_file(window::state& state, string_ref index) {
 
-    std::ifstream i(_window_file_);
-    if (!i)
+    scope_data data;
+    if (!load_file_data(_window_file_, data))
         return false;
 
-    json j;
-    i >> j;
+    auto j = json::parse({ data.ptr, data.size });
 
     if (!j.count(str(index)))
         return false;
@@ -75,10 +73,10 @@ void save_window_file(window const& window) {
 
     json j;
 
-    std::ifstream i(_window_file_);
-    if (i) {
+    scope_data data;
+    if (load_file_data(_window_file_, data)) {
 
-        i >> j;
+        j = json::parse({ data.ptr, data.size });
 
         json d;
         d[index] = state;
@@ -90,10 +88,18 @@ void save_window_file(window const& window) {
         j[index] = state;
     }
 
-    log()->trace("save window {}", str(j.dump()));
+    file file(str(_window_file_), true);
+    if (!file.is_open()) {
+
+        log()->error("save window {}", str(j.dump()));
+        return;
+    }
 
-    std::ofstream o(_window_file_);
-    o << std::setw(4) << j << std::endl;
+    auto jString = j.dump(4);
+
+    file.write(jString.data(), jString.size());
+
+    log()->trace("save window {}", str(j.dump()));
 }
 
 void app::handle_config() {
@@ -235,6 +241,8 @@ bool app::setup() {
 
 bool app::create_gui() {
 
+    gui_config.ini_file_dir = file_system::get_pref_dir();
+
     gui.setup(window.get(), gui_config);
     if (!gui.create(device, target->get_frame_count(), shading.get_vk_pass()))
         return false;
diff --git a/liblava/app/def.hpp b/liblava/app/def.hpp
index 14a60c737e428751dc9d0a1797e7446cb379df58..8d5cfe6ff8fbe0774ec070d41afa1551b202d24f 100644
--- a/liblava/app/def.hpp
+++ b/liblava/app/def.hpp
@@ -9,7 +9,7 @@
 namespace lava {
 
 // window
-constexpr name _window_file_ = "data/window.json";
+constexpr name _window_file_ = "window.json";
 constexpr name _x_ = "x";
 constexpr name _y_ = "y";
 constexpr name _width_ = "width";
@@ -20,6 +20,9 @@ constexpr name _resizable_ = "resizable";
 constexpr name _decorated_ = "decorated";
 constexpr name _maximized_ = "maximized";
 
+// gui
+constexpr name _gui_file_ = "gui.ini";
+
 // config
 constexpr name _paused_ = "paused";
 constexpr name _speed_ = "speed";
@@ -28,11 +31,7 @@ constexpr name _save_interval_ = "save interval";
 constexpr name _auto_load_ = "auto load";
 constexpr name _fixed_delta_ = "fixed delta";
 constexpr name _delta_ = "delta";
-constexpr name _dt_ = "dt";
 constexpr name _gui_ = "gui";
 constexpr name _vsync_ = "vsync";
 
-constexpr name _frame_ = "frame";
-constexpr name _current_ = "current";
-
 } // lava
diff --git a/liblava/app/gui.cpp b/liblava/app/gui.cpp
index d2897e684e923116c57b742d021481feeda255a5..f63334fffa67f7bddef563c8e57d0ae99368d775 100644
--- a/liblava/app/gui.cpp
+++ b/liblava/app/gui.cpp
@@ -3,6 +3,7 @@
 // license   : MIT; see accompanying LICENSE file
 
 #include <liblava/app/gui.hpp>
+#include <liblava/app/def.hpp>
 
 #define GLFW_INCLUDE_NONE
 #define GLFW_INCLUDE_VULKAN
@@ -198,7 +199,7 @@ void gui::setup(GLFWwindow* window_, config config) {
             ImGui::GetIO().AddInputCharacter(static_cast<unsigned short>(c));
     });
 
-    io.IniFilename = "data/gui.ini";
+    set_ini_file(config.ini_file_dir);
 
     on_key_event = [&](key_event const& event) {
 
@@ -455,6 +456,15 @@ bool gui::want_capture_mouse() const {
     return ImGui::GetIO().WantCaptureMouse;
 }
 
+void gui::set_ini_file(fs::path dir) {
+    
+    dir.append(_gui_file_);
+
+    ini_file = dir.string();
+
+    ImGui::GetIO().IniFilename = str(ini_file);
+}
+
 void gui::invalidate_device_objects() {
 
     vertex_buffers.clear();
diff --git a/liblava/app/gui.hpp b/liblava/app/gui.hpp
index 57ce3dd8cd8b7da23b3ded455084d38a1aff93dc..c3fb240d3f5030025cdc6c082699f77266ab412b 100644
--- a/liblava/app/gui.hpp
+++ b/liblava/app/gui.hpp
@@ -38,6 +38,8 @@ struct gui : input_callback {
         r32 font_size = default_font_size;
 
         icon_font icon;
+
+        fs::path ini_file_dir;
     };
 
     void setup(GLFWwindow* window, config config);
@@ -73,6 +75,9 @@ struct gui : input_callback {
 
     void toggle() { active = !active; }
 
+    void set_ini_file(fs::path dir);
+    fs::path get_ini_file() const { return fs::path(ini_file); }
+
 private:
     void handle_key_event(i32 key, i32 scancode, i32 action, i32 mods);
     void handle_mouse_button_event(i32 button, i32 action, i32 mods);
@@ -110,6 +115,8 @@ private:
 
     std::vector<GLFWcursor*> mouse_cursors;
 
+    string ini_file;
+
     bool active = true;
 };
 
diff --git a/liblava/frame/frame.cpp b/liblava/frame/frame.cpp
index 507c0dbdacbd5d5b6dfdcee3198b2c97a876017f..5dd2a73c622e05d4ddf61eaca59df2ece021ad13 100644
--- a/liblava/frame/frame.cpp
+++ b/liblava/frame/frame.cpp
@@ -188,9 +188,6 @@ bool frame::setup(frame_config config_) {
 
     file_system::get().mount_res();
 
-    if (config.data_folder)
-        file_system::get().create_data_folder();
-
     _initialized = true;
 
     log()->info("---");
diff --git a/liblava/frame/frame.hpp b/liblava/frame/frame.hpp
index eac9d9452599a80378a1485e8107c20467959dc9..9aa2dfcefb1a10e15a764dbd36ed3f8660eabb5e 100644
--- a/liblava/frame/frame.hpp
+++ b/liblava/frame/frame.hpp
@@ -14,8 +14,8 @@ namespace lava {
 struct frame_config {
 
     explicit frame_config() = default;
-    explicit frame_config(name app_, argh::parser cmd_line_, bool data_folder_ = false)
-                         : app(app_), cmd_line(cmd_line_), data_folder(data_folder_) {}
+    explicit frame_config(name app_, argh::parser cmd_line_)
+                         : app(app_), cmd_line(cmd_line_) {}
 
     argh::parser cmd_line;
 
@@ -26,8 +26,6 @@ struct frame_config {
     log_config log;
     instance::debug_config debug;
     instance::app_info app_info;
-
-    bool data_folder = false;
 };
 
 enum error {
diff --git a/liblava/util/file.hpp b/liblava/util/file.hpp
index e6fefd20cf40ca611e33b32ab1f34f36349ca84e..809c89c5b7e6407f47ac1f83ca337e8e2b4a56bd 100644
--- a/liblava/util/file.hpp
+++ b/liblava/util/file.hpp
@@ -18,7 +18,7 @@ struct PHYSFS_File;
 namespace lava {
 
 constexpr name _zip_ = "zip";
-constexpr name _config_file_ = "data/config.json";
+constexpr name _config_file_ = "config.json";
 
 using json = nlohmann::json;