diff --git a/README.md b/README.md
deleted file mode 100644
--- a/README.md
+++ /dev/null
@@ -1,192 +0,0 @@
-# hpack: An alternative format for Haskell packages
-
-## Examples
-
- * Given this [package.yaml](https://github.com/sol/hpack/blob/master/package.yaml) running `hpack` will generate [hpack.cabal](https://github.com/sol/hpack/blob/master/hpack.cabal)
- * Given this [package.yaml](https://github.com/zalora/getopt-generics/blob/master/package.yaml) running `hpack` will generate [getopt-generics.cabal](https://github.com/zalora/getopt-generics/blob/master/getopt-generics.cabal)
- * Given this [package.yaml](https://github.com/hspec/sensei/blob/master/package.yaml) running `hpack` will generate [sensei.cabal](https://github.com/hspec/sensei/blob/master/sensei.cabal)
- * Given this [package.yaml](https://github.com/haskell-compat/base-orphans/blob/master/package.yaml) running `hpack` will generate [base-orphans.cabal](https://github.com/haskell-compat/base-orphans/blob/master/base-orphans.cabal)
-
-## Documentation
-
-### Getting started
-
-One easy way of getting started is to use
-[hpack-convert](http://hackage.haskell.org/package/hpack-convert) to convert an
-existing cabal file into a `package.yaml`.
-
-### Quick-reference
-
-#### Top-level fields
-
-| Hpack | Cabal | Default | Notes | Example |
-| --- | --- | --- | --- | --- |
-| `name` | `name` | | | |
-| `version` | `version` | `0.0.0` | | |
-| `synopsis` | `synopsis` | | | |
-| `description` | `description` | | | |
-| `category` | `category` | | | |
-| `stability` | `stability` | | | |
-| `homepage` | `homepage` | If `github` given, `<repo>#readme` | | |
-| `bug-reports` | `bug-reports` | If `github` given, `<repo>/issues` | | |
-| `author` | `author` | | May be a list | |
-| `maintainer` | `maintainer` | | May be a list | |
-| `copyright` | `copyright` | | May be a list |
-| `license` | `license` | | | |
-| `license-file` | `license-file` | `LICENSE` if file exists | | |
-| `tested-with` | `tested-with` | | | |
-| `build-type` | `build-type` | `Simple` | Must be `Simple`, `Configure`, `Make`, or `Custom` | |
-| | `cabal-version` | `>= 1.10` or `>= 1.21` | `>= 1.21` if library component has `reexported-modules` field | |
-| `extra-source-files` | `extra-source-files` | | Accepts [glob patterns](#file-globbing) | |
-| `data-files` | `data-files` | | Accepts [glob patterns](#file-globbing) | |
-| `github` | `source-repository head` | | Accepts `user/repo` or `user/repo/subdir` | `github: foo/bar`
-| `git`    | `source-repository head` | | No effect if `github` given | `git: https://my.repo.com/foo` |
-| `flags`  | `flag <name>` | | Map from flag name to flag (see [Flags](#flags)) | |
-| `library` | `library` | | See [Library fields](#library-fields) | |
-| `executables` | `executable <name>` | | Map from executable name to executable (see [Executable fields](#executable-fields)) | |
-| `tests` | `test-suite <name>` | | Map from test name to test (see [Test fields](#test-fields)) | |
-| `benchmarks` | `benchmark <name>` | | Map from benchmark name to benchmark (see [Benchmark fields](#benchmark-fields)) | |
-
-#### Global top-level fields
-
-These fields are merged with all library, executable, test, and benchmark components.
-
-| Hpack | Cabal | Default | Notes |
-| --- | --- | --- | --- |
-| `source-dirs` | `hs-source-dirs` | | |
-| `default-extensions` | `default-extensions` | | |
-| `other-extension` | `other-extensions` | | |
-| `ghc-options` | `ghc-options` | | |
-| `ghc-prof-options` | `ghc-prof-options` | | |
-| `cpp-options` | `cpp-options` | | |
-| `cc-options` | `cc-options` | | |
-| `c-sources` | `c-sources` | | |
-| `extra-lib-dirs` | `extra-lib-dirs` | | |
-| `extra-libraries` | `extra-libraries` | | |
-| `include-dirs` | `include-dirs` | | |
-| `install-includes` | `install-includes` | | |
-| `ld-options` | `ld-options` | | |
-| `buildable` | `buildable` | | May be overridden by later stanza |
-| `dependencies` | `build-depends` | | |
-| `build-tools` | `build-tools` | | |
-| `when` | | | Accepts a list of conditionals (see [Conditionals](#conditionals)) |
-
-#### <a name="library-fields"></a>Library fields
-
-| Hpack | Cabal | Default | Notes |
-| --- | --- | --- | --- |
-| `exposed` | `exposed` | | |
-| `exposed-modules` | `exposed-modules` | All modules in `source-dirs` less `other-modules` | |
-| `other-modules` | `other-modules` | All modules in `source-dirs` less `exposed-modules` | |
-| `reexported-modules` | `reexported-modules` | | |
-| | `default-language` | `Haskell2010` | |
-
-#### <a name="executable-fields"></a>Executable fields
-
-| Hpack | Cabal | Default | Notes |
-| --- | --- | --- | --- |
-| `main` | `main-is` | | |
-| `other-modules` | `other-modules` | | |
-| | `default-language` | `Haskell2010` | |
-
-#### <a name="test-fields"></a>Test fields
-
-| Hpack | Cabal | Default | Notes |
-| --- | --- | --- | --- |
-| | `type` | `exitcode-stdio-1.0` | |
-| `main` | `main-is` | | |
-| `other-modules` | `other-modules` | | |
-| | `default-language` | `Haskell2010` | |
-
-#### <a name="benchmark-fields"></a>Benchmark fields
-
-| Hpack | Cabal | Default | Notes |
-| --- | --- | --- | --- |
-| | `type` | `exitcode-stdio-1.0` | |
-| `main` | `main-is` | | |
-| `other-modules` | `other-modules` | | |
-| | `default-language` | `Haskell2010` | |
-
-#### <a name="flags"></a>Flags
-
-| Hpack | Cabal | Default | Notes |
-| --- | --- | --- | --- |
-| `description` | `description` | | Optional |
-| `manual` | `manual` | | Required (unlike Cabal) |
-| `default` | `default` | | Required (unlike Cabal) |
-
-#### <a name="conditionals"></a> Conditionals
-
-Conditionals with no else branch:
-
-- Must have a `condition` field
-- May have any number of other fields
-
-For example,
-
-    when:
-      - condition: os(darwin)
-        extra-lib-dirs: lib/darwin
-
-becomes
-
-    if os(darwin)
-      extra-lib-dirs:
-        lib/darwin
-
-Conditionals with an else branch:
-
-- Must have a `condition` field
-- Must have a `then` field, itself an object containing any number of other fields
-- Must have a `else` field, itself an object containing any number of other fields
-- All other top-level fields are ignored
-
-For example,
-
-    when:
-      - condition: flag(fast)
-        then:
-          ghc-options: -O2
-        else:
-          ghc-options: -O0
-
-becomes
-
-    if flag(fast)
-      ghc-options: -O2
-    else
-      ghc-options: -O0
-
-
-### <a name="file-globbing"></a>File globbing
-
-At place where you can specify a list of files you can also use glob patterns.
-Glob patters and ordinary file names can be freely mixed, e.g.:
-
-```yaml
-extra-source-files:
-  - static/*.js
-  - static/site.css
-```
-
-Glob patterns are expanded according to the following rules:
-
- - `?` and `*` are expanded according to POSIX (they match arbitrary
-   characters, except for directory separators)
- - `**` is expanded in a `zsh`-like fashion (matching across directory
-   separators)
- - `?`, `*` and `**` do not match a `.` at the beginning of a file/directory
-
-### Slides
-
- - Slides from my talk about `hpack` at the Singapore Haskell meetup:
-   http://typeful.net/talks/hpack
-
-## Vim integration
-
-To run `hpack` automatically on modifications to `package.yaml` add the
-following to your `~/.vimrc`:
-
-```vim
-autocmd BufWritePost package.yaml silent !hpack --silent
-```
diff --git a/hpack.cabal b/hpack.cabal
--- a/hpack.cabal
+++ b/hpack.cabal
@@ -3,8 +3,9 @@
 -- see: https://github.com/sol/hpack
 
 name:           hpack
-version:        0.16.0
+version:        0.17.0
 synopsis:       An alternative format for Haskell packages
+description:    See README at <https://github.com/sol/hpack#readme>
 category:       Development
 homepage:       https://github.com/sol/hpack#readme
 bug-reports:    https://github.com/sol/hpack/issues
@@ -14,9 +15,6 @@
 build-type:     Simple
 cabal-version:  >= 1.10
 
-extra-source-files:
-    README.md
-
 source-repository head
   type: git
   location: https://github.com/sol/hpack
@@ -78,7 +76,7 @@
   main-is: Spec.hs
   hs-source-dirs:
       test
-      src
+    , src
   ghc-options: -Wall
   cpp-options: -DTEST
   build-depends:
diff --git a/src/Hpack/Config.hs b/src/Hpack/Config.hs
--- a/src/Hpack/Config.hs
+++ b/src/Hpack/Config.hs
@@ -24,6 +24,7 @@
 , GitUrl
 , GitRef
 , GhcOption
+, CustomSetup(..)
 , Section(..)
 , Library(..)
 , Executable(..)
@@ -48,7 +49,7 @@
 import           Data.Map.Lazy (Map)
 import qualified Data.Map.Lazy as Map
 import qualified Data.HashMap.Lazy as HashMap
-import           Data.List.Compat (nub, (\\), sortBy)
+import           Data.List.Compat (nub, (\\), sortBy, isPrefixOf)
 import           Data.Maybe
 import           Data.Ord
 import           Data.String
@@ -65,7 +66,32 @@
 import           Hpack.Yaml
 
 package :: String -> String -> Package
-package name version = Package name version Nothing Nothing Nothing Nothing Nothing Nothing [] [] [] Simple Nothing Nothing Nothing [] [] [] Nothing Nothing [] [] []
+package name version = Package {
+    packageName = name
+  , packageVersion = version
+  , packageSynopsis = Nothing
+  , packageDescription = Nothing
+  , packageHomepage = Nothing
+  , packageBugReports = Nothing
+  , packageCategory = Nothing
+  , packageStability = Nothing
+  , packageAuthor = []
+  , packageMaintainer = []
+  , packageCopyright = []
+  , packageBuildType = Simple
+  , packageLicense = Nothing
+  , packageLicenseFile = Nothing
+  , packageTestedWith = Nothing
+  , packageFlags = []
+  , packageExtraSourceFiles = []
+  , packageDataFiles = []
+  , packageSourceRepository = Nothing
+  , packageCustomSetup = Nothing
+  , packageLibrary = Nothing
+  , packageExecutables = []
+  , packageTests = []
+  , packageBenchmarks = []
+  }
 
 renamePackage :: String -> Package -> Package
 renamePackage name p@Package{..} = p {
@@ -128,6 +154,9 @@
   default fieldNames :: (HasTypeName a, Selectors (Rep a)) => Proxy a -> [String]
   fieldNames proxy = map (hyphenize $ typeName proxy) (selectors proxy)
 
+  ignoreUnderscoredUnknownFields :: Proxy a -> Bool
+  ignoreUnderscoredUnknownFields _ = False
+
 data CaptureUnknownFields a = CaptureUnknownFields {
   captureUnknownFieldsFields :: [FieldName]
 , captureUnknownFieldsValue :: a
@@ -145,18 +174,33 @@
     where
       unknownSectionFields = getUnknownFields v (Proxy :: Proxy (Section a))
 
+instance FromJSON (CaptureUnknownFields CustomSetupSection) where
+  parseJSON = captureUnknownFields
+
 instance FromJSON (CaptureUnknownFields FlagSection) where
   parseJSON = captureUnknownFields
 
 getUnknownFields :: forall a. HasFieldNames a => Value -> Proxy a -> [FieldName]
 getUnknownFields v _ = case v of
-  Object o -> unknown
+  Object o -> ignoreUnderscored unknown
     where
       unknown = keys \\ fields
       keys = map T.unpack (HashMap.keys o)
       fields = fieldNames (Proxy :: Proxy a)
+      ignoreUnderscored
+        | ignoreUnderscoredUnknownFields (Proxy :: Proxy a) = filter (not . isPrefixOf "_")
+        | otherwise = id
   _ -> []
 
+data CustomSetupSection = CustomSetupSection {
+  customSetupSectionDependencies :: Maybe (List Dependency)
+} deriving (Eq, Show, Generic)
+
+instance HasFieldNames CustomSetupSection
+
+instance FromJSON CustomSetupSection where
+  parseJSON = genericParseJSON_
+
 data LibrarySection = LibrarySection {
   librarySectionExposed :: Maybe Bool
 , librarySectionExposedModules :: Maybe (List String)
@@ -285,13 +329,15 @@
 , packageConfigDataFiles :: Maybe (List FilePath)
 , packageConfigGithub :: Maybe Text
 , packageConfigGit :: Maybe String
+, packageConfigCustomSetup :: Maybe (CaptureUnknownFields CustomSetupSection)
 , packageConfigLibrary :: Maybe (CaptureUnknownFields (Section LibrarySection))
 , packageConfigExecutables :: Maybe (Map String (CaptureUnknownFields (Section ExecutableSection)))
 , packageConfigTests :: Maybe (Map String (CaptureUnknownFields (Section ExecutableSection)))
 , packageConfigBenchmarks :: Maybe (Map String (CaptureUnknownFields (Section ExecutableSection)))
 } deriving (Eq, Show, Generic)
 
-instance HasFieldNames PackageConfig
+instance HasFieldNames PackageConfig where
+  ignoreUnderscoredUnknownFields _ = True
 
 instance FromJSON PackageConfig where
   parseJSON value = handleNullValues <$> genericParseJSON_ value
@@ -385,12 +431,17 @@
 , packageExtraSourceFiles :: [FilePath]
 , packageDataFiles :: [FilePath]
 , packageSourceRepository :: Maybe SourceRepository
+, packageCustomSetup :: Maybe CustomSetup
 , packageLibrary :: Maybe (Section Library)
 , packageExecutables :: [Section Executable]
 , packageTests :: [Section Executable]
 , packageBenchmarks :: [Section Executable]
 } deriving (Eq, Show)
 
+data CustomSetup = CustomSetup {
+  customSetupDependencies :: [Dependency]
+} deriving (Eq, Show)
+
 data Library = Library {
   libraryExposed :: Maybe Bool
 , libraryExposedModules :: [String]
@@ -433,6 +484,7 @@
 
 instance HasFieldNames a => HasFieldNames (Section a) where
   fieldNames Proxy = fieldNames (Proxy :: Proxy a) ++ fieldNames (Proxy :: Proxy CommonOptions)
+  ignoreUnderscoredUnknownFields _ = ignoreUnderscoredUnknownFields (Proxy :: Proxy a)
 
 data FlagSection = FlagSection {
   _flagSectionDescription :: Maybe String
@@ -463,12 +515,20 @@
 mkPackage :: FilePath -> (CaptureUnknownFields (Section PackageConfig)) -> IO ([String], Package)
 mkPackage dir (CaptureUnknownFields unknownFields globalOptions@Section{sectionData = PackageConfig{..}}) = do
   let
+    nameWarnings :: [String]
+    name :: String
     (nameWarnings, name) = maybe (["Package name not specified, inferred " ++ show inferredName], inferredName) ((,) []) packageConfigName
       where inferredName = takeBaseName dir
 
+    mCustomSetup :: Maybe CustomSetup
+    mCustomSetup = toCustomSetup <$> mCustomSetupSection
+
   libraryResult <- mapM (toLibrary dir name globalOptions) mLibrarySection
   let
+    mLibrary :: Maybe (Section Library)
     mLibrary = fmap snd libraryResult
+
+    libraryWarnings :: [String]
     libraryWarnings = maybe [] fst libraryResult
 
   (executablesWarnings, executables) <- toExecutables dir globalOptions (map (fmap captureUnknownFieldsValue) executableSections)
@@ -490,7 +550,10 @@
   (dataFilesWarnings, dataFiles) <-
     expandGlobs "data-files" dir (fromMaybeList packageConfigDataFiles)
 
-  let pkg = Package {
+  let defaultBuildType :: BuildType
+      defaultBuildType = maybe Simple (const Custom) mCustomSetup
+
+      pkg = Package {
         packageName = name
       , packageVersion = fromMaybe "0.0.0" packageConfigVersion
       , packageSynopsis = packageConfigSynopsis
@@ -502,7 +565,7 @@
       , packageAuthor = fromMaybeList packageConfigAuthor
       , packageMaintainer = fromMaybeList packageConfigMaintainer
       , packageCopyright = fromMaybeList packageConfigCopyright
-      , packageBuildType = fromMaybe Simple packageConfigBuildType
+      , packageBuildType = fromMaybe defaultBuildType packageConfigBuildType
       , packageLicense = packageConfigLicense
       , packageLicenseFile = packageConfigLicenseFile <|> (guard licenseFileExists >> Just "LICENSE")
       , packageTestedWith = packageConfigTestedWith
@@ -510,6 +573,7 @@
       , packageExtraSourceFiles = extraSourceFiles
       , packageDataFiles = dataFiles
       , packageSourceRepository = sourceRepository
+      , packageCustomSetup = mCustomSetup
       , packageLibrary = mLibrary
       , packageExecutables = executables
       , packageTests = tests
@@ -520,6 +584,7 @@
            formatUnknownFields "package description" unknownFields
         ++ nameWarnings
         ++ flagWarnings
+        ++ maybe [] (formatUnknownFields "custom-setup section") (captureUnknownFieldsFields <$> packageConfigCustomSetup)
         ++ maybe [] (formatUnknownFields "library section") (captureUnknownFieldsFields <$> packageConfigLibrary)
         ++ formatUnknownSectionFields "executable" executableSections
         ++ formatUnknownSectionFields "test" testsSections
@@ -554,6 +619,9 @@
     toList :: Maybe (Map String a) -> [(String, a)]
     toList = Map.toList . fromMaybe mempty
 
+    mCustomSetupSection :: Maybe CustomSetupSection
+    mCustomSetupSection = captureUnknownFieldsValue <$> packageConfigCustomSetup
+
     mLibrarySection :: Maybe (Section LibrarySection)
     mLibrarySection = captureUnknownFieldsValue <$> packageConfigLibrary
 
@@ -602,6 +670,10 @@
 expandCSources dir sect@Section{..} = do
   (warnings, files) <- expandGlobs "c-sources" dir sectionCSources
   return (warnings, sect {sectionCSources = files})
+
+toCustomSetup :: CustomSetupSection -> CustomSetup
+toCustomSetup CustomSetupSection{..} = CustomSetup
+  { customSetupDependencies = fromMaybeList customSetupSectionDependencies }
 
 toLibrary :: FilePath -> String -> Section global -> Section LibrarySection -> IO ([String], Section Library)
 toLibrary dir name globalOptions library = traverse fromLibrarySection sect >>= expandCSources dir
diff --git a/src/Hpack/Run.hs b/src/Hpack/Run.hs
--- a/src/Hpack/Run.hs
+++ b/src/Hpack/Run.hs
@@ -68,8 +68,13 @@
     dataFiles :: Element
     dataFiles = Field "data-files" (LineSeparatedList packageDataFiles)
 
+    sourceRepository :: [Element]
     sourceRepository = maybe [] (return . renderSourceRepository) packageSourceRepository
 
+    customSetup :: [Element]
+    customSetup = maybe [] (return . renderCustomSetup) packageCustomSetup
+
+    library :: [Element]
     library = maybe [] (return . renderLibrary) packageLibrary
 
     stanzas :: [Element]
@@ -78,7 +83,8 @@
       : dataFiles
       : sourceRepository
       ++ concat [
-        map renderFlag packageFlags
+        customSetup
+      , map renderFlag packageFlags
       , library
       , renderExecutables packageExecutables
       , renderTests packageTests
@@ -189,6 +195,10 @@
     mainIs = Field "main-is" (Literal executableMain)
     otherModules = renderOtherModules executableOtherModules
 
+renderCustomSetup :: CustomSetup -> Element
+renderCustomSetup CustomSetup{..} =
+  Stanza "custom-setup" [renderSetupDepends customSetupDependencies]
+
 renderLibrary :: Section Library -> Element
 renderLibrary sect@(sectionData -> Library{..}) = Stanza "library" $
   renderSection sect ++
@@ -279,3 +289,6 @@
 
 renderBuildTools :: [Dependency] -> Element
 renderBuildTools = Field "build-tools" . CommaSeparatedList . map dependencyName
+
+renderSetupDepends :: [Dependency] -> Element
+renderSetupDepends = Field "setup-depends" . CommaSeparatedList . map dependencyName
diff --git a/src/Hpack/Yaml.hs b/src/Hpack/Yaml.hs
--- a/src/Hpack/Yaml.hs
+++ b/src/Hpack/Yaml.hs
@@ -1,7 +1,8 @@
 {-# LANGUAGE RecordWildCards #-}
 module Hpack.Yaml where
 
-import           Data.Yaml
+import           Data.Yaml hiding (decodeFile, decodeFileEither)
+import           Data.Yaml.Include
 
 decodeYaml :: FromJSON a => FilePath -> IO (Either String a)
 decodeYaml file = do
diff --git a/test/Hpack/ConfigSpec.hs b/test/Hpack/ConfigSpec.hs
--- a/test/Hpack/ConfigSpec.hs
+++ b/test/Hpack/ConfigSpec.hs
@@ -309,6 +309,7 @@
         name: foo
         bar: 23
         baz: 42
+        _qux: 66
         |]
         (`shouldBe` [
           "Ignoring unknown field \"bar\" in package description"
@@ -323,9 +324,11 @@
           - condition: impl(ghc)
             bar: 23
             baz: 42
+            _qux: 66
         |]
         (`shouldBe` [
-          "Ignoring unknown field \"bar\" in package description"
+          "Ignoring unknown field \"_qux\" in package description"
+        , "Ignoring unknown field \"bar\" in package description"
         , "Ignoring unknown field \"baz\" in package description"
         ]
         )
@@ -641,6 +644,56 @@
         , packageExecutables = [(section $ executable "foo" "Main.hs") {sectionBuildable = Just False}]
         }
         )
+
+    context "when reading custom-setup section" $ do
+      it "warns on unknown fields" $ do
+        withPackageWarnings_ [i|
+          name: foo
+          custom-setup:
+            foo: 1
+            bar: 2
+          |]
+          (`shouldBe` [
+            "Ignoring unknown field \"bar\" in custom-setup section"
+          , "Ignoring unknown field \"foo\" in custom-setup section"
+          ])
+
+      it "sets build-type: Custom, if missing" $ do
+        withPackageConfig_ [i|
+          custom-setup:
+            dependencies:
+              - base
+          |]
+          (packageBuildType >>> (`shouldBe` Custom))
+
+      it "leaves build-type alone, if it exists" $ do
+        withPackageConfig_ [i|
+          name: foo
+          build-type: Make
+          custom-setup:
+            dependencies:
+              - base
+          |]
+          (packageBuildType >>> (`shouldBe` Make))
+
+      it "accepts dependencies" $ do
+        withPackageConfig_ [i|
+          custom-setup:
+            dependencies:
+              - foo >1.0
+              - bar ==2.0
+          |]
+          (packageCustomSetup >>> fmap customSetupDependencies >>> (`shouldBe` Just ["foo >1.0", "bar ==2.0"]))
+
+    it "allows yaml merging and overriding fields" $ do
+      withPackageConfig_ [i|
+        _common: &common
+          name: n1
+
+        <<: *common
+        name: n2
+        |]
+        (packageName >>> (`shouldBe` "n2"))
 
     context "when reading library section" $ do
       it "warns on unknown fields" $ do
diff --git a/test/Hpack/RunSpec.hs b/test/Hpack/RunSpec.hs
--- a/test/Hpack/RunSpec.hs
+++ b/test/Hpack/RunSpec.hs
@@ -103,6 +103,22 @@
         , "  default-language: Haskell2010"
         ]
 
+    context "when rendering custom-setup section" $ do
+      it "includes setup-depends" $ do
+        let setup = CustomSetup
+              { customSetupDependencies = ["foo >1.0", "bar ==2.0"] }
+        renderPackage_ package {packageCustomSetup = Just setup} `shouldBe` unlines [
+            "name: foo"
+          , "version: 0.0.0"
+          , "build-type: Simple"
+          , "cabal-version: >= 1.10"
+          , ""
+          , "custom-setup"
+          , "  setup-depends:"
+          , "      foo >1.0"
+          , "    , bar ==2.0"
+          ]
+
     context "when rendering library section" $ do
       it "renders library section" $ do
         renderPackage_ package {packageLibrary = Just $ section library} `shouldBe` unlines [
