diff --git a/Test.hs b/Test.hs
--- a/Test.hs
+++ b/Test.hs
@@ -19,7 +19,16 @@
 import Data.Maybe
 
 main :: IO ()
-main = rawTest >> argTest >> optTest >> flagTest >> bigProgTests >> optDefTest >> envTest
+main =
+     rawTest
+  >> argTest
+  >> optTest
+  >> flagTest
+  >> bigProgTests
+  >> optDefTest
+  >> envTest
+  >> envOptTest
+  >> envOptDefTest
 
 rawProg :: ProgramT Raw IO Bool
 rawProg = raw (pure True)
@@ -88,8 +97,34 @@
 
 envTest :: IO ()
 envTest = do
+  putStrLn "Testing environment variables"
   testBool =<< isNothing <$> test (envProg (== ("POOP" :: String))) (State mempty mempty mempty)
   setEnv "ONOGOTTAFINDABIGNAME" "POOP"
   testMaybeBool =<< test (envProg (== ("POOP" :: String))) (State mempty mempty mempty)
   setEnv "ONOGOTTAFINDABIGNAME" "POP"
   testMaybeBool =<< fmap not <$> test (envProg (== ("POOP" :: String))) (State mempty mempty mempty)
+
+envOptProg :: (Maybe x -> Bool) -> ProgramT (Env 'Optional "BIGNAME" x & Raw) IO Bool
+envOptProg prop = envOpt \e -> raw (pure (prop e))
+
+envOptProg' :: ProgramT (Env 'Optional "BIGNAME" x & Raw) IO (Maybe x)
+envOptProg' = envOpt \e -> raw (pure e)
+
+envOptTest :: IO ()
+envOptTest = do
+  putStrLn "Testing optional environment variables"
+  testMaybeBool =<< test (envOptProg (== (Nothing @Bool))) (State mempty mempty mempty)
+  setEnv "BIGNAME" "POP"
+  testMaybeBool =<< fmap not <$> test (envOptProg (== (Just ("POOP" :: String)))) (State mempty mempty mempty)
+  testMaybeBool =<< test (envOptProg (== (Just ("POP" :: String)))) (State mempty mempty mempty)
+
+envOptDefProg :: x -> (x -> Bool) -> ProgramT (Env 'Optional "CORPUS" x & Raw) IO Bool
+envOptDefProg x prop = envOptDef x \e -> raw (pure (prop e))
+
+envOptDefTest :: IO ()
+envOptDefTest = do
+  putStrLn "Testing optional environment variables with hard-coded defaults"
+  testMaybeBool =<< test (envOptDefProg (10 :: Int) (== 10)) (State mempty mempty mempty)
+  testMaybeBool =<< fmap not <$> test (envOptDefProg "POP" (== ("POOP" :: String))) (State mempty mempty mempty)
+  setEnv "CORPUS" "POOP"
+  testMaybeBool =<< test (envOptDefProg "POP" (== ("POOP" :: String))) (State mempty mempty mempty)
diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -22,7 +22,7 @@
 type TaskManager
   = Named "task-manager"
   & ("help" & Raw
-  + Env 'Required "TASK_DIRECTORY" FilePath
+  + Env 'Optional "TASK_DIRECTORY" FilePath
     & ("edit"  & TaskProgram
      + "open"  & TaskProgram
      + "close" & TaskProgram
@@ -35,7 +35,7 @@
 type TaskProgram = Arg "task-name" String & Raw
   
 taskManager :: ProgramT TaskManager IO ()
-taskManager = toplevel @"task-manager" . env @"TASK_DIRECTORY" $ \tasksFilePath -> 
+taskManager = toplevel @"task-manager" . envOptDef @"TASK_DIRECTORY" "tasks" $ \tasksFilePath -> 
       sub @"edit" (editTask tasksFilePath) 
   <+> sub @"open" (newTask tasksFilePath)
   <+> sub @"close" (closeTask tasksFilePath)
diff --git a/commander-cli.cabal b/commander-cli.cabal
--- a/commander-cli.cabal
+++ b/commander-cli.cabal
@@ -1,7 +1,7 @@
 cabal-version:       2.4
 
 name:                commander-cli
-version:             0.6.1.0
+version:             0.6.2.0
 synopsis:            A command line argument/option parser library built around a monadic metaphor
 description:         A command line argument/option parser library built around a monadic metaphor.
 homepage:            https://github.com/SamuelSchlesinger/commander-cli
diff --git a/src/Options/Commander.hs b/src/Options/Commander.hs
--- a/src/Options/Commander.hs
+++ b/src/Options/Commander.hs
@@ -428,9 +428,9 @@
   run f = Action $ \state -> do
     val <- lookupEnv (symbolVal (Proxy @name))
     case val of
-      Just v ->
-        case unrender (pack v) of
-          Just t -> return (run (unEnvProgramT'Optional f t), state)  
+      Just v -> do
+        case unrender @t (pack v) of
+          Just t -> return (run (unEnvProgramT'Optional f (Just t)), state)  
           Nothing -> return (Defeat, state)
       Nothing -> return (run (unEnvProgramT'Optional f (unEnvDefault f)), state)
 
