diff --git a/src/tangara/lua/file_iterator.cpp b/src/tangara/lua/file_iterator.cpp
index d318e255..270c8f30 100644
--- a/src/tangara/lua/file_iterator.cpp
+++ b/src/tangara/lua/file_iterator.cpp
@@ -7,6 +7,7 @@
 #include "esp_log.h"
 
 #include <string>
+#include <algorithm>
 
 #include "drivers/spi.hpp"
 #include "ff.h"
@@ -91,4 +92,64 @@ auto FileIterator::iterate(bool show_hidden) -> bool {
   return true;
 }
 
+
+
+FileIteratorSorted::FileIteratorSorted(std::string filepath, bool showHidden)
+    : offset_(-1) {
+
+  FileIterator iter(filepath, showHidden);
+
+  while (true) {
+    iter.next();
+    std::optional<FileEntry> res = iter.value();
+    if (res) {
+      files_.push_back(*res);
+    } else {
+      break;
+    }
+  }
+
+  std::sort(files_.begin(), files_.end(),
+    [](const auto& lhs, const auto& rhs) {
+        if (lhs.isDirectory > rhs.isDirectory) {
+          return true;
+        } else if (lhs.isDirectory < rhs.isDirectory) {
+          return false;
+        }
+
+        return lhs.name < rhs.name;
+    });
+
+  // reindex the files
+  for(size_t i = 0; i != files_.size(); i++) {
+    files_[i].index = i + 1;
+  }
+}
+
+FileIteratorSorted::~FileIteratorSorted() {
+}
+
+auto FileIteratorSorted::value() const -> const std::optional<FileEntry> {
+  if (offset_ < 0 || offset_ >= files_.size()) {
+    return std::nullopt;
+  }
+  return std::optional(files_[offset_]);
+}
+
+auto FileIteratorSorted::next() -> void {
+  if (offset_ < (int) files_.size()) {
+    offset_++;
+  }
+}
+
+auto FileIteratorSorted::prev() -> void {
+  if (offset_ <= 0) {
+    offset_ = -1;
+    return;
+  }
+
+  offset_--;
+}
+
+
 }  // namespace lua
diff --git a/src/tangara/lua/file_iterator.hpp b/src/tangara/lua/file_iterator.hpp
index 2d5c2d7d..f5b76bd7 100644
--- a/src/tangara/lua/file_iterator.hpp
+++ b/src/tangara/lua/file_iterator.hpp
@@ -8,6 +8,7 @@
 
 #include <string>
 #include <optional>
+#include <vector>
 
 #include "ff.h"
 
@@ -43,4 +44,18 @@ class FileIterator {
   auto iterate(bool reverse = false) -> bool;
 };
 
+class FileIteratorSorted {
+ public:
+  FileIteratorSorted(std::string filepath, bool showHidden);
+  ~FileIteratorSorted();
+
+  auto value() const -> const std::optional<FileEntry>;
+  auto next() -> void;
+  auto prev() -> void;
+
+ private:
+  std::vector<FileEntry> files_;
+  int offset_;
+};
+
 } // namespace lua
diff --git a/src/tangara/lua/lua_filesystem.cpp b/src/tangara/lua/lua_filesystem.cpp
index b7d446f3..f1f073d1 100644
--- a/src/tangara/lua/lua_filesystem.cpp
+++ b/src/tangara/lua/lua_filesystem.cpp
@@ -38,22 +38,22 @@ auto check_file_entry(lua_State* L, int stack_pos) -> lua::FileEntry* {
   return entry;
 }
 
-auto check_file_iterator(lua_State* L, int stack_pos) -> lua::FileIterator* {
-  lua::FileIterator* it = *reinterpret_cast<lua::FileIterator**>(
+auto check_file_iterator(lua_State* L, int stack_pos) -> lua::FileIteratorSorted* {
+  lua::FileIteratorSorted* it = *reinterpret_cast<lua::FileIteratorSorted**>(
       luaL_checkudata(L, stack_pos, kFileIteratorMetatable));
   return it;
 }
 
-static auto push_iterator(lua_State* state, const lua::FileIterator& it)
+static auto push_iterator(lua_State* state, const lua::FileIteratorSorted& it)
     -> void {
-  lua::FileIterator** data = reinterpret_cast<lua::FileIterator**>(
+  lua::FileIteratorSorted** data = reinterpret_cast<lua::FileIteratorSorted**>(
       lua_newuserdata(state, sizeof(uintptr_t)));
-  *data = new lua::FileIterator(it);
+  *data = new lua::FileIteratorSorted(it);
   luaL_setmetatable(state, kFileIteratorMetatable);
 }
 
 static auto fs_iterate_prev(lua_State* state) -> int {
-  lua::FileIterator* it = check_file_iterator(state, 1);
+  lua::FileIteratorSorted* it = check_file_iterator(state, 1);
   it->prev();
   std::optional<lua::FileEntry> res = it->value();
 
@@ -67,7 +67,7 @@ static auto fs_iterate_prev(lua_State* state) -> int {
 }
 
 static auto fs_iterate(lua_State* state) -> int {
-  lua::FileIterator* it = check_file_iterator(state, 1);
+  lua::FileIteratorSorted* it = check_file_iterator(state, 1);
   it->next();
   std::optional<lua::FileEntry> res = it->value();
 
@@ -81,13 +81,13 @@ static auto fs_iterate(lua_State* state) -> int {
 }
 
 static auto fs_iterator_clone(lua_State* state) -> int {
-  lua::FileIterator* it = check_file_iterator(state, 1);
+  lua::FileIteratorSorted* it = check_file_iterator(state, 1);
   push_iterator(state, *it);
   return 1;
 }
 
 static auto fs_iterator_value(lua_State* state) -> int {
-  lua::FileIterator* it = check_file_iterator(state, 1);
+  lua::FileIteratorSorted* it = check_file_iterator(state, 1);
   std::optional<lua::FileEntry> res = it->value();
 
   if (res) {
@@ -100,7 +100,7 @@ static auto fs_iterator_value(lua_State* state) -> int {
 }
 
 static auto fs_iterator_gc(lua_State* state) -> int {
-  lua::FileIterator* it = check_file_iterator(state, 1);
+  lua::FileIteratorSorted* it = check_file_iterator(state, 1);
   delete it;
   return 0;
 }
@@ -155,7 +155,7 @@ static auto fs_new_iterator(lua_State* state) -> int {
   // Takes a filepath as a string and returns a new FileIterator
   // on that directory
   std::string filepath = luaL_checkstring(state, -1);
-  lua::FileIterator iter(filepath, false);
+  lua::FileIteratorSorted iter(filepath, false);
    push_iterator(state, iter);
   return 1;
 }
diff --git a/src/tangara/lua/lua_filesystem.hpp b/src/tangara/lua/lua_filesystem.hpp
index d0f51498..dad058a1 100644
--- a/src/tangara/lua/lua_filesystem.hpp
+++ b/src/tangara/lua/lua_filesystem.hpp
@@ -10,7 +10,7 @@
 
 namespace lua {
 
-auto check_file_iterator(lua_State*, int stack_pos) -> lua::FileIterator*;
+auto check_file_iterator(lua_State*, int stack_pos) -> lua::FileIteratorSorted*;
 
 auto RegisterFileSystemModule(lua_State*) -> void;