diff --git a/ports/unix/file.c b/ports/unix/file.c
index 9bb44c6abdb492bdabf46d1c94c16943f7e3ba88..165bbd00b0382a38577ad7f9f2ffc0aa37b1ee57 100644
--- a/ports/unix/file.c
+++ b/ports/unix/file.c
@@ -37,7 +37,7 @@
 #include "py/mphal.h"
 #include "fdfile.h"
 
-#if MICROPY_PY_IO
+#if MICROPY_PY_IO && !MICROPY_VFS
 
 #ifdef _WIN32
 #define fsync _commit
@@ -277,4 +277,4 @@ const mp_obj_fdfile_t mp_sys_stdin_obj  = { .base = {&mp_type_textio}, .fd = STD
 const mp_obj_fdfile_t mp_sys_stdout_obj = { .base = {&mp_type_textio}, .fd = STDOUT_FILENO };
 const mp_obj_fdfile_t mp_sys_stderr_obj = { .base = {&mp_type_textio}, .fd = STDERR_FILENO };
 
-#endif // MICROPY_PY_IO
+#endif // MICROPY_PY_IO && !MICROPY_VFS
diff --git a/ports/unix/main.c b/ports/unix/main.c
index 03f2f357ee9208293adf045e0d00a644f200eee5..b68fe927973252884f611256159e191096b42222 100644
--- a/ports/unix/main.c
+++ b/ports/unix/main.c
@@ -46,6 +46,8 @@
 #include "py/mphal.h"
 #include "py/mpthread.h"
 #include "extmod/misc.h"
+#include "extmod/vfs.h"
+#include "extmod/vfs_posix.h"
 #include "genhdr/mpversion.h"
 #include "input.h"
 
@@ -447,6 +449,18 @@ MP_NOINLINE int main_(int argc, char **argv) {
 
     mp_init();
 
+    #if MICROPY_VFS_POSIX
+    {
+        // Mount the host FS at the root of our internal VFS
+        mp_obj_t args[2] = {
+            mp_type_vfs_posix.make_new(&mp_type_vfs_posix, 0, 0, NULL),
+            MP_OBJ_NEW_QSTR(MP_QSTR__slash_),
+        };
+        mp_vfs_mount(2, args, (mp_map_t*)&mp_const_empty_map);
+        MP_STATE_VM(vfs_cur) = MP_STATE_VM(vfs_mount_table);
+    }
+    #endif
+
     char *home = getenv("HOME");
     char *path = getenv("MICROPYPATH");
     if (path == NULL) {
@@ -645,6 +659,7 @@ MP_NOINLINE int main_(int argc, char **argv) {
     return ret & 0xff;
 }
 
+#if !MICROPY_VFS
 uint mp_import_stat(const char *path) {
     struct stat st;
     if (stat(path, &st) == 0) {
@@ -656,6 +671,7 @@ uint mp_import_stat(const char *path) {
     }
     return MP_IMPORT_STAT_NO_EXIST;
 }
+#endif
 
 void nlr_jump_fail(void *val) {
     printf("FATAL: uncaught NLR %p\n", val);
diff --git a/ports/unix/moduos_vfs.c b/ports/unix/moduos_vfs.c
index 96defa5544e23976902bd900f75a6448fd795a48..c61471e582dd98dee764756cd478b6191f693762 100644
--- a/ports/unix/moduos_vfs.c
+++ b/ports/unix/moduos_vfs.c
@@ -28,6 +28,7 @@
 #include <string.h>
 
 #include "extmod/vfs.h"
+#include "extmod/vfs_posix.h"
 #include "extmod/vfs_fat.h"
 
 #if MICROPY_VFS
@@ -52,6 +53,9 @@ STATIC const mp_rom_map_elem_t uos_vfs_module_globals_table[] = {
     { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mp_vfs_statvfs_obj) },
     { MP_ROM_QSTR(MP_QSTR_unlink), MP_ROM_PTR(&mp_vfs_remove_obj) }, // unlink aliases to remove
 
+    #if MICROPY_VFS_POSIX
+    { MP_ROM_QSTR(MP_QSTR_VfsPosix), MP_ROM_PTR(&mp_type_vfs_posix) },
+    #endif
     #if MICROPY_VFS_FAT
     { MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) },
     #endif
diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h
index f0e17ccad0150268d62c10e6f94aa71be2ecd32e..016dabf9f46afcae6f8e09aa9ed14110f55929ba 100644
--- a/ports/unix/mpconfigport.h
+++ b/ports/unix/mpconfigport.h
@@ -180,9 +180,9 @@ extern const struct _mp_obj_module_t mp_module_ffi;
 extern const struct _mp_obj_module_t mp_module_jni;
 
 #if MICROPY_PY_UOS_VFS
-#define MICROPY_PY_UOS_VFS_DEF { MP_ROM_QSTR(MP_QSTR_uos_vfs), MP_ROM_PTR(&mp_module_uos_vfs) },
+#define MICROPY_PY_UOS_DEF { MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&mp_module_uos_vfs) },
 #else
-#define MICROPY_PY_UOS_VFS_DEF
+#define MICROPY_PY_UOS_DEF { MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&mp_module_os) },
 #endif
 #if MICROPY_PY_FFI
 #define MICROPY_PY_FFI_DEF { MP_ROM_QSTR(MP_QSTR_ffi), MP_ROM_PTR(&mp_module_ffi) },
@@ -221,8 +221,7 @@ extern const struct _mp_obj_module_t mp_module_jni;
     MICROPY_PY_UTIME_DEF \
     MICROPY_PY_SOCKET_DEF \
     { MP_ROM_QSTR(MP_QSTR_umachine), MP_ROM_PTR(&mp_module_machine) }, \
-    { MP_ROM_QSTR(MP_QSTR_uos), MP_ROM_PTR(&mp_module_os) }, \
-    MICROPY_PY_UOS_VFS_DEF \
+    MICROPY_PY_UOS_DEF \
     MICROPY_PY_USELECT_DEF \
     MICROPY_PY_TERMIOS_DEF \
 
diff --git a/ports/unix/mpconfigport_coverage.h b/ports/unix/mpconfigport_coverage.h
index b3fcd1e6b039874ff577caa07648dc01fe190b68..f0e6fbe94b741ef73cde68e212305351d97c4f73 100644
--- a/ports/unix/mpconfigport_coverage.h
+++ b/ports/unix/mpconfigport_coverage.h
@@ -34,6 +34,7 @@
 
 #define MICROPY_FLOAT_HIGH_QUALITY_HASH (1)
 #define MICROPY_ENABLE_SCHEDULER       (1)
+#define MICROPY_READER_VFS             (1)
 #define MICROPY_PY_DELATTR_SETATTR     (1)
 #define MICROPY_PY_REVERSE_SPECIAL_METHODS (1)
 #define MICROPY_PY_BUILTINS_RANGE_BINOP (1)
@@ -43,7 +44,17 @@
 #define MICROPY_PY_URANDOM_EXTRA_FUNCS (1)
 #define MICROPY_PY_IO_BUFFEREDWRITER (1)
 #define MICROPY_PY_IO_RESOURCE_STREAM (1)
+#define MICROPY_VFS_POSIX              (1)
 #undef MICROPY_VFS_FAT
 #define MICROPY_VFS_FAT                (1)
 #define MICROPY_PY_FRAMEBUF            (1)
 #define MICROPY_PY_COLLECTIONS_NAMEDTUPLE__ASDICT (1)
+
+// TODO these should be generic, not bound to fatfs
+#define mp_type_fileio mp_type_vfs_posix_fileio
+#define mp_type_textio mp_type_vfs_posix_textio
+
+// use vfs's functions for import stat and builtin open
+#define mp_import_stat mp_vfs_import_stat
+#define mp_builtin_open mp_vfs_open
+#define mp_builtin_open_obj mp_vfs_open_obj