diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,11 @@
 # CHANGELOG
 
+- 0.9.4.0 (2019-10-19)
+    * Read language extensions from `.cabal` file (by Georgy Lukyanov)
+
+- 0.9.3.1 (2019-10-08)
+    * Fix CircleCI configuration
+
 - 0.9.3.0 (2019-10-08)
     * Bump `optparse-applicative` to 0.15
     * Don't remove page breaks in the trailing whitespace step (by Chris
diff --git a/data/stylish-haskell.yaml b/data/stylish-haskell.yaml
--- a/data/stylish-haskell.yaml
+++ b/data/stylish-haskell.yaml
@@ -241,3 +241,9 @@
 # language_extensions:
   # - TemplateHaskell
   # - QuasiQuotes
+
+# Attempt to find the cabal file in ancestors of the current directory, and
+# parse options (currently only language extensions) from that.
+#
+# Default: true
+cabal: true
diff --git a/lib/Language/Haskell/Stylish/Config.hs b/lib/Language/Haskell/Stylish/Config.hs
--- a/lib/Language/Haskell/Stylish/Config.hs
+++ b/lib/Language/Haskell/Stylish/Config.hs
@@ -17,22 +17,22 @@
 import qualified Data.Aeson.Types                                 as A
 import qualified Data.ByteString                                  as B
 import qualified Data.FileEmbed                                   as FileEmbed
-import           Data.List                                        (inits,
-                                                                   intercalate)
+import           Data.List                                        (intercalate,
+                                                                   nub)
 import           Data.Map                                         (Map)
 import qualified Data.Map                                         as M
 import           Data.Maybe                                       (fromMaybe)
 import           Data.Yaml                                        (decodeEither',
                                                                    prettyPrintParseException)
 import           System.Directory
-import           System.FilePath                                  (joinPath,
-                                                                   splitPath,
-                                                                   (</>))
+import           System.FilePath                                  ((</>))
 import qualified System.IO                                        as IO (Newline (..),
                                                                          nativeNewline)
 
 
 --------------------------------------------------------------------------------
+import qualified Language.Haskell.Stylish.Config.Cabal            as Cabal
+import           Language.Haskell.Stylish.Config.Internal
 import           Language.Haskell.Stylish.Step
 import qualified Language.Haskell.Stylish.Step.Imports            as Imports
 import qualified Language.Haskell.Stylish.Step.LanguagePragmas    as LanguagePragmas
@@ -54,6 +54,7 @@
     , configColumns            :: Int
     , configLanguageExtensions :: [String]
     , configNewline            :: IO.Newline
+    , configCabal              :: Bool
     }
 
 
@@ -79,24 +80,19 @@
     current    <- getCurrentDirectory
     configPath <- getXdgDirectory XdgConfig "stylish-haskell"
     home       <- getHomeDirectory
-    mbConfig   <- search $
+    mbConfig   <- search verbose $
         [d </> configFileName | d <- ancestors current] ++
         [configPath </> "config.yaml", home </> configFileName]
 
     return mbConfig
-  where
-    -- All ancestors of a dir (including that dir)
-    ancestors :: FilePath -> [FilePath]
-    ancestors = init . map joinPath . reverse . inits . splitPath
 
-    search :: [FilePath] -> IO (Maybe FilePath)
-    search []       = return Nothing
-    search (f : fs) = do
-        -- TODO Maybe catch an error here, dir might be unreadable
-        exists <- doesFileExist f
-        verbose $ f ++ if exists then " exists" else " does not exist"
-        if exists then return (Just f) else search fs
-
+search :: Verbose -> [FilePath] -> IO (Maybe FilePath)
+search _ []             = return Nothing
+search verbose (f : fs) = do
+    -- TODO Maybe catch an error here, dir might be unreadable
+    exists <- doesFileExist f
+    verbose $ f ++ if exists then " exists" else " does not exist"
+    if exists then return (Just f) else search verbose fs
 
 --------------------------------------------------------------------------------
 loadConfig :: Verbose -> Maybe FilePath -> IO Config
@@ -107,9 +103,17 @@
     case decodeEither' bytes of
         Left err     -> error $
             "Language.Haskell.Stylish.Config.loadConfig: " ++ prettyPrintParseException err
-        Right config -> return config
+        Right config -> do
+          cabalLanguageExtensions <- if configCabal config
+            then map show <$> Cabal.findLanguageExtensions verbose
+            else pure []
 
+          return $ config
+            { configLanguageExtensions = nub $
+                configLanguageExtensions config ++ cabalLanguageExtensions
+            }
 
+
 --------------------------------------------------------------------------------
 parseConfig :: A.Value -> A.Parser Config
 parseConfig (A.Object o) = do
@@ -119,6 +123,7 @@
         <*> (o A..:? "columns"             A..!= 80)
         <*> (o A..:? "language_extensions" A..!= [])
         <*> (o A..:? "newline"             >>= parseEnum newlines IO.nativeNewline)
+        <*> (o A..:? "cabal"               A..!= True)
 
     -- Then fill in the steps based on the partial config we already have
     stepValues <- o A..: "steps" :: A.Parser [A.Value]
diff --git a/lib/Language/Haskell/Stylish/Config/Cabal.hs b/lib/Language/Haskell/Stylish/Config/Cabal.hs
new file mode 100644
--- /dev/null
+++ b/lib/Language/Haskell/Stylish/Config/Cabal.hs
@@ -0,0 +1,92 @@
+--------------------------------------------------------------------------------
+module Language.Haskell.Stylish.Config.Cabal
+    ( findLanguageExtensions
+    ) where
+
+
+--------------------------------------------------------------------------------
+import           Data.Either                              (isRight)
+import           Data.List                                (nub)
+import           Data.Maybe                               (maybeToList)
+import qualified Distribution.PackageDescription          as Cabal
+import qualified Distribution.PackageDescription.Parsec   as Cabal
+import qualified Distribution.Simple.Utils                as Cabal
+import qualified Distribution.Types.CondTree              as Cabal
+import qualified Distribution.Verbosity                   as Cabal
+import qualified Language.Haskell.Extension               as Language
+import           Language.Haskell.Stylish.Verbose
+import           System.Directory                         (getCurrentDirectory)
+
+
+--------------------------------------------------------------------------------
+import           Language.Haskell.Stylish.Config.Internal
+
+
+--------------------------------------------------------------------------------
+findLanguageExtensions :: Verbose -> IO [Language.KnownExtension]
+findLanguageExtensions verbose =
+    findCabalFile verbose >>=
+    maybe (pure []) (readDefaultLanguageExtensions verbose)
+
+
+--------------------------------------------------------------------------------
+-- | Find the closest .cabal file, possibly going up the directory structure.
+findCabalFile :: Verbose -> IO (Maybe FilePath)
+findCabalFile verbose = do
+  potentialProjectRoots <- ancestors <$> getCurrentDirectory
+  potentialCabalFile <- filter isRight <$>
+    traverse Cabal.findPackageDesc potentialProjectRoots
+  case potentialCabalFile of
+    [Right cabalFile] -> return (Just cabalFile)
+    _ -> do
+      verbose $ ".cabal file not found, directories searched: " <>
+        show potentialProjectRoots
+      verbose $ "Stylish Haskell will work basing on LANGUAGE pragmas in source files."
+      return Nothing
+
+
+--------------------------------------------------------------------------------
+-- | Extract @default-extensions@ fields from a @.cabal@ file
+readDefaultLanguageExtensions :: Verbose -> FilePath -> IO [Language.KnownExtension]
+readDefaultLanguageExtensions verbose cabalFile = do
+  verbose $ "Parsing " <> cabalFile <> "..."
+  packageDescription <- Cabal.readGenericPackageDescription Cabal.silent cabalFile
+  let library :: [Cabal.Library]
+      library = maybeToList $ fst . Cabal.ignoreConditions <$>
+        Cabal.condLibrary packageDescription
+
+      subLibraries :: [Cabal.Library]
+      subLibraries = fst . Cabal.ignoreConditions . snd <$>
+        Cabal.condSubLibraries packageDescription
+
+      executables :: [Cabal.Executable]
+      executables = fst . Cabal.ignoreConditions . snd <$>
+        Cabal.condExecutables packageDescription
+
+      testSuites :: [Cabal.TestSuite]
+      testSuites = fst . Cabal.ignoreConditions . snd <$>
+        Cabal.condTestSuites packageDescription
+
+      benchmarks :: [Cabal.Benchmark]
+      benchmarks = fst . Cabal.ignoreConditions . snd <$>
+        Cabal.condBenchmarks packageDescription
+
+      gatherBuildInfos :: [Cabal.BuildInfo]
+      gatherBuildInfos = map Cabal.libBuildInfo library <>
+                         map Cabal.libBuildInfo subLibraries <>
+                         map Cabal.buildInfo executables <>
+                         map Cabal.testBuildInfo testSuites <>
+                         map Cabal.benchmarkBuildInfo benchmarks
+
+      defaultExtensions :: [Language.KnownExtension]
+      defaultExtensions = map fromEnabled . filter isEnabled $
+        concatMap Cabal.defaultExtensions gatherBuildInfos
+        where isEnabled (Language.EnableExtension _) = True
+              isEnabled _                            = False
+
+              fromEnabled (Language.EnableExtension x) = x
+              fromEnabled x                             =
+                error $ "Language.Haskell.Stylish.Config.readLanguageExtensions: " <>
+                        "invalid LANGUAGE pragma:  " <> show x
+  verbose $ "Gathered default-extensions: " <> show defaultExtensions
+  pure $ nub defaultExtensions
diff --git a/lib/Language/Haskell/Stylish/Config/Internal.hs b/lib/Language/Haskell/Stylish/Config/Internal.hs
new file mode 100644
--- /dev/null
+++ b/lib/Language/Haskell/Stylish/Config/Internal.hs
@@ -0,0 +1,15 @@
+--------------------------------------------------------------------------------
+module Language.Haskell.Stylish.Config.Internal
+    ( ancestors
+    ) where
+
+
+--------------------------------------------------------------------------------
+import           Data.List       (inits)
+import           System.FilePath (joinPath, splitPath)
+
+
+--------------------------------------------------------------------------------
+-- All ancestors of a dir (including that dir)
+ancestors :: FilePath -> [FilePath]
+ancestors = map joinPath . reverse . dropWhile null . inits . splitPath
diff --git a/stylish-haskell.cabal b/stylish-haskell.cabal
--- a/stylish-haskell.cabal
+++ b/stylish-haskell.cabal
@@ -1,5 +1,5 @@
 Name:          stylish-haskell
-Version:       0.9.3.0
+Version:       0.9.4.0
 Synopsis:      Haskell code prettifier
 Homepage:      https://github.com/jaspervdj/stylish-haskell
 License:       BSD3
@@ -41,6 +41,8 @@
     Language.Haskell.Stylish.Align
     Language.Haskell.Stylish.Block
     Language.Haskell.Stylish.Config
+    Language.Haskell.Stylish.Config.Cabal
+    Language.Haskell.Stylish.Config.Internal
     Language.Haskell.Stylish.Editor
     Language.Haskell.Stylish.Parse
     Language.Haskell.Stylish.Step
@@ -52,6 +54,7 @@
     aeson            >= 0.6    && < 1.5,
     base             >= 4.8    && < 5,
     bytestring       >= 0.9    && < 0.11,
+    Cabal            >= 2.4    && < 2.5,
     containers       >= 0.3    && < 0.7,
     directory        >= 1.2.3  && < 1.4,
     filepath         >= 1.1    && < 1.5,
@@ -75,6 +78,7 @@
     aeson            >= 0.6    && < 1.5,
     base             >= 4.8    && < 5,
     bytestring       >= 0.9    && < 0.11,
+    Cabal            >= 2.4    && < 2.5,
     containers       >= 0.3    && < 0.7,
     directory        >= 1.2.3  && < 1.4,
     filepath         >= 1.1    && < 1.5,
@@ -94,18 +98,21 @@
     Language.Haskell.Stylish.Align
     Language.Haskell.Stylish.Block
     Language.Haskell.Stylish.Config
+    Language.Haskell.Stylish.Config.Cabal
+    Language.Haskell.Stylish.Config.Internal
+    Language.Haskell.Stylish.Config.Tests
     Language.Haskell.Stylish.Editor
     Language.Haskell.Stylish.Parse
     Language.Haskell.Stylish.Parse.Tests
     Language.Haskell.Stylish.Step
-    Language.Haskell.Stylish.Step.SimpleAlign
-    Language.Haskell.Stylish.Step.SimpleAlign.Tests
-    Language.Haskell.Stylish.Step.Squash
-    Language.Haskell.Stylish.Step.Squash.Tests
     Language.Haskell.Stylish.Step.Imports
     Language.Haskell.Stylish.Step.Imports.Tests
     Language.Haskell.Stylish.Step.LanguagePragmas
     Language.Haskell.Stylish.Step.LanguagePragmas.Tests
+    Language.Haskell.Stylish.Step.SimpleAlign
+    Language.Haskell.Stylish.Step.SimpleAlign.Tests
+    Language.Haskell.Stylish.Step.Squash
+    Language.Haskell.Stylish.Step.Squash.Tests
     Language.Haskell.Stylish.Step.Tabs
     Language.Haskell.Stylish.Step.Tabs.Tests
     Language.Haskell.Stylish.Step.TrailingWhitespace
@@ -120,10 +127,12 @@
     HUnit                >= 1.2 && < 1.7,
     test-framework       >= 0.4 && < 0.9,
     test-framework-hunit >= 0.2 && < 0.4,
+    random               >= 1.1,
     -- Copied from regular dependencies...
     aeson            >= 0.6    && < 1.5,
     base             >= 4.8    && < 5,
     bytestring       >= 0.9    && < 0.11,
+    Cabal            >= 2.4    && < 2.5,
     containers       >= 0.3    && < 0.7,
     directory        >= 1.2.3  && < 1.4,
     filepath         >= 1.1    && < 1.5,
diff --git a/tests/Language/Haskell/Stylish/Config/Tests.hs b/tests/Language/Haskell/Stylish/Config/Tests.hs
new file mode 100644
--- /dev/null
+++ b/tests/Language/Haskell/Stylish/Config/Tests.hs
@@ -0,0 +1,142 @@
+module Language.Haskell.Stylish.Config.Tests
+    ( tests
+    ) where
+
+
+--------------------------------------------------------------------------------
+import           Control.Exception               hiding (assert)
+import qualified Data.Set                        as Set
+import           System.Directory
+import           System.FilePath                 ((</>))
+import           System.IO.Error
+import           System.Random
+import           Test.Framework                  (Test, testGroup)
+import           Test.Framework.Providers.HUnit  (testCase)
+import           Test.HUnit                      (Assertion, assert)
+--------------------------------------------------------------------------------
+import           Language.Haskell.Stylish.Config
+
+--------------------------------------------------------------------------------
+tests :: Test
+tests = testGroup "Language.Haskell.Stylish.Config"
+    [ testCase "Extensions extracted correctly from .cabal file"
+               testExtensionsFromDotCabal
+    , testCase "Extensions extracted correctly from .stylish-haskell.yaml file"
+               testExtensionsFromDotStylish
+    , testCase "Extensions extracted correctly from .stylish-haskell.yaml and .cabal files"
+               testExtensionsFromBoth
+    ]
+--------------------------------------------------------------------------------
+
+-- | Create a temporary directory with a randomised name built from the template provided
+createTempDirectory :: String -> IO FilePath
+createTempDirectory template  = do
+  tmpRootDir <- getTemporaryDirectory
+  dirId <- randomIO :: IO Word
+  findTempName tmpRootDir dirId
+  where
+    findTempName :: FilePath -> Word -> IO FilePath
+    findTempName tmpRootDir x = do
+      let dirpath = tmpRootDir </> template ++ show x
+      r <- try $ createDirectory dirpath
+      case r of
+        Right _ -> return dirpath
+        Left  e | isAlreadyExistsError e -> findTempName tmpRootDir (x+1)
+                | otherwise              -> ioError e
+
+-- | Perform an action inside a temporary directory tree and purge the tree afterwords
+withTestDirTree :: IO a -> IO a
+withTestDirTree action = bracket
+    ((,) <$> getCurrentDirectory <*> createTempDirectory "stylish_haskell")
+    (\(current, temp) ->
+        setCurrentDirectory current *>
+        removeDirectoryRecursive temp)
+    (\(_, temp) -> setCurrentDirectory temp *> action)
+
+-- | Put an example config files (.cabal/.stylish-haskell.yaml/both)
+-- into the current directory and extract extensions from it.
+createFilesAndGetExtensions :: [(FilePath, String)] -> IO Extensions
+createFilesAndGetExtensions files = withTestDirTree $ do
+  mapM_ (\(k, v) -> writeFile k v) files
+  -- create an empty directory and change into it
+  createDirectory "src"
+  setCurrentDirectory "src"
+  -- from that directory read the config file and extract extensions
+  -- to make sure the search for .cabal file works
+  config <- loadConfig (const (pure ())) Nothing
+  pure $ configLanguageExtensions config
+
+--------------------------------------------------------------------------------
+testExtensionsFromDotCabal :: Assertion
+testExtensionsFromDotCabal =
+  assert $ (expected ==) . Set.fromList <$>
+    createFilesAndGetExtensions [("test.cabal", dotCabal True)]
+    where
+      expected = Set.fromList ["ScopedTypeVariables", "DataKinds"]
+
+--------------------------------------------------------------------------------
+testExtensionsFromDotStylish :: Assertion
+testExtensionsFromDotStylish =
+  assert $ (expected ==) . Set.fromList <$>
+    createFilesAndGetExtensions [(".stylish-haskell.yaml", dotStylish)]
+    where
+      expected = Set.fromList ["TemplateHaskell", "QuasiQuotes"]
+
+--------------------------------------------------------------------------------
+testExtensionsFromBoth :: Assertion
+testExtensionsFromBoth =
+  assert $ (expected ==) . Set.fromList <$>
+    createFilesAndGetExtensions [ ("test.cabal", dotCabal True)
+                                , (".stylish-haskell.yaml", dotStylish)]
+    where
+      expected = Set.fromList
+        ["ScopedTypeVariables", "DataKinds", "TemplateHaskell", "QuasiQuotes"]
+
+-- | Example cabal file borrowed from
+--   https://www.haskell.org/cabal/users-guide/developing-packages.html
+--   with some default-extensions added
+dotCabal :: Bool -> String
+dotCabal includeExtensions = unlines $
+  [ "name:            TestPackage"
+  , "version:         0.0"
+  , "synopsis:        Package with library and two programs"
+  , "license:         BSD3"
+  , "author:          Angela Author"
+  , "build-type:      Simple"
+  , "cabal-version:   >= 1.2"
+  , ""
+  , "library"
+  , "   build-depends:   HUnit"
+  , "   exposed-modules: A, B, C"
+  ] ++
+  [if includeExtensions then "   default-extensions: ScopedTypeVariables"
+                        else ""]
+  ++
+  [ ""
+  , "executable program1"
+  , "   main-is:         Main.hs"
+  , "   hs-source-dirs:  prog1"
+  , "   other-modules:   A, B"
+  ] ++
+  [if includeExtensions then "   default-extensions: DataKinds"
+                        else ""]
+
+-- | Example .stylish-haskell.yaml
+dotStylish :: String
+dotStylish = unlines $
+  [ "steps:"
+  , "  - imports:"
+  , "      align: none"
+  , "      list_align: after_alias"
+  , "      long_list_align: inline"
+  , "      separate_lists: true"
+  , "  - language_pragmas:"
+  , "      style: vertical"
+  , "      align: false"
+  , "      remove_redundant: true"
+  , "  - trailing_whitespace: {}"
+  , "columns: 110"
+  , "language_extensions:"
+  , "  - TemplateHaskell"
+  , "  - QuasiQuotes"
+  ]
diff --git a/tests/TestSuite.hs b/tests/TestSuite.hs
--- a/tests/TestSuite.hs
+++ b/tests/TestSuite.hs
@@ -9,6 +9,7 @@
 
 
 --------------------------------------------------------------------------------
+import qualified Language.Haskell.Stylish.Config.Tests
 import qualified Language.Haskell.Stylish.Parse.Tests
 import qualified Language.Haskell.Stylish.Step.Imports.Tests
 import qualified Language.Haskell.Stylish.Step.LanguagePragmas.Tests
@@ -23,6 +24,7 @@
 main :: IO ()
 main = defaultMain
     [ Language.Haskell.Stylish.Parse.Tests.tests
+    , Language.Haskell.Stylish.Config.Tests.tests
     , Language.Haskell.Stylish.Step.Imports.Tests.tests
     , Language.Haskell.Stylish.Step.LanguagePragmas.Tests.tests
     , Language.Haskell.Stylish.Step.SimpleAlign.Tests.tests
