diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,9 @@
 # Changelog for horizon-gen-nix
 
+## v0.4.0
+
+* Support horizon-spec 0.4.1
+
 ## v0.3.1
 
 * Remove broken --force flag.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,22 +1,39 @@
 # horizon-gen-nix
 
+
 horizon-gen-nix is an executable for generating nix expressions
 from [horizon-spec](https://hackage.haskell.org/package/horizon-spec)
 dhall definitions.
 
 ```
-Usage: horizon-gen-nix [--input-file INPUT_FILE] [--packages-dir PACKAGES_DIR]
-                       COMMAND
+Usage: horizon-gen-nix [--input-file INPUT_FILE]
 
 Available options:
   -h,--help                Show this help text
   --input-file INPUT_FILE  The name of the input file.
-  --packages-dir PACKAGES_DIR
-                           The directory to put haskell packages.
+```
 
-Available commands:
-  make-package-set         Run in MakePackageSet Mode
-  overlay                  Run in Overlay Mode
+## Example input
+
+The input file mentioned in the previous sections contains a dhall expression of
+the `HorizonExport` type (see `horizon-spec`).
+
+Here is an example input file:
+
+```
+let H =
+      https://gitlab.homotopic.tech/horizon/horizon-spec/-/raw/0.4.1/dhall/package.dhall
+        sha256:9f2def711ea8796cdb24fa837da6681f9a7e752f87aeff08eee9b494c6e3374c
+
+in  H.HorizonExport.MakeOverlay
+      { packagesDir = "pkgs"
+      , overlayFile = "overlay.nix"
+      , overlay =
+        [ H.callHackage "cabal2nix" "2.19.1"
+        , H.callHackage "distribution-nixpkgs" "1.7.0.1"
+        , H.callHackage "horizon-spec" "0.4.1"
+        ]
+      }
 ```
 
 ## Building
diff --git a/horizon-gen-nix.cabal b/horizon-gen-nix.cabal
--- a/horizon-gen-nix.cabal
+++ b/horizon-gen-nix.cabal
@@ -1,6 +1,6 @@
 cabal-version:      3.0
 name:               horizon-gen-nix
-version:            0.3.1.0
+version:            0.4.0
 synopsis:           Generate nix expressions from horizon-spec definitions
 description:        Generate nix expressions from horizon-spec definitions
 category:           Package Management, Nix
@@ -25,9 +25,6 @@
     Horizon.Gen.Nix.Options
     Horizon.Gen.Nix.Pretty
     Horizon.Gen.Nix.Types.HorizonMode
-    Horizon.Gen.Nix.Types.OverlayFile
-    Horizon.Gen.Nix.Types.PackagesDirectory
-    Horizon.Gen.Nix.Types.PackageSetFile
     Horizon.Gen.Nix.Writers
 
   hs-source-dirs:     src
@@ -52,7 +49,7 @@
     , directory
     , distribution-nixpkgs
     , either
-    , horizon-spec          >=0.3  && <0.4
+    , horizon-spec          >=0.4  && <0.5
     , language-nix
     , lens
     , optparse-applicative
diff --git a/src/Horizon/Gen/Nix.hs b/src/Horizon/Gen/Nix.hs
--- a/src/Horizon/Gen/Nix.hs
+++ b/src/Horizon/Gen/Nix.hs
@@ -6,49 +6,40 @@
   , makeOverlay
   ) where
 
-import           Dhall                                   (auto, inputFile)
-import           Horizon.Gen.Nix.Options                 (HorizonCommand (MakePackageSetCommand, OverlayCommand),
-                                                          HorizonOptions (MkHorizonOptions),
-                                                          MakePackageSetOptions,
-                                                          OverlayOptions,
-                                                          fromInputFile,
-                                                          horizonGenNixOptsInfo,
-                                                          optHorizonCommand,
-                                                          optInputFile,
-                                                          optOverlayFile,
-                                                          optPackageSetFile,
-                                                          optPackagesDirectory)
-import           Horizon.Gen.Nix.Types.PackagesDirectory (PackagesDirectory)
-import           Horizon.Gen.Nix.Writers                 (writeHaskellPackages,
-                                                          writeMakePackageSet,
-                                                          writeOverlay)
-import           Horizon.Spec                            (Overlay, PackageSet,
-                                                          fromOverlay, packages)
-import           Options.Applicative                     (execParser)
-import           Path                                    (toFilePath)
-import           Path.Dhall                              ()
+import           Dhall                   (auto, inputFile)
+import           Horizon.Gen.Nix.Options (HorizonOptions (MkHorizonOptions),
+                                          fromInputFile, horizonGenNixOptsInfo,
+                                          optInputFile)
+import           Horizon.Gen.Nix.Writers (writeHaskellPackages,
+                                          writeMakePackageSet, writeOverlay)
+import           Horizon.Spec            (HorizonExport (MakeOverlay, MakePackageSet),
+                                          OverlayExportSettings (MkOverlayExportSettings),
+                                          PackageSetExportSettings (MkPackageSetExportSettings),
+                                          fromOverlay, packages)
+import           Options.Applicative     (execParser)
+import           Path                    (toFilePath)
+import           Path.Dhall              ()
 
 
-makeMakePackageSet :: MakePackageSetOptions -> PackagesDirectory -> PackageSet -> IO ()
-makeMakePackageSet opts d xs = do
+makeMakePackageSet :: PackageSetExportSettings -> IO ()
+makeMakePackageSet (MkPackageSetExportSettings d f xs) = do
   writeHaskellPackages d (packages xs)
-  writeMakePackageSet d (optPackageSetFile opts) xs
+  writeMakePackageSet d f xs
 
-makeOverlay :: OverlayOptions -> PackagesDirectory -> Overlay -> IO ()
-makeOverlay opts d xs = do
+makeOverlay :: OverlayExportSettings -> IO ()
+makeOverlay (MkOverlayExportSettings d f xs) = do
   writeHaskellPackages d (fromOverlay xs)
-  writeOverlay d (optOverlayFile opts) xs
+  writeOverlay d f xs
 
+processHorizonExport :: HorizonExport -> IO ()
+processHorizonExport (MakePackageSet settings) = makeMakePackageSet settings
+processHorizonExport (MakeOverlay settings)    = makeOverlay settings
+
 horizonGenNix :: HorizonOptions -> IO ()
-horizonGenNix MkHorizonOptions{..} =
+horizonGenNix MkHorizonOptions{..} = do
   let fp = toFilePath . fromInputFile $ optInputFile
-  in case optHorizonCommand of
-    MakePackageSetCommand opts -> do
-      x <- inputFile @PackageSet auto fp
-      makeMakePackageSet opts optPackagesDirectory x
-    OverlayCommand opts -> do
-      x <- inputFile @Overlay auto fp
-      makeOverlay opts optPackagesDirectory x
+  x <- inputFile @HorizonExport auto fp
+  processHorizonExport x
 
 main :: IO ()
 main = do
diff --git a/src/Horizon/Gen/Nix/Options.hs b/src/Horizon/Gen/Nix/Options.hs
--- a/src/Horizon/Gen/Nix/Options.hs
+++ b/src/Horizon/Gen/Nix/Options.hs
@@ -5,83 +5,19 @@
   ( horizonGenNixOpts
   , horizonGenNixOptsInfo
   , InputFile (..)
-  , HorizonCommand (..)
   , HorizonOptions (..)
-  , MakePackageSetOptions (..)
-  , OverlayOptions (..)
-  , defaultMakePackageSetOptions
-  , defaultPackagesDirectory
-  , defaultPackageSetFile
-  , defaultOverlayFile
-  , defaultOverlayOptions
   ,   ) where
 
-import           Data.Either.Combinators                 (mapLeft)
-import           Data.Kind                               (Type)
-import           Horizon.Gen.Nix.Types.OverlayFile       (OverlayFile (MkOverlayFile))
-import           Horizon.Gen.Nix.Types.PackagesDirectory (PackagesDirectory (MkPackagesDirectory))
-import           Horizon.Gen.Nix.Types.PackageSetFile    (PackageSetFile (MkPackageSetFile))
-import           Options.Applicative                     (Parser, ParserInfo,
-                                                          ReadM, command,
-                                                          eitherReader, help,
-                                                          helper, info, long,
-                                                          metavar, option,
-                                                          progDesc, subparser,
-                                                          value)
-import           Path                                    (File, Path, Rel,
-                                                          mkRelDir, mkRelFile,
-                                                          parseRelDir,
-                                                          parseRelFile)
-import           Path.Dhall                              ()
-
-
-parsePackagesDirectory :: ReadM PackagesDirectory
-parsePackagesDirectory = eitherReader $ mapLeft show . fmap MkPackagesDirectory . parseRelDir
-
-defaultPackagesDirectory :: PackagesDirectory
-defaultPackagesDirectory = MkPackagesDirectory $(mkRelDir "pkgs")
-
-packagesDirectoryOption :: Parser PackagesDirectory
-packagesDirectoryOption =
-  option parsePackagesDirectory
-    (  long "packages-dir"
-    <> metavar "PACKAGES_DIR"
-    <> value defaultPackagesDirectory
-    <> help "The directory to put haskell packages."
-    )
-
-
-parsePackageSetFile :: ReadM PackageSetFile
-parsePackageSetFile = eitherReader $ mapLeft show . fmap MkPackageSetFile . parseRelFile
-
-defaultPackageSetFile :: PackageSetFile
-defaultPackageSetFile = MkPackageSetFile $(mkRelFile "initial-packages.nix")
-
-packageSetFileOption :: Parser PackageSetFile
-packageSetFileOption =
-  option parsePackageSetFile
-    (  long "packageset-file"
-    <> metavar "PACKAGESET_FILE"
-    <> value defaultPackageSetFile
-    <> help "The name of the package set file"
-    )
+import           Data.Either.Combinators (mapLeft)
+import           Data.Kind               (Type)
+import           Options.Applicative     (Parser, ParserInfo, ReadM,
+                                          eitherReader, help, helper, info,
+                                          long, metavar, option, value)
+import           Path                    (File, Path, Rel, mkRelFile,
+                                          parseRelFile)
+import           Path.Dhall              ()
 
 
-parseOverlayFile :: ReadM OverlayFile
-parseOverlayFile = eitherReader $ mapLeft show . fmap MkOverlayFile . parseRelFile
-
-defaultOverlayFile :: OverlayFile
-defaultOverlayFile = MkOverlayFile $(mkRelFile "overlay.nix")
-
-overlayFileOption :: Parser OverlayFile
-overlayFileOption =
-  option parseOverlayFile
-    (  long "overlay-file"
-    <> metavar "OVERLAY_FILE"
-    <> value defaultOverlayFile
-    <> help "The name of the overlay file."
-    )
-
 type InputFile :: Type
 newtype InputFile where
   MkInputFile :: { fromInputFile :: Path Rel File }
@@ -104,67 +40,15 @@
     )
 
 
-type MakePackageSetOptions :: Type
-data MakePackageSetOptions where
-  MkMakePackageSetOptions :: { optPackageSetFile :: PackageSetFile }
-                          -> MakePackageSetOptions
-  deriving stock (Eq, Show)
-
-makePackageSetOptions :: Parser MakePackageSetOptions
-makePackageSetOptions =
-      MkMakePackageSetOptions
-  <$> packageSetFileOption
-
-defaultMakePackageSetOptions :: MakePackageSetOptions
-defaultMakePackageSetOptions = MkMakePackageSetOptions defaultPackageSetFile
-
-
-type OverlayOptions :: Type
-data OverlayOptions where
-  MkOverlayOptions :: { optOverlayFile :: OverlayFile}
-                   -> OverlayOptions
-  deriving stock (Eq, Show)
-
-overlayOptions :: Parser OverlayOptions
-overlayOptions =
-      MkOverlayOptions
-  <$> overlayFileOption
-
-defaultOverlayOptions :: OverlayOptions
-defaultOverlayOptions = MkOverlayOptions defaultOverlayFile
-
-
-type HorizonCommand :: Type
-data HorizonCommand where
-  MakePackageSetCommand :: MakePackageSetOptions -> HorizonCommand
-  OverlayCommand :: OverlayOptions -> HorizonCommand
-  deriving stock (Eq, Show)
-
 type HorizonOptions :: Type
 data HorizonOptions where
-  MkHorizonOptions :: { optInputFile :: InputFile
-                      , optPackagesDirectory :: PackagesDirectory
-                      , optHorizonCommand :: HorizonCommand} -> HorizonOptions
+  MkHorizonOptions :: { optInputFile :: InputFile } -> HorizonOptions
   deriving stock (Eq, Show)
 
-makePackageSetCommand :: Parser HorizonCommand
-makePackageSetCommand = fmap MakePackageSetCommand makePackageSetOptions
-
-overlayCommand :: Parser HorizonCommand
-overlayCommand = fmap OverlayCommand overlayOptions
-
-horizonCommandOpts :: Parser HorizonCommand
-horizonCommandOpts = subparser
-  ( command "make-package-set" (info (helper <*> makePackageSetCommand) ( progDesc "Run in MakePackageSet Mode" ))
- <> command "overlay" (info (helper <*> overlayCommand) ( progDesc "Run in Overlay Mode" ))
-  )
-
 horizonGenNixOpts :: Parser HorizonOptions
 horizonGenNixOpts =
       MkHorizonOptions
   <$> inputFileOption
-  <*> packagesDirectoryOption
-  <*> horizonCommandOpts
 
 horizonGenNixOptsInfo :: ParserInfo HorizonOptions
 horizonGenNixOptsInfo = info (helper <*> horizonGenNixOpts) mempty
diff --git a/src/Horizon/Gen/Nix/Types/OverlayFile.hs b/src/Horizon/Gen/Nix/Types/OverlayFile.hs
deleted file mode 100644
--- a/src/Horizon/Gen/Nix/Types/OverlayFile.hs
+++ /dev/null
@@ -1,10 +0,0 @@
-module Horizon.Gen.Nix.Types.OverlayFile (OverlayFile(MkOverlayFile), fromOverlayFile) where
-
-import           Data.Kind (Type)
-import           Path      (File, Path, Rel)
-
-
-type OverlayFile :: Type
-data OverlayFile where
-  MkOverlayFile :: { fromOverlayFile :: Path Rel File } -> OverlayFile
-  deriving stock (Show, Eq)
diff --git a/src/Horizon/Gen/Nix/Types/PackageSetFile.hs b/src/Horizon/Gen/Nix/Types/PackageSetFile.hs
deleted file mode 100644
--- a/src/Horizon/Gen/Nix/Types/PackageSetFile.hs
+++ /dev/null
@@ -1,10 +0,0 @@
-module Horizon.Gen.Nix.Types.PackageSetFile (PackageSetFile(MkPackageSetFile), fromPackageSetFile) where
-
-import           Data.Kind (Type)
-import           Path      (File, Path, Rel)
-
-
-type PackageSetFile :: Type
-data PackageSetFile where
-  MkPackageSetFile :: { fromPackageSetFile :: Path Rel File } -> PackageSetFile
-  deriving stock (Show, Eq)
diff --git a/src/Horizon/Gen/Nix/Types/PackagesDirectory.hs b/src/Horizon/Gen/Nix/Types/PackagesDirectory.hs
deleted file mode 100644
--- a/src/Horizon/Gen/Nix/Types/PackagesDirectory.hs
+++ /dev/null
@@ -1,10 +0,0 @@
-module Horizon.Gen.Nix.Types.PackagesDirectory (PackagesDirectory(MkPackagesDirectory), fromPackagesDirectory) where
-
-import           Data.Kind (Type)
-import           Path      (Dir, Path, Rel)
-
-
-type PackagesDirectory :: Type
-data PackagesDirectory where
-  MkPackagesDirectory :: { fromPackagesDirectory :: Path Rel Dir } -> PackagesDirectory
-  deriving stock (Show, Eq)
diff --git a/src/Horizon/Gen/Nix/Writers.hs b/src/Horizon/Gen/Nix/Writers.hs
--- a/src/Horizon/Gen/Nix/Writers.hs
+++ b/src/Horizon/Gen/Nix/Writers.hs
@@ -15,14 +15,14 @@
 import           Distribution.Nixpkgs.Haskell.Derivation (Derivation)
 import           Horizon.Gen.Nix.Cabal2Nix.Options       (haskellPackageToCabal2NixOptions)
 import           Horizon.Gen.Nix.Pretty                  (prettyDerivation)
-import           Horizon.Gen.Nix.Types.OverlayFile       (OverlayFile (MkOverlayFile))
-import           Horizon.Gen.Nix.Types.PackagesDirectory (PackagesDirectory (MkPackagesDirectory))
-import           Horizon.Gen.Nix.Types.PackageSetFile    (PackageSetFile (MkPackageSetFile))
 import           Horizon.Spec                            (HaskellPackage,
                                                           Name (MkName),
                                                           Overlay (MkOverlay),
+                                                          OverlayFile (MkOverlayFile),
                                                           PackageList (MkPackageList),
                                                           PackageSet (MkPackageSet),
+                                                          PackageSetFile (MkPackageSetFile),
+                                                          PackagesDir (MkPackagesDir),
                                                           fromName,
                                                           fromPackageList)
 import           Path                                    (File, Path,
@@ -38,8 +38,8 @@
 import           Text.PrettyPrint.HughesPJClass          (render)
 
 
-writeOverlay :: PackagesDirectory -> OverlayFile -> Overlay -> IO ()
-writeOverlay (MkPackagesDirectory d) (MkOverlayFile f) (MkOverlay (MkPackageList xs)) = withFile (toFilePath f) WriteMode $ \h -> do
+writeOverlay :: PackagesDir -> OverlayFile -> Overlay -> IO ()
+writeOverlay (MkPackagesDir d) (MkOverlayFile f) (MkOverlay (MkPackageList xs)) = withFile (toFilePath f) WriteMode $ \h -> do
   hPutStrLn h "{ pkgs, ... }:"
   hPutStrLn h ""
   hPutStrLn h "final: prev: with pkgs.haskell.lib; {"
@@ -49,8 +49,8 @@
     hPutStrLn h ""
   hPutStrLn h "}"
 
-writeMakePackageSet :: PackagesDirectory -> PackageSetFile -> PackageSet -> IO ()
-writeMakePackageSet (MkPackagesDirectory d) (MkPackageSetFile f) (MkPackageSet _ (MkPackageList xs)) = withFile (toFilePath f) WriteMode $ \h -> do
+writeMakePackageSet :: PackagesDir -> PackageSetFile -> PackageSet -> IO ()
+writeMakePackageSet (MkPackagesDir d) (MkPackageSetFile f) (MkPackageSet _ (MkPackageList xs)) = withFile (toFilePath f) WriteMode $ \h -> do
   hPutStrLn h "{ pkgs, lib, callPackage, ... }:"
   hPutStrLn h ""
   hPutStrLn h "self: with pkgs.haskell.lib; {"
@@ -66,8 +66,8 @@
 writeDerivation :: Path b File -> Derivation -> IO ()
 writeDerivation f = writeFile (toFilePath f) . show . prettyDerivation
 
-writeHaskellPackage :: PackagesDirectory -> Name -> HaskellPackage -> IO ()
-writeHaskellPackage (MkPackagesDirectory d) (MkName f) y = do
+writeHaskellPackage :: PackagesDir -> Name -> HaskellPackage -> IO ()
+writeHaskellPackage (MkPackagesDir d) (MkName f) y = do
   let o = haskellPackageToCabal2NixOptions y
   createDirectoryIfMissing True (toFilePath d)
   f' <- parseRelFile  $ T.unpack (f <> ".nix")
@@ -75,5 +75,5 @@
   q  <- doesFileExist $ toFilePath j
   unless q $ writeCabal2Nix j o
 
-writeHaskellPackages :: PackagesDirectory -> PackageList -> IO ()
+writeHaskellPackages :: PackagesDir -> PackageList -> IO ()
 writeHaskellPackages d = mapM_ (uncurry $ writeHaskellPackage d) . toList . fromPackageList
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -5,14 +5,8 @@
 import           Control.Exception       (bracket_)
 import           Control.Monad           (forM_)
 import           Horizon.Gen.Nix         (horizonGenNix)
-import           Horizon.Gen.Nix.Options (HorizonCommand (MakePackageSetCommand, OverlayCommand),
-                                          HorizonOptions (MkHorizonOptions),
-                                          InputFile (MkInputFile),
-                                          defaultMakePackageSetOptions,
-                                          defaultOverlayOptions,
-                                          defaultPackagesDirectory,
-                                          optHorizonCommand, optInputFile,
-                                          optPackagesDirectory)
+import           Horizon.Gen.Nix.Options (HorizonOptions (MkHorizonOptions),
+                                          InputFile (MkInputFile), optInputFile)
 import           Path                    (File, Path, Rel, mkRelFile,
                                           parseRelFile, toFilePath)
 import           System.Directory        (removeFile)
@@ -39,19 +33,15 @@
   , $(mkRelFile "pkgs/myPackage.nix")
   ]
 
-runHorizonGenNixFor :: FilePath -> HorizonCommand -> IO ()
-runHorizonGenNixFor s cmd = do
+runHorizonGenNixFor :: FilePath -> IO ()
+runHorizonGenNixFor s = do
     fp <- parseRelFile $ "test/data/" ++ s ++ "/input.dhall"
-    let opts = MkHorizonOptions
-                 { optHorizonCommand = cmd
-                 , optPackagesDirectory = defaultPackagesDirectory
-                 , optInputFile = MkInputFile fp
-                 }
+    let opts = MkHorizonOptions { optInputFile = MkInputFile fp }
     horizonGenNix opts
 
-expectedOutputTest :: FilePath -> [Path Rel File] -> HorizonCommand -> Spec
-expectedOutputTest s xs cmd = describe s $ sequential $
-  aroundAll_ (bracket_ (runHorizonGenNixFor s cmd) (mapM_ (removeFile . toFilePath) xs)) $ forM_ xs $ \x ->
+expectedOutputTest :: FilePath -> [Path Rel File] -> Spec
+expectedOutputTest s xs = describe s $ sequential $
+  aroundAll_ (bracket_ (runHorizonGenNixFor s) (mapM_ (removeFile . toFilePath) xs)) $ forM_ xs $ \x ->
     it (toFilePath x) $
       goldenStringFile
         ("test/data/" ++ s ++ "/output/" ++ toFilePath x ++ ".golden")
@@ -59,7 +49,7 @@
 
 main :: IO ()
 main = sydTest $ doNotRandomiseExecutionOrder $ sequential $ do
-  expectedOutputTest "sample-package-set" outputFilesPackageSetRel (MakePackageSetCommand defaultMakePackageSetOptions)
-  expectedOutputTest "modified-package-set" outputFilesPackageSetRel (MakePackageSetCommand defaultMakePackageSetOptions)
-  expectedOutputTest "sample-overlay" outputFilesOverlayRel (OverlayCommand defaultOverlayOptions)
-  expectedOutputTest "modified-overlay" outputFilesOverlayRel (OverlayCommand defaultOverlayOptions)
+  expectedOutputTest "sample-package-set" outputFilesPackageSetRel
+  expectedOutputTest "modified-package-set" outputFilesPackageSetRel
+  expectedOutputTest "sample-overlay" outputFilesOverlayRel
+  expectedOutputTest "modified-overlay" outputFilesOverlayRel
