diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,11 @@
 # ChangeLog hie-bios
 
+## 2021-03-21 - 0.7.5
+
+### Bug Fixes
+
+* Improve out-of-the-box support for dynamically linked GHC. [#286](https://github.com/mpickering/hie-bios/pull/286), [#287](https://github.com/mpickering/hie-bios/pull/287)
+
 ## 2021-02-19 - 0.7.4
 
 ### Bug Fixes
diff --git a/hie-bios.cabal b/hie-bios.cabal
--- a/hie-bios.cabal
+++ b/hie-bios.cabal
@@ -1,6 +1,6 @@
 Cabal-Version:          2.2
 Name:                   hie-bios
-Version:                0.7.4
+Version:                0.7.5
 Author:                 Matthew Pickering <matthewtpickering@gmail.com>
 Maintainer:             Matthew Pickering <matthewtpickering@gmail.com>
 License:                BSD-3-Clause
diff --git a/src/HIE/Bios/Cradle.hs b/src/HIE/Bios/Cradle.hs
--- a/src/HIE/Bios/Cradle.hs
+++ b/src/HIE/Bios/Cradle.hs
@@ -60,6 +60,7 @@
 import qualified Data.HashMap.Strict as Map
 import           Data.Maybe (fromMaybe, maybeToList)
 import           GHC.Fingerprint (fingerprintString)
+import DynFlags (dynamicGhc)
 
 hie_bios_output :: String
 hie_bios_output = "HIE_BIOS_OUTPUT"
@@ -172,6 +173,14 @@
 configFileName :: FilePath
 configFileName = "hie.yaml"
 
+-- | Pass '-dynamic' flag when GHC is built with dynamic linking.
+-- 
+-- Append flag to options of 'defaultCradle' and 'directCradle' if GHC is dynmically linked,
+-- because unlike the case of using build tools, which means '-dynamic' can be set via
+-- '.cabal' or 'package.yaml', users have to create an explicit hie.yaml to pass this flag.
+argDynamic :: [String]
+argDynamic = ["-dynamic" | dynamicGhc]
+
 ---------------------------------------------------------------
 
 isCabalCradle :: Cradle a -> Bool
@@ -225,7 +234,7 @@
     , cradleOptsProg = CradleAction
         { actionName = Types.Default
         , runCradle = \_ _ ->
-            return (CradleSuccess (ComponentOptions [] cur_dir []))
+            return (CradleSuccess (ComponentOptions argDynamic cur_dir []))
         , runGhcCmd = runGhcCmdOnPath cur_dir
         }
     }
@@ -334,7 +343,7 @@
     , cradleOptsProg = CradleAction
         { actionName = Types.Direct
         , runCradle = \_ _ ->
-            return (CradleSuccess (ComponentOptions args wdir []))
+            return (CradleSuccess (ComponentOptions (args ++ argDynamic) wdir []))
         , runGhcCmd = runGhcCmdOnPath wdir
         }
     }
@@ -484,7 +493,7 @@
                       ghcArgs ++ ["-rtsopts=ignore", "-outputdir", tmpDir, "-o", wrapper_fp, wrapper_hs])
                       { cwd = Just wdir }
           readCreateProcess ghc "" >>= putStr
-      else withFile wrapper_fp WriteMode $ \h -> hPutStr h wrapperContents
+      else writeFile wrapper_fp wrapperContents
     setMode wrapper_fp
     pure wrapper_fp
   where
diff --git a/src/HIE/Bios/Environment.hs b/src/HIE/Bios/Environment.hs
--- a/src/HIE/Bios/Environment.hs
+++ b/src/HIE/Bios/Environment.hs
@@ -44,6 +44,7 @@
         $ setIgnoreInterfacePragmas            -- Ignore any non-essential information in interface files such as unfoldings changing.
         $ writeInterfaceFiles (Just cache_dir) -- Write interface files to the cache
         $ setVerbosity 0                       -- Set verbosity to zero just in case the user specified `-vx` in the options.
+        $ (if dynamicGhc then updateWays . addWay' WayDyn else id) -- Add dynamic way if GHC is built with dynamic linking 
         $ setLinkerOptions df''                 -- Set `-fno-code` to avoid generating object files, unless we have to.
         )
 
diff --git a/tests/BiosTests.hs b/tests/BiosTests.hs
--- a/tests/BiosTests.hs
+++ b/tests/BiosTests.hs
@@ -26,7 +26,11 @@
 import System.IO.Temp
 import System.Exit (ExitCode(ExitSuccess, ExitFailure))
 import Control.Monad.Extra (unlessM)
+import DynFlags (dynamicGhc)
 
+argDynamic :: [String]
+argDynamic = ["-dynamic" | dynamicGhc]
+
 main :: IO ()
 main = do
   writeStackYamlFiles
@@ -56,7 +60,7 @@
                 runCradle (cradleOptsProg crdl) (const (pure ())) "./a/A.hs"
                 >>= \case
                   CradleSuccess r ->
-                    componentOptions r `shouldMatchList` ["a"]
+                    componentOptions r `shouldMatchList` ["a"] <> argDynamic
                   _ -> expectationFailure "Cradle could not be loaded"
 
         , testCaseSteps "Can load symlinked module" $ \step -> do
@@ -71,7 +75,7 @@
                 runCradle (cradleOptsProg crdl) (const (pure ())) "./b/A.hs"
                 >>= \case
                   CradleSuccess r ->
-                    componentOptions r `shouldMatchList` ["b"]
+                    componentOptions r `shouldMatchList` ["b"] <> argDynamic
                   _ -> expectationFailure "Cradle could not be loaded"
 
         , testCaseSteps "Can not load symlinked module that is ignored" $ \step -> do
