diff --git a/cherry-core-alpha.cabal b/cherry-core-alpha.cabal
--- a/cherry-core-alpha.cabal
+++ b/cherry-core-alpha.cabal
@@ -1,6 +1,6 @@
 cabal-version:       >=1.10
 name:                cherry-core-alpha
-version:             0.4.0.0
+version:             0.5.0.0
 synopsis:            The core library for Cherry Haskell.
 description:         The core library for Cherry Haskell, including a standard fuctions, server, and json parsing.
 license:             BSD3
diff --git a/src/File.hs b/src/File.hs
--- a/src/File.hs
+++ b/src/File.hs
@@ -13,15 +13,20 @@
 
 -}
 
-module File (Path, read, write, doesExist, list) where
+module File (Path, read, rename, write, delete, doesExist, list) where
 
 import qualified List
 import qualified String
+import qualified Data.Maybe
+import qualified System.IO.Error
+import qualified Control.Exception
 import qualified Internal.Task as Task
 import qualified Internal.Utils as U
 import qualified "text-utf8" Data.Text.IO as IO
 import qualified System.Directory as Directory
-import Prelude (return, getContents)
+import qualified Prelude as P
+import Prelude (return, getContents, sequence)
+import Data.List (stripPrefix)
 import Basics
 import Maybe (Maybe (..))
 import Result (Result (..))
@@ -41,15 +46,39 @@
 
 {-| -}
 write :: Path -> String -> Task x ()
-write filename string =
+write path string =
   Task.Task <| do
-    let dir = String.split "/" filename |> List.reverse |> List.drop 1 |> List.reverse |> String.join "/"
+    let dir = String.split "/" path |> List.reverse |> List.drop 1 |> List.reverse |> String.join "/"
     Directory.createDirectoryIfMissing True (String.toList dir)
-    IO.writeFile (String.toList filename) (String.toTextUtf8 string)
+    IO.writeFile (String.toList path) (String.toTextUtf8 string)
     return (Ok ())
 
 
 {-| -}
+rename :: Path -> Path -> Task x ()
+rename old new =
+  Task.Task <|
+    let handleError err =
+          if System.IO.Error.isDoesNotExistError err
+            then return ()
+            else Control.Exception.throwIO err
+    in
+    P.fmap Ok (Directory.renameFile (String.toList old) (String.toList new) `Control.Exception.catch` handleError)
+
+
+{-| -}
+delete :: Path -> Task x ()
+delete path =
+  Task.Task <|
+    let handleError err =
+          if System.IO.Error.isDoesNotExistError err
+            then return ()
+            else Control.Exception.throwIO err
+    in
+    P.fmap Ok (Directory.removeFile (String.toList path) `Control.Exception.catch` handleError)
+
+
+{-| -}
 doesExist :: Path -> Task x Bool
 doesExist path =
   Task.Task <| do
@@ -66,8 +95,30 @@
 
 
 {-| -}
-list :: Path -> Task x (List Path)
+list :: Path -> Task String (List Path)
 list path =
-  Task.Task <| do
-    files <- Directory.listDirectory (String.toList path)
-    return (Ok (List.map String.fromList files))
+  Task.Task <|
+    let
+        findFiles :: P.String -> List P.String -> P.IO (List P.String)
+        findFiles folder acc = do
+          items <- Directory.listDirectory folder
+          newfiles <- List.foldl checkOne (return []) (List.map (\i -> folder ++ "/" ++ i) items)
+          return (acc ++ newfiles)
+
+        checkOne :: P.String -> P.IO (List P.String) -> P.IO (List P.String)
+        checkOne name acc = do
+          exists <- Directory.doesDirectoryExist name
+          if exists then do
+            files <- acc
+            findFiles name files
+          else
+            P.fmap (\fs -> name : fs) acc
+    in do
+    let directory = String.toList path
+    exists <- Directory.doesDirectoryExist directory
+    if exists then do
+      files <- findFiles directory []
+      let final = Data.Maybe.mapMaybe (stripPrefix (directory ++ "/")) files
+      return (Ok (List.map String.fromList final))
+    else
+      return (Err "Given path is not a directory.")
