diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,22 @@
 # Changelog for harg
 
-## Unreleased changes
+## 0.1.3.0 [2019.08.28]
+
+- Add `manyParser` to parse list of options separated by delimiter
+
+## 0.1.2.0 [2019.08.19]
+
+- Add `optRequired` to mark option as required
+
+## 0.1.1.0 [2019.08.16]
+
+- Add `optDefaultStr` to provide defaults as unparsed strings
+- Bump dependencies (`barbies` and `higgledy`)
+
+## 0.1.0.1 [2019.07.19]
+
+- Minor documentation changes
+
+## 0.1.0.0 [2019.07.18]
+
+- Initial release
diff --git a/README.lhs b/README.lhs
--- a/README.lhs
+++ b/README.lhs
@@ -1,9 +1,10 @@
-# `harg` :nut_and_bolt:
+# harg
 
-[![Build Status](https://travis-ci.org/alexpeits/harg.svg?branch=master)](https://travis-ci.org/alexpeits/harg) [![Hackage](https://img.shields.io/hackage/v/harg.svg)](https://hackage.haskell.org/package/harg)
+[![Build Status](https://travis-ci.org/alexpeits/harg.svg?branch=master)](https://travis-ci.org/alexpeits/harg)
+[![Hackage](https://img.shields.io/hackage/v/harg.svg)](https://hackage.haskell.org/package/harg)
 
 `harg` is a library for configuring programs by scanning command line arguments, environment
-variables and default values. Under the hood, it uses a subset of
+variables, default values and more. Under the hood, it uses a subset of
 [`optparse-applicative`](https://hackage.haskell.org/package/optparse-applicative) to expose regular
 arguments, switch arguments and subcommands. The library relies heavily on the use of higher kinded
 data (HKD) thanks to the [`barbies`](https://hackage.haskell.org/package/barbies) library. Using
@@ -17,8 +18,6 @@
 
 tl;dr: Take a look at the [example](Example.hs).
 
-(WIP)
-
 Here are some different usage scenarios. Let's first enable some language extensions and add some
 imports:
 
@@ -151,6 +150,24 @@
 -> Maybe a` use `parseWith`, which runs the parser and in case of failure uses a default error
 message. For example, `readParser` is defined as `parseWith readMaybe`.
 
+Finally, an optional option with type `a` can be specified by setting its type to `Maybe a`. The
+declaration is exactly the same as it would be for `a`, and adding `optOptional` to the modifiers
+turns turns the parser from `String -> Either String a` to `String -> Either String (Maybe a)` but
+without using the `Read` instance for `Maybe`:
+
+``` haskell ignore
+someOpt :: Opt (Maybe Int)
+someOpt
+  = toOpt ( option readParser
+          & optLong "something"
+          & optOptional
+          )
+```
+
+Note that `optOptional` can't be used with `optDefault`. Using them together raises a type error at
+compile time, to ensure there's no ambiguous behaviour (e.g. the order of declaration of modifiers
+should not influence the resulting option).
+
 There are 3 ways to configure this datatype.
 
 ### 1. Using a `barbie` type
@@ -706,6 +723,34 @@
               & optHelp "JSON config filepath"
               )
 ```
+
+Here, the type of the option for the JSON source is `ConfigFile`. This type is a wrapper around
+`FilePath`, which looks like this:
+
+``` haskell ignore
+data ConfigFile
+  = ConfigFile FilePath
+  | NoConfigFile
+```
+
+This has the advantage that, if the user wants to specify an optional configuration file, they can
+simply say:
+
+``` haskell
+jsonOpt :: Opt ConfigFile
+jsonOpt
+  = toOpt ( option strParser
+          & optLong "json"
+          & optDefault NoConfigFile
+          )
+```
+
+Also, because `ConfigFile` has an `IsString` instance, there's no need to say
+`optLong (ConfigFile "json")` (if `OverloadedStrings` is enabled).
+
+There's a bit of a disconnect between `ConfigFile` and the ability to make optional options using
+`Maybe` and `optOptional`. The reason for it is that the type that `JSONSource` wraps is not
+polymorphic, since it needs to be a filepath specifically.
 
 # Roadmap
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,9 +1,10 @@
-# `harg` :nut_and_bolt:
+# harg
 
-[![Build Status](https://travis-ci.org/alexpeits/harg.svg?branch=master)](https://travis-ci.org/alexpeits/harg) [![Hackage](https://img.shields.io/hackage/v/harg.svg)](https://hackage.haskell.org/package/harg)
+[![Build Status](https://travis-ci.org/alexpeits/harg.svg?branch=master)](https://travis-ci.org/alexpeits/harg)
+[![Hackage](https://img.shields.io/hackage/v/harg.svg)](https://hackage.haskell.org/package/harg)
 
 `harg` is a library for configuring programs by scanning command line arguments, environment
-variables and default values. Under the hood, it uses a subset of
+variables, default values and more. Under the hood, it uses a subset of
 [`optparse-applicative`](https://hackage.haskell.org/package/optparse-applicative) to expose regular
 arguments, switch arguments and subcommands. The library relies heavily on the use of higher kinded
 data (HKD) thanks to the [`barbies`](https://hackage.haskell.org/package/barbies) library. Using
@@ -17,8 +18,6 @@
 
 tl;dr: Take a look at the [example](Example.hs).
 
-(WIP)
-
 Here are some different usage scenarios. Let's first enable some language extensions and add some
 imports:
 
@@ -151,6 +150,24 @@
 -> Maybe a` use `parseWith`, which runs the parser and in case of failure uses a default error
 message. For example, `readParser` is defined as `parseWith readMaybe`.
 
+Finally, an optional option with type `a` can be specified by setting its type to `Maybe a`. The
+declaration is exactly the same as it would be for `a`, and adding `optOptional` to the modifiers
+turns turns the parser from `String -> Either String a` to `String -> Either String (Maybe a)` but
+without using the `Read` instance for `Maybe`:
+
+``` haskell ignore
+someOpt :: Opt (Maybe Int)
+someOpt
+  = toOpt ( option readParser
+          & optLong "something"
+          & optOptional
+          )
+```
+
+Note that `optOptional` can't be used with `optDefault`. Using them together raises a type error at
+compile time, to ensure there's no ambiguous behaviour (e.g. the order of declaration of modifiers
+should not influence the resulting option).
+
 There are 3 ways to configure this datatype.
 
 ### 1. Using a `barbie` type
@@ -706,6 +723,34 @@
               & optHelp "JSON config filepath"
               )
 ```
+
+Here, the type of the option for the JSON source is `ConfigFile`. This type is a wrapper around
+`FilePath`, which looks like this:
+
+``` haskell ignore
+data ConfigFile
+  = ConfigFile FilePath
+  | NoConfigFile
+```
+
+This has the advantage that, if the user wants to specify an optional configuration file, they can
+simply say:
+
+``` haskell
+jsonOpt :: Opt ConfigFile
+jsonOpt
+  = toOpt ( option strParser
+          & optLong "json"
+          & optDefault NoConfigFile
+          )
+```
+
+Also, because `ConfigFile` has an `IsString` instance, there's no need to say
+`optLong (ConfigFile "json")` (if `OverloadedStrings` is enabled).
+
+There's a bit of a disconnect between `ConfigFile` and the ability to make optional options using
+`Maybe` and `optOptional`. The reason for it is that the type that `JSONSource` wraps is not
+polymorphic, since it needs to be a filepath specifically.
 
 # Roadmap
 
diff --git a/harg.cabal b/harg.cabal
--- a/harg.cabal
+++ b/harg.cabal
@@ -1,8 +1,8 @@
 cabal-version: 2.2
 
 name:           harg
-version:        0.1.0.1
-synopsis:       Haskell program configuration from multiple sources
+version:        0.1.3.0
+synopsis:       Haskell program configuration using higher kinded data
 description:    Please see the README on GitHub at <https://github.com/alexpeits/harg#readme>
 homepage:       https://github.com/alexpeits/harg
 bug-reports:    https://github.com/alexpeits/harg/issues
@@ -13,7 +13,7 @@
 license:        BSD-3-Clause
 license-file:   LICENSE
 build-type:     Simple
-category:       System, CLI, Options, Parsing
+category:       System, CLI, Options, Parsing, HKD
 extra-source-files:
     README.md
     CHANGELOG.md
@@ -38,6 +38,7 @@
                       Options.Harg.Pretty
                       Options.Harg.Single
                       Options.Harg.Sources
+                      Options.Harg.Sources.DefaultStr
                       Options.Harg.Sources.Env
                       Options.Harg.Sources.JSON
                       Options.Harg.Sources.NoSource
@@ -62,11 +63,12 @@
                       -Wno-unticked-promoted-constructors
   build-depends:      base >=4.7 && <5
                     , aeson >= 1.4.2 && < 1.5
-                    , barbies >= 1.0.0 && < 1.2
+                    , barbies >= 1.1.0 && < 1.2
                     , bytestring >= 0.10.8 && < 0.11
                     , directory >= 1.3.3 && < 1.4
-                    , higgledy >= 0.2.0 && < 0.3
+                    , higgledy >= 0.3.0 && < 0.4
                     , optparse-applicative >= 0.14.3 && < 0.15
+                    , split >= 0.2.3 && < 0.3
                     , text >= 1.2.3 && < 1.3
                     , yaml >= 0.11.0 && < 0.12
   default-language:   Haskell2010
diff --git a/src/Options/Harg.hs b/src/Options/Harg.hs
--- a/src/Options/Harg.hs
+++ b/src/Options/Harg.hs
@@ -37,6 +37,8 @@
   , optMetavar
   , optEnvVar
   , optDefault
+  , optDefaultStr
+  , optRequired
   , optOptional
   , toOpt
   , Opt
@@ -46,6 +48,7 @@
   , readParser
   , strParser
   , boolParser
+  , manyParser
 
   -- ** Executing options
   , execOpt
diff --git a/src/Options/Harg/Construct.hs b/src/Options/Harg/Construct.hs
--- a/src/Options/Harg/Construct.hs
+++ b/src/Options/Harg/Construct.hs
@@ -7,9 +7,11 @@
 import Data.Char          (toLower)
 import Data.Kind          (Constraint)
 import Data.String        (IsString(..))
-import GHC.TypeLits       (ErrorMessage(..), TypeError, Symbol)
+import GHC.TypeLits       (ErrorMessage(..), TypeError, Symbol, AppendSymbol)
 import Text.Read          (readMaybe)
 
+import Data.List.Split    (splitOn)
+
 import Options.Harg.Types
 
 
@@ -72,9 +74,11 @@
 
 class HasDefault o (attr :: [OptAttr]) where
   -- | Add a default value to an option. Cannot be used in conjuction with
-  -- 'optOptional'.
+  -- with 'optRequired', 'optDefaultStr' or 'optOptional'.
   optDefault
-    :: NotInAttrs OptOptional attr "optDefault" "optOptional"
+    :: ( NotInAttrs OptDefault attr (DuplicateAttrMultipleErr "optDefault" '["optDefaultStr", "optRequired"])
+       , NotInAttrs OptOptional attr (IncompatibleAttrsErr "optDefault" "optOptional")
+       )
     => a -> o attr a -> o (OptDefault ': attr) a
 
 instance HasDefault OptionOpt a where
@@ -83,10 +87,40 @@
 instance HasDefault ArgumentOpt a where
   optDefault a o = o { _aDefault = Just a }
 
--- optional
--- | Class for options that can be optional. Cannot be used in
--- conjunction with 'HasDefault'. Note that this will turn a parser for @a@
--- into a parser for @Maybe a@, modifying the reader function appropriately.
+class HasDefaultStr o (attr :: [OptAttr]) where
+  -- | Add a default unparsed value to an option. Cannot be used in conjuction
+  -- with 'optDefault', 'optRequired' or 'optOptional'.
+  optDefaultStr
+    :: ( NotInAttrs OptDefault attr (DuplicateAttrMultipleErr "optDefaultStr" '["optDefault", "optRequired"])
+       , NotInAttrs OptOptional attr (IncompatibleAttrsErr "optDefaultStr" "optOptional")
+       )
+    => String -> o attr a -> o (OptDefault ': attr) a
+
+instance HasDefaultStr OptionOpt a where
+  optDefaultStr s o = o { _oDefaultStr = Just s }
+
+instance HasDefaultStr ArgumentOpt a where
+  optDefaultStr s o = o { _aDefaultStr = Just s }
+
+class HasRequired o (attr :: [OptAttr]) where
+  -- | Mark an option as required. Cannot be used in conjunction with
+  -- 'optOptional', 'optDefault' or 'optRequiredStr'.
+  optRequired
+    :: ( NotInAttrs OptDefault attr (DuplicateAttrMultipleErr "optRequired" '["optDefault", "optDefaultStr"])
+       , NotInAttrs OptOptional attr (IncompatibleAttrsErr "optRequired" "optOptional")
+       )
+    => o attr a -> o (OptDefault ': attr) a
+
+instance HasRequired OptionOpt a where
+  optRequired o = o { _oDefault = Nothing }
+
+instance HasRequired ArgumentOpt a where
+  optRequired o = o { _aDefault = Nothing }
+
+-- | Class for options that can be optional. Cannot be used in conjunction with
+-- 'HasDefault', 'HasDefaultStr' or 'HasRequired'. Note that this will turn a
+-- parser for @a@ into a parser for @Maybe a@, modifying the reader function
+-- appropriately.
 -- For example:
 --
 -- @
@@ -99,31 +133,36 @@
 -- @
 class HasOptional o (attr :: [OptAttr]) where
   -- | Specify that an option is optional. This will convert an @Opt a@ to an
-  -- @Opt (Maybe a)@
+  -- @Opt (Maybe a)@. Cannot be used in conjunction with 'optDefault', 'optDefaultStr'
+  -- or 'optRequired'.
   optOptional
-    :: NotInAttrs OptDefault attr "optOptional" "optDefault"
+    :: ( NotInAttrs OptOptional attr (DuplicateAttrErr "optOptional")
+       , NotInAttrs OptDefault attr (IncompatibleAttrsErr "optOptional" "optDefault")
+       )
     => o attr a -> o (OptOptional ': attr) (Maybe a)
 
 instance HasOptional OptionOpt a where
   optOptional OptionOpt{..}
     = OptionOpt
-        { _oLong    = _oLong
-        , _oShort   = _oShort
-        , _oHelp    = _oHelp
-        , _oMetavar = _oMetavar
-        , _oEnvVar  = _oEnvVar
-        , _oDefault = Just Nothing
-        , _oReader  = fmap Just . _oReader
+        { _oLong       = _oLong
+        , _oShort      = _oShort
+        , _oHelp       = _oHelp
+        , _oMetavar    = _oMetavar
+        , _oEnvVar     = _oEnvVar
+        , _oDefault    = Just Nothing
+        , _oDefaultStr = Nothing
+        , _oReader     = fmap Just . _oReader
         }
 
 instance HasOptional ArgumentOpt a where
   optOptional ArgumentOpt{..}
     = ArgumentOpt
-        { _aHelp    = _aHelp
-        , _aMetavar = _aMetavar
-        , _aEnvVar  = _aEnvVar
-        , _aDefault = Just Nothing
-        , _aReader  = fmap Just . _aReader
+        { _aHelp       = _aHelp
+        , _aMetavar    = _aMetavar
+        , _aEnvVar     = _aEnvVar
+        , _aDefault    = Just Nothing
+        , _aDefaultStr = Nothing
+        , _aReader     = fmap Just . _aReader
         }
 
 -- | Class to convert an intermediate option type into 'Opt'. Instances
@@ -135,40 +174,43 @@
 instance IsOpt OptionOpt attr where
   toOpt OptionOpt{..}
     = Opt
-        { _optLong    = _oLong
-        , _optShort   = _oShort
-        , _optHelp    = _oHelp
-        , _optMetavar = _oMetavar
-        , _optEnvVar  = _oEnvVar
-        , _optDefault = _oDefault
-        , _optReader  = _oReader
-        , _optType    = OptionOptType
+        { _optLong       = _oLong
+        , _optShort      = _oShort
+        , _optHelp       = _oHelp
+        , _optMetavar    = _oMetavar
+        , _optEnvVar     = _oEnvVar
+        , _optDefault    = _oDefault
+        , _optDefaultStr = _oDefaultStr
+        , _optReader     = _oReader
+        , _optType       = OptionOptType
         }
 
 instance IsOpt FlagOpt attr where
   toOpt FlagOpt{..}
     = Opt
-        { _optLong    = _fLong
-        , _optShort   = _fShort
-        , _optHelp    = _fHelp
-        , _optMetavar = Nothing
-        , _optEnvVar  = _fEnvVar
-        , _optDefault = Just _fDefault
-        , _optReader  = _fReader
-        , _optType    = FlagOptType _fActive
+        { _optLong       = _fLong
+        , _optShort      = _fShort
+        , _optHelp       = _fHelp
+        , _optMetavar    = Nothing
+        , _optEnvVar     = _fEnvVar
+        , _optDefault    = Just _fDefault
+        , _optDefaultStr = Nothing
+        , _optReader     = _fReader
+        , _optType       = FlagOptType _fActive
         }
 
 instance IsOpt ArgumentOpt attr where
   toOpt ArgumentOpt{..}
     = Opt
-        { _optLong    = Nothing
-        , _optShort   = Nothing
-        , _optHelp    = _aHelp
-        , _optMetavar = _aMetavar
-        , _optEnvVar  = _aEnvVar
-        , _optDefault = _aDefault
-        , _optReader  = _aReader
-        , _optType    = ArgumentOptType
+        { _optLong       = Nothing
+        , _optShort      = Nothing
+        , _optHelp       = _aHelp
+        , _optMetavar    = _aMetavar
+        , _optEnvVar     = _aEnvVar
+        , _optDefault    = _aDefault
+        , _optDefaultStr = _aDefaultStr
+        , _optReader     = _aReader
+        , _optType       = ArgumentOptType
         }
 
 -- | Create an option parser, equivalent to 'Options.Applicative.option'. The
@@ -188,13 +230,14 @@
   -> OptionOpt '[] a
 option p
   = OptionOpt
-      { _oLong    = Nothing
-      , _oShort   = Nothing
-      , _oHelp    = Nothing
-      , _oMetavar = Nothing
-      , _oEnvVar  = Nothing
-      , _oDefault = Nothing
-      , _oReader  = p
+      { _oLong       = Nothing
+      , _oShort      = Nothing
+      , _oHelp       = Nothing
+      , _oMetavar    = Nothing
+      , _oEnvVar     = Nothing
+      , _oDefault    = Nothing
+      , _oDefaultStr = Nothing
+      , _oReader     = p
       }
 
 -- | Similar to 'option', but accepts a modifier function and returns an 'Opt'
@@ -333,11 +376,12 @@
   -> ArgumentOpt '[] a
 argument p
   = ArgumentOpt
-      { _aHelp    = Nothing
-      , _aMetavar = Nothing
-      , _aEnvVar  = Nothing
-      , _aDefault = Nothing
-      , _aReader  = p
+      { _aHelp       = Nothing
+      , _aMetavar    = Nothing
+      , _aEnvVar     = Nothing
+      , _aDefault    = Nothing
+      , _aDefaultStr = Nothing
+      , _aReader     = p
       }
 
 -- | Similar to 'argument', but accepts a modifier function and returns an
@@ -393,6 +437,13 @@
       "false" -> Right False
       _       -> Left ("Unable to parse " <> s <> " to Bool")
 
+-- | A parser that can parse many items, returning a list.
+manyParser
+  :: String  -- ^ Separator
+  -> OptReader a  -- ^ Parser for each string
+  -> OptReader [a]
+manyParser sep parser
+  = traverse parser . splitOn sep
 
 -- | Wrap a symbol in quotes, for pretty printing in type errors.
 type QuoteSym (s :: Symbol)
@@ -403,15 +454,35 @@
 type family NotInAttrs
     (x :: k)
     (xs :: [k])
-    (l :: Symbol)
-    (r :: Symbol)
+    (err :: ErrorMessage)
     :: Constraint where
-  NotInAttrs _ '[]  _ _
+  NotInAttrs _ '[]  _
     = ()
-  NotInAttrs x (x ': _) l r
-    = TypeError
-    (    QuoteSym l :<>: 'Text " and " :<>: QuoteSym r
-    :<>: 'Text " cannot be mixed in an option definition."
-    )
-  NotInAttrs x (y ': xs) l r
-    = NotInAttrs x xs l r
+  NotInAttrs x (x ': _) err
+    = TypeError err
+  NotInAttrs x (y ': xs) err
+    = NotInAttrs x xs err
+
+type family CommaSep (xs :: [Symbol]) :: Symbol where
+  CommaSep '[] = ""
+  CommaSep '[x] = " or " `AppendSymbol` x
+  CommaSep (x ': xs) = " or one of " `AppendSymbol` CommaSep' x xs
+
+type family CommaSep' (s :: Symbol) (xs :: [Symbol]) :: Symbol where
+  CommaSep' s '[]       = s
+  CommaSep' s (x ': xs) = CommaSep' (s `AppendSymbol` ", " `AppendSymbol` x) xs
+
+type DuplicateAttrErr attr
+  =    QuoteSym attr
+  :<>: 'Text " is already specified."
+
+type DuplicateAttrMultipleErr attr rest
+  =    QuoteSym attr
+  :<>: 'Text (CommaSep rest)
+  :<>: 'Text " has already been specified."
+
+type IncompatibleAttrsErr l r
+  =    QuoteSym l
+  :<>: 'Text " and "
+  :<>: QuoteSym r
+  :<>: 'Text " cannot be mixed in an option definition."
diff --git a/src/Options/Harg/Operations.hs b/src/Options/Harg/Operations.hs
--- a/src/Options/Harg/Operations.hs
+++ b/src/Options/Harg/Operations.hs
@@ -6,23 +6,26 @@
 {-# LANGUAGE UndecidableInstances #-}
 module Options.Harg.Operations where
 
-import           Data.Functor.Identity      (Identity(..))
+import           Data.Functor.Identity           (Identity(..))
 
-import qualified Data.Barbie                as B
-import qualified Options.Applicative        as Optparse
+import qualified Data.Barbie                     as B
+import qualified Options.Applicative             as Optparse
 
-import           Options.Harg.Cmdline       (mkOptparseParser)
-import           Options.Harg.Config        (mkConfigParser, getConfig)
-import           Options.Harg.Het.All       (All)
-import           Options.Harg.Het.HList     (AssocListF, MapAssocList(..))
-import           Options.Harg.Het.Variant   (VariantF)
-import           Options.Harg.Pretty        (ppWarning, ppError)
-import           Options.Harg.Sources       (accumSourceResults, defaultSources)
-import           Options.Harg.Sources.Env   (EnvSourceVal)
-import           Options.Harg.Sources.Types (GetSource(..), RunSource(..))
-import           Options.Harg.Subcommands   (Subcommands(..))
-import           Options.Harg.Types         (HargCtx(..), getCtx, Opt, OptError)
-import           Options.Harg.Util          (toDummyOpts, allToDummyOpts, compose)
+import           Options.Harg.Cmdline            (mkOptparseParser)
+import           Options.Harg.Config             (mkConfigParser, getConfig)
+import           Options.Harg.Het.All            (All)
+import           Options.Harg.Het.HList          (AssocListF, MapAssocList(..))
+import           Options.Harg.Het.Prod           ((:*)(..))
+import           Options.Harg.Het.Variant        (VariantF)
+import           Options.Harg.Pretty             (ppWarning, ppError)
+import           Options.Harg.Sources            ( accumSourceResults
+                                                 , DefaultSources, defaultSources
+                                                 , HiddenSources, hiddenSources
+                                                 )
+import           Options.Harg.Sources.Types      (GetSource(..), RunSource(..))
+import           Options.Harg.Subcommands        (Subcommands(..))
+import           Options.Harg.Types              (HargCtx(..), getCtx, Opt, OptError)
+import           Options.Harg.Util               (toDummyOpts, allToDummyOpts, compose)
 
 
 -- | Run the option parser and combine with values from the specified sources,
@@ -43,7 +46,7 @@
 execOptWithCtx ctx conf opts
   = do
       let
-        configParser = mkConfigParser ctx (compose Identity conf)
+        configParser = mkConfigParser ctx $ compose Identity (conf :* hiddenSources)
         dummyParser = mkOptparseParser [] (toDummyOpts @String opts)
       config <- getConfig ctx configParser dummyParser
       sourceVals <- getSource ctx config
@@ -107,7 +110,7 @@
      , B.ProductB c
      , Subcommands ts xs
      , GetSource c Identity
-     , All (RunSource (SourceVal c)) xs
+     , All (RunSource (SourceVal (c :* HiddenSources))) xs
      , All (RunSource ()) xs
      , MapAssocList xs
      )
@@ -118,7 +121,7 @@
 execCommandsWithCtx ctx conf opts
   = do
       let
-        configParser = mkConfigParser ctx (compose Identity conf)
+        configParser = mkConfigParser ctx $ compose Identity (conf :* hiddenSources)
         (_, dummyCommands)
           = mapSubcommand () (allToDummyOpts @String opts)
         dummyParser
@@ -144,7 +147,7 @@
      , B.ProductB c
      , Subcommands ts xs
      , GetSource c Identity
-     , All (RunSource (SourceVal c)) xs
+     , All (RunSource (SourceVal (c :* HiddenSources))) xs
      , All (RunSource ()) xs
      , MapAssocList xs
      )
@@ -162,7 +165,7 @@
   :: forall ts xs.
      ( B.TraversableB (VariantF xs)
      , Subcommands ts xs
-     , All (RunSource EnvSourceVal) xs
+     , All (RunSource (SourceVal (DefaultSources :* HiddenSources))) xs
      , All (RunSource ()) xs
      , MapAssocList xs
      )
@@ -178,7 +181,7 @@
   :: forall ts xs.
      ( B.TraversableB (VariantF xs)
      , Subcommands ts xs
-     , All (RunSource EnvSourceVal) xs
+     , All (RunSource (SourceVal (DefaultSources :* HiddenSources))) xs
      , All (RunSource ()) xs
      , MapAssocList xs
      )
diff --git a/src/Options/Harg/Sources.hs b/src/Options/Harg/Sources.hs
--- a/src/Options/Harg/Sources.hs
+++ b/src/Options/Harg/Sources.hs
@@ -9,6 +9,7 @@
 
 import qualified Data.Barbie                as B
 
+import           Options.Harg.Sources.DefaultStr
 import           Options.Harg.Sources.Env
 import           Options.Harg.Sources.Types
 import           Options.Harg.Types
@@ -40,7 +41,16 @@
           OptParsed a       -> ([], Compose (Just a))
           _                 -> ([], Compose Nothing)
 
+type HiddenSources = DefaultStrSource
+
+-- | Sources hidden from user that are always enabled
+hiddenSources :: HiddenSources f
+hiddenSources
+  = DefaultStrSource
+
+type DefaultSources = EnvSource
+
 -- | Default sources, equivalent to 'EnvSource'
-defaultSources :: EnvSource f
+defaultSources :: DefaultSources f
 defaultSources
   = EnvSource
diff --git a/src/Options/Harg/Sources/DefaultStr.hs b/src/Options/Harg/Sources/DefaultStr.hs
new file mode 100644
--- /dev/null
+++ b/src/Options/Harg/Sources/DefaultStr.hs
@@ -0,0 +1,57 @@
+{-# LANGUAGE DeriveAnyClass #-}
+{-# LANGUAGE DeriveGeneric  #-}
+{-# LANGUAGE TypeFamilies   #-}
+module Options.Harg.Sources.DefaultStr where
+
+import           Data.Functor.Compose       (Compose (..))
+import           Data.Kind                  (Type)
+import           GHC.Generics               (Generic)
+
+import qualified Data.Barbie                as B
+
+import           Options.Harg.Sources.Types
+import           Options.Harg.Types
+
+
+-- | Source that enables a parser to read options from defaults that are provided
+-- as strings (unparsed).
+data DefaultStrSource (f :: Type -> Type) = DefaultStrSource
+  deriving (Generic, B.FunctorB, B.TraversableB, B.ProductB)
+
+-- | Value of 'DefaultStrSource' is a dummy value, as the default string option can
+-- be found inside the 'Opt' ('_optDefaultStr').
+data DefaultStrSourceVal = DefaultStrSourceVal
+
+instance GetSource DefaultStrSource f where
+  type SourceVal DefaultStrSource = DefaultStrSourceVal
+  getSource HargCtx{..} _
+    = pure DefaultStrSourceVal
+
+instance
+    B.FunctorB a => RunSource DefaultStrSourceVal a where
+  runSource DefaultStrSourceVal opt
+    = [runDefaultStrSource opt]
+
+runDefaultStrSource
+  :: forall a f.
+     ( B.FunctorB a
+     , Applicative f
+     )
+  => a (Compose Opt f)
+  -> a (Compose SourceRunResult f)
+runDefaultStrSource
+  = B.bmap go
+  where
+    go :: Compose Opt f x -> Compose SourceRunResult f x
+    go (Compose opt@Opt{..})
+      = case _optDefaultStr of
+          Nothing
+            -> Compose $ pure <$> OptNotFound
+          Just str
+            -> Compose $ tryParse str
+      where
+        tryParse
+          = either
+              (OptFoundNoParse . toOptError opt (Just "DefaultStrSource"))
+              OptParsed
+          . _optReader
diff --git a/src/Options/Harg/Types.hs b/src/Options/Harg/Types.hs
--- a/src/Options/Harg/Types.hs
+++ b/src/Options/Harg/Types.hs
@@ -8,15 +8,16 @@
 -- | The basic option type
 data Opt a
   = Opt
-      { _optLong    :: Maybe String -- ^ Modifier for long options (e.g. @--user@)
-      , _optShort   :: Maybe Char   -- ^ Modifier for short options (e.g. @-u@)
-      , _optHelp    :: Maybe String -- ^ Option help to be shown when invoked
-                                    --   with @--help/-h@ or in case of error
-      , _optMetavar :: Maybe String -- ^ Metavar to be shown in the help description
-      , _optEnvVar  :: Maybe String -- ^ Environment variable for use with 'EnvSource'
-      , _optDefault :: Maybe a      -- ^ Default value
-      , _optReader  :: OptReader a  -- ^ Option parser
-      , _optType    :: OptType a    -- ^ Option type
+      { _optLong       :: Maybe String -- ^ Modifier for long options (e.g. @--user@)
+      , _optShort      :: Maybe Char   -- ^ Modifier for short options (e.g. @-u@)
+      , _optHelp       :: Maybe String -- ^ Option help to be shown when invoked
+                                       --   with @--help/-h@ or in case of error
+      , _optMetavar    :: Maybe String -- ^ Metavar to be shown in the help description
+      , _optEnvVar     :: Maybe String -- ^ Environment variable for use with 'EnvSource'
+      , _optDefault    :: Maybe a      -- ^ Default value
+      , _optDefaultStr :: Maybe String -- ^ Default value as string (unparsed)
+      , _optReader     :: OptReader a  -- ^ Option parser
+      , _optType       :: OptType a    -- ^ Option type
       }
   deriving Functor
 
@@ -36,13 +37,14 @@
 -- | Option for flags with arguments. Corresponds to 'Options.Applicative.option'.
 data OptionOpt (attr :: [OptAttr]) a
   = OptionOpt
-      { _oLong    :: Maybe String
-      , _oShort   :: Maybe Char
-      , _oHelp    :: Maybe String
-      , _oMetavar :: Maybe String
-      , _oEnvVar  :: Maybe String
-      , _oDefault :: Maybe a
-      , _oReader  :: OptReader a
+      { _oLong       :: Maybe String
+      , _oShort      :: Maybe Char
+      , _oHelp       :: Maybe String
+      , _oMetavar    :: Maybe String
+      , _oEnvVar     :: Maybe String
+      , _oDefault    :: Maybe a
+      , _oDefaultStr :: Maybe String
+      , _oReader     :: OptReader a
       }
 
 -- | Option for flags that act like switches between a default and an active
@@ -62,11 +64,12 @@
 -- 'Options.Applicative.argument'.
 data ArgumentOpt (attr :: [OptAttr]) a
   = ArgumentOpt
-      { _aHelp    :: Maybe String
-      , _aMetavar :: Maybe String
-      , _aEnvVar  :: Maybe String
-      , _aDefault :: Maybe a
-      , _aReader  :: OptReader a
+      { _aHelp       :: Maybe String
+      , _aMetavar    :: Maybe String
+      , _aEnvVar     :: Maybe String
+      , _aDefault    :: Maybe a
+      , _aDefaultStr :: Maybe String
+      , _aReader     :: OptReader a
       }
 
 -- | Datatype that holds errors that arise when running the sources.
