diff --git a/ihaskell.cabal b/ihaskell.cabal
--- a/ihaskell.cabal
+++ b/ihaskell.cabal
@@ -7,7 +7,7 @@
 -- PVP summary:      +--+------- breaking API changes
 --                   |  | +----- non-breaking API additions
 --                   |  | | +--- code changes with no API change
-version:             0.10.3.0
+version:             0.10.4.0
 
 -- A short (one-line) description of the package.
 synopsis:            A Haskell backend kernel for the Jupyter project.
@@ -63,14 +63,14 @@
     ghc-options:       -Wpartial-fields
 
   build-depends:
-                       base                 >=4.9 && <4.17,
+                       base                 >=4.9 && <4.19,
                        binary               ,
                        containers           ,
                        directory            ,
                        bytestring           ,
                        exceptions           ,
                        filepath             ,
-                       ghc                  >=8.0 && <9.3,
+                       ghc                  >=8.0 && <9.7,
                        ghc-boot             ,
                        haskeline            ,
                        parsec               ,
diff --git a/main/Main.hs b/main/Main.hs
--- a/main/Main.hs
+++ b/main/Main.hs
@@ -14,7 +14,7 @@
 import           Control.Arrow (second)
 import           Data.Aeson hiding (Success)
 import           System.Process (readProcess, readProcessWithExitCode)
-import           System.Exit (exitSuccess, ExitCode(ExitSuccess))
+import           System.Exit (exitSuccess, ExitCode)
 import           Control.Exception (try)
 import           System.Environment (getArgs)
 import           System.Environment (setEnv)
@@ -99,6 +99,10 @@
       kernelSpecOpts { kernelSpecCodeMirror = codemirror }
     addFlag kernelSpecOpts (GhcLibDir libdir) =
       kernelSpecOpts { kernelSpecGhcLibdir = libdir }
+    addFlag kernelSpecOpts (KernelName name) =
+      kernelSpecOpts { kernelSpecKernelName = name}
+    addFlag kernelSpecOpts (DisplayName name) =
+      kernelSpecOpts { kernelSpecDisplayName = name}
     addFlag kernelSpecOpts (RTSFlags rts) =
       kernelSpecOpts { kernelSpecRTSOptions = rts }
     addFlag kernelSpecOpts (KernelspecInstallPrefix prefix) =
@@ -132,7 +136,7 @@
     let stack =
           case runResult :: Either SomeException (ExitCode, String, String) of
             Left _ -> False
-            Right (exitCode, stackStdout, _) -> exitCode == ExitSuccess && "The Haskell Tool Stack" `isInfixOf` stackStdout
+            Right (_, stackStdout, stackStderr) -> "The Haskell Tool Stack" `isInfixOf` (stackStdout ++ stackStderr)
 
     -- If we're in a stack directory, use `stack` to set the environment
     -- We can't do this with base <= 4.6 because setEnv doesn't exist.
diff --git a/src/IHaskell/Display.hs b/src/IHaskell/Display.hs
--- a/src/IHaskell/Display.hs
+++ b/src/IHaskell/Display.hs
@@ -87,8 +87,8 @@
 html = DisplayData MimeHtml . T.pack
 
 -- | Generate an SVG display.
-svg :: String -> DisplayData
-svg = DisplayData MimeSvg . T.pack
+svg :: T.Text -> DisplayData
+svg = DisplayData MimeSvg
 
 -- | Generate a LaTeX display.
 latex :: String -> DisplayData
diff --git a/src/IHaskell/Eval/Completion.hs b/src/IHaskell/Eval/Completion.hs
--- a/src/IHaskell/Eval/Completion.hs
+++ b/src/IHaskell/Eval/Completion.hs
@@ -20,13 +20,20 @@
 import qualified Data.List.Split.Internals as Split
 import           System.Environment (getEnv)
 
-import           GHC
-#if MIN_VERSION_ghc(9,2,0)
+import           GHC hiding (ModuleName)
+#if MIN_VERSION_ghc(9,4,0)
 import           GHC.Unit.Database
 import           GHC.Unit.State
+import           GHC.Driver.Env
 import           GHC.Driver.Ppr
 import           GHC.Driver.Session
 import           GHC.Driver.Monad as GhcMonad
+#elif MIN_VERSION_ghc(9,2,0)
+import           GHC.Unit.Database
+import           GHC.Unit.State
+import           GHC.Driver.Ppr
+import           GHC.Driver.Session
+import           GHC.Driver.Monad as GhcMonad
 #elif MIN_VERSION_ghc(9,0,0)
 import           GHC.Unit.Database
 import           GHC.Unit.State
@@ -86,7 +93,13 @@
   let isQualified = ('.' `elem`)
       unqualNames = nub $ filter (not . isQualified) rdrNames
       qualNames = nub $ scopeNames ++ filter isQualified rdrNames
-#if MIN_VERSION_ghc(9,2,0)
+#if MIN_VERSION_ghc(9,4,0)
+  logger <- getLogger
+  hsc_env <- getSession
+  (db, _, _, _) <- liftIO $ initUnits logger flags Nothing (hsc_all_home_unit_ids hsc_env)
+  let getNames = map (moduleNameString . exposedName) . unitExposedModules
+      moduleNames = nub $ concatMap getNames $ concatMap unitDatabaseUnits db
+#elif MIN_VERSION_ghc(9,2,0)
   logger <- getLogger
   (db, _, _, _) <- liftIO $ initUnits logger flags Nothing
   let getNames = map (moduleNameString . exposedName) . unitExposedModules
diff --git a/src/IHaskell/Eval/Evaluate.hs b/src/IHaskell/Eval/Evaluate.hs
--- a/src/IHaskell/Eval/Evaluate.hs
+++ b/src/IHaskell/Eval/Evaluate.hs
@@ -35,7 +35,7 @@
 import           System.Exit
 import           System.Environment (getEnv)
 
-#if MIN_VERSION_ghc(9,2,0)
+#if MIN_VERSION_ghc(9,4,0)
 import qualified GHC.Runtime.Debugger as Debugger
 import           GHC.Runtime.Eval
 import           GHC.Driver.Session
@@ -44,11 +44,27 @@
 import           GHC.Utils.Outputable hiding ((<>))
 import           GHC.Data.Bag
 import           GHC.Driver.Backend
+import           GHC.Driver.Env
 import           GHC.Driver.Ppr
 import           GHC.Runtime.Context
+import           GHC.Types.Error
 import           GHC.Types.SourceError
 import           GHC.Unit.Types (UnitId)
 import qualified GHC.Utils.Error as ErrUtils
+#elif MIN_VERSION_ghc(9,2,0)
+import qualified GHC.Runtime.Debugger as Debugger
+import           GHC.Runtime.Eval
+import           GHC.Driver.Session
+import           GHC.Unit.State
+import           Control.Monad.Catch as MC
+import           GHC.Utils.Outputable hiding ((<>))
+import           GHC.Data.Bag
+import           GHC.Driver.Backend
+import           GHC.Driver.Ppr
+import           GHC.Runtime.Context
+import           GHC.Types.SourceError
+import           GHC.Unit.Types (UnitId)
+import qualified GHC.Utils.Error as ErrUtils
 #elif MIN_VERSION_ghc(9,0,0)
 import qualified GHC.Runtime.Debugger as Debugger
 import           GHC.Runtime.Eval
@@ -208,7 +224,16 @@
   -- Run the rest of the interpreter
   action hasSupportLibraries
 
-#if MIN_VERSION_ghc(9,2,0)
+#if MIN_VERSION_ghc(9,4,0)
+packageIdString' :: Logger -> DynFlags -> HscEnv -> UnitInfo -> IO String
+packageIdString' logger dflags hsc_env pkg_cfg = do
+    (_, unitState, _, _) <- initUnits logger dflags Nothing (hsc_all_home_unit_ids hsc_env)
+    case (lookupUnit unitState $ mkUnit pkg_cfg) of
+      Nothing -> pure "(unknown)"
+      Just cfg -> let
+        PackageName name = unitPackageName cfg
+        in pure $ unpackFS name
+#elif MIN_VERSION_ghc(9,2,0)
 packageIdString' :: Logger -> DynFlags -> UnitInfo -> IO String
 packageIdString' logger dflags pkg_cfg = do
     (_, unitState, _, _) <- initUnits logger dflags Nothing
@@ -239,7 +264,12 @@
     fromMaybe "(unknown)" (unitIdPackageIdString dflags $ packageConfigId pkg_cfg)
 #endif
 
-#if MIN_VERSION_ghc(9,2,0)
+#if MIN_VERSION_ghc(9,4,0)
+getPackageConfigs :: Logger -> DynFlags -> HscEnv -> IO [GenUnitInfo UnitId]
+getPackageConfigs logger dflags hsc_env = do
+    (pkgDb, _, _, _) <- initUnits logger dflags Nothing (hsc_all_home_unit_ids hsc_env)
+    pure $ foldMap unitDatabaseUnits pkgDb
+#elif MIN_VERSION_ghc(9,2,0)
 getPackageConfigs :: Logger -> DynFlags -> IO [GenUnitInfo UnitId]
 getPackageConfigs logger dflags = do
     (pkgDb, _, _, _) <- initUnits logger dflags Nothing
@@ -274,8 +304,16 @@
   (dflgs, _) <- liftIO $ initPackages dflags
 #endif
 
-#if MIN_VERSION_ghc(9,2,0)
+#if MIN_VERSION_ghc(9,4,0)
   logger <- getLogger
+  hsc_env <- getSession
+  db <- liftIO $ getPackageConfigs logger dflgs hsc_env
+  packageNames <- liftIO $ mapM (packageIdString' logger dflgs hsc_env) db
+  let hiddenPackages = Set.intersection hiddenPackageNames (Set.fromList packageNames)
+      hiddenFlags = fmap HidePackage $ Set.toList hiddenPackages
+      initStr = "ihaskell-"
+#elif MIN_VERSION_ghc(9,2,0)
+  logger <- getLogger
   db <- liftIO $ getPackageConfigs logger dflgs
   packageNames <- liftIO $ mapM (packageIdString' logger dflgs) db
   let hiddenPackages = Set.intersection hiddenPackageNames (Set.fromList packageNames)
@@ -328,9 +366,15 @@
 
   void $ setSessionDynFlags $ dflgs { packageFlags = hiddenFlags ++ packageFlags dflgs }
 
+#if MIN_VERSION_ghc(9,6,0)
   -- Import implicit prelude.
   importDecl <- parseImportDecl "import Prelude"
+  let implicitPrelude = importDecl { ideclExt = (ideclExt importDecl) { ideclImplicit = True } }
+#else
+  -- Import implicit prelude.
+  importDecl <- parseImportDecl "import Prelude"
   let implicitPrelude = importDecl { ideclImplicit = True }
+#endif
       displayImports' = if importSupportLibraries then displayImports else []
 
   -- Import modules.
@@ -506,7 +550,13 @@
         let commMessages = evalmsgs ++ messages
         widgetHandler state commMessages
 
-#if MIN_VERSION_ghc(9,2,0)
+#if MIN_VERSION_ghc(9,6,0)
+getErrMsgDoc :: ErrUtils.Diagnostic e => ErrUtils.MsgEnvelope e -> SDoc
+getErrMsgDoc = ErrUtils.pprLocMsgEnvelopeDefault
+#elif MIN_VERSION_ghc(9,4,0)
+getErrMsgDoc :: ErrUtils.Diagnostic e => ErrUtils.MsgEnvelope e -> SDoc
+getErrMsgDoc = ErrUtils.pprLocMsgEnvelope
+#elif MIN_VERSION_ghc(9,2,0)
 getErrMsgDoc :: ErrUtils.WarnMsg -> SDoc
 getErrMsgDoc = ErrUtils.pprLocMsgEnvelope
 #else
@@ -530,7 +580,11 @@
 
     sourceErrorHandler :: SourceError -> Interpreter EvalOut
     sourceErrorHandler srcerr = do
+#if MIN_VERSION_ghc(9,4,0)
+      let msgs = bagToList . getMessages $ srcErrorMessages srcerr
+#else
       let msgs = bagToList $ srcErrorMessages srcerr
+#endif
       errStrs <- forM msgs $ doc . getErrMsgDoc
 
       let fullErr = unlines errStrs
@@ -656,7 +710,11 @@
         then evalImport "import qualified Prelude as Prelude"
         else when ("-XImplicitPrelude" `elem` flags) $ do
           importDecl <- parseImportDecl "import Prelude"
+#if MIN_VERSION_ghc(9,6,0)
+          let implicitPrelude = importDecl { ideclExt = (ideclExt importDecl) { ideclImplicit = True } }
+#else
           let implicitPrelude = importDecl { ideclImplicit = True }
+#endif
           imports <- getContext
           setContext $ IIDecl implicitPrelude : imports
 
@@ -903,7 +961,9 @@
 evalCommand _ (Directive SPrint binding) state = wrapExecution state $ do
   flags <- getSessionDynFlags
   contents <- liftIO $ newIORef []
-#if MIN_VERSION_ghc(9,0,0)
+#if MIN_VERSION_ghc(9,4,0)
+  let action = \_lflags _msgclass _srcspan msg -> modifyIORef' contents (showSDoc flags msg :)
+#elif MIN_VERSION_ghc(9,0,0)
   let action = \_dflags _warn _sev _srcspan msg -> modifyIORef' contents (showSDoc flags msg :)
 #else
   let action = \_dflags _sev _srcspan _ppr _style msg -> modifyIORef' contents (showSDoc flags msg :)
@@ -1153,7 +1213,9 @@
     -- Compile loaded modules.
     flags <- getSessionDynFlags
     errRef <- liftIO $ newIORef []
-#if MIN_VERSION_ghc(9,0,0)
+#if MIN_VERSION_ghc(9,4,0)
+    let logAction = \_lflags _msgclass _srcspan msg -> modifyIORef' errRef (showSDoc flags msg :)
+#elif MIN_VERSION_ghc(9,0,0)
     let logAction = \_dflags _warn _sev _srcspan msg -> modifyIORef' errRef (showSDoc flags msg :)
 #else
     let logAction = \_dflags _sev _srcspan _ppr _style msg -> modifyIORef' errRef (showSDoc flags msg :)
@@ -1172,7 +1234,11 @@
         }
 
     -- Load the new target.
+#if MIN_VERSION_ghc(9,4,0)
+    target <- guessTarget name Nothing Nothing
+#else
     target <- guessTarget name Nothing
+#endif
     oldTargets <- getTargets
     -- Add a target, but make sure targets are unique!
     addTarget target
@@ -1215,7 +1281,9 @@
 
       -- Switch to interpreted mode!
       flags <- getSessionDynFlags
-#if MIN_VERSION_ghc(9,2,0)
+#if MIN_VERSION_ghc(9,6,0)
+      _ <- setSessionDynFlags flags { backend = interpreterBackend }
+#elif MIN_VERSION_ghc(9,2,0)
       _ <- setSessionDynFlags flags { backend = Interpreter }
 #else
       _ <- setSessionDynFlags flags { hscTarget = HscInterpreted }
@@ -1283,7 +1351,9 @@
 
       -- Switch to interpreted mode!
       flags <- getSessionDynFlags
-#if MIN_VERSION_ghc(9,2,0)
+#if MIN_VERSION_ghc(9,6,0)
+      _ <- setSessionDynFlags flags { backend = interpreterBackend }
+#elif MIN_VERSION_ghc(9,2,0)
       _ <- setSessionDynFlags flags { backend = Interpreter }
 #else
       _ <- setSessionDynFlags flags { hscTarget = HscInterpreted }
diff --git a/src/IHaskell/Eval/Util.hs b/src/IHaskell/Eval/Util.hs
--- a/src/IHaskell/Eval/Util.hs
+++ b/src/IHaskell/Eval/Util.hs
@@ -34,7 +34,25 @@
 #endif
 
 -- GHC imports.
-#if MIN_VERSION_ghc(9,2,0)
+#if MIN_VERSION_ghc(9,4,0)
+import           GHC.Core.InstEnv (is_cls, is_tys, mkInstEnv, instEnvElts)
+import           GHC.Core.Unify
+import           GHC.Types.TyThing.Ppr
+import           GHC.Driver.CmdLine
+import           GHC.Driver.Monad (modifySession)
+import           GHC.Driver.Ppr
+import           GHC.Driver.Session
+import           GHC.Driver.Env.Types
+import           GHC.Platform.Ways
+import           GHC.Runtime.Context
+import           GHC.Types.Name (pprInfixName)
+import           GHC.Types.Name.Set
+import           GHC.Types.TyThing
+import qualified GHC.Driver.Session as DynFlags
+import qualified GHC.Utils.Outputable as O
+import qualified GHC.Utils.Ppr as Pretty
+import           GHC.Runtime.Loader
+#elif MIN_VERSION_ghc(9,2,0)
 import           GHC.Core.InstEnv (is_cls, is_tys)
 import           GHC.Core.Unify
 import           GHC.Types.TyThing.Ppr
@@ -178,7 +196,9 @@
         is_on = test f dflags
         quiet = not show_all && test f default_dflags == is_on
 
-#if MIN_VERSION_ghc(8,10,0)
+#if MIN_VERSION_ghc(9,6,0)
+    default_dflags = defaultDynFlags (settings dflags)
+#elif MIN_VERSION_ghc(8,10,0)
     default_dflags = defaultDynFlags (settings dflags) (llvmConfig dflags)
 #elif MIN_VERSION_ghc(8,6,0)
     default_dflags = defaultDynFlags (settings dflags) (llvmTargets dflags, llvmPasses dflags)
@@ -215,6 +235,10 @@
         Nothing          -> O.text "Haskell2010"
         Just Haskell98   -> O.text "Haskell98"
         Just Haskell2010 -> O.text "Haskell2010"
+#if MIN_VERSION_ghc(9,4,0)
+        Just GHC2021 -> O.text "GHC2021"
+#else
+#endif
     , (if show_all
          then O.text "all active language options:"
          else O.text "with the following modifiers:") O.$$
@@ -232,7 +256,9 @@
         quiet = not show_all && test f default_dflags == is_on
 
     default_dflags =
-#if MIN_VERSION_ghc(8,10,0)
+#if MIN_VERSION_ghc(9,6,0)
+      defaultDynFlags (settings dflags) `lang_set`
+#elif MIN_VERSION_ghc(8,10,0)
       defaultDynFlags (settings dflags) (llvmConfig dflags) `lang_set`
 #elif MIN_VERSION_ghc(8,6,0)
       defaultDynFlags (settings dflags) (llvmTargets dflags, llvmPasses dflags) `lang_set`
@@ -307,7 +333,11 @@
 doc :: GhcMonad m => O.SDoc -> m String
 doc sdoc = do
   flags <- getSessionDynFlags
+#if MIN_VERSION_ghc(9,6,0)
+  let unqual = O.neverQualify
+#else
   unqual <- getPrintUnqual
+#endif
 #if MIN_VERSION_ghc(9,0,0)
   let style = O.mkUserStyle unqual O.AllTheWay
 #elif MIN_VERSION_ghc(8,2,0)
@@ -376,7 +406,9 @@
             in packageDBFlags originalFlags ++ [pkg]
 
   void $ setSessionDynFlags $ dflags
-#if MIN_VERSION_ghc(9,2,0)
+#if MIN_VERSION_ghc(9,6,0)
+    { backend = interpreterBackend
+#elif MIN_VERSION_ghc(9,2,0)
     { backend = Interpreter
 #else
     { hscTarget = HscInterpreted
@@ -436,24 +468,40 @@
 #endif
 
     -- Check whether an import is an *implicit* import of something.
-#if MIN_VERSION_ghc(8,4,0)
+#if MIN_VERSION_ghc(9,6,0)
     implicitImportOf :: ImportDecl GhcPs -> InteractiveImport -> Bool
+    implicitImportOf _ (IIModule _) = False
+    implicitImportOf imp (IIDecl decl) = ideclImplicit (ideclExt decl) && imp `importOf` IIDecl decl
+#elif MIN_VERSION_ghc(8,4,0)
+    implicitImportOf :: ImportDecl GhcPs -> InteractiveImport -> Bool
+    implicitImportOf _ (IIModule _) = False
+    implicitImportOf imp (IIDecl decl) = ideclImplicit decl && imp `importOf` IIDecl decl
 #else
     implicitImportOf :: ImportDecl RdrName -> InteractiveImport -> Bool
-#endif
     implicitImportOf _ (IIModule _) = False
     implicitImportOf imp (IIDecl decl) = ideclImplicit decl && imp `importOf` IIDecl decl
+#endif
 
     -- Check whether an import is hidden.
-#if MIN_VERSION_ghc(8,4,0)
+#if MIN_VERSION_ghc(9,6,0)
     isHiddenImport :: ImportDecl GhcPs -> Bool
+    isHiddenImport imp =
+      case ideclImportList imp of
+        Just (EverythingBut, _) -> True
+        _              -> False
+#elif MIN_VERSION_ghc(8,4,0)
+    isHiddenImport :: ImportDecl GhcPs -> Bool
+    isHiddenImport imp =
+      case ideclHiding imp of
+        Just (True, _) -> True
+        _              -> False
 #else
     isHiddenImport :: ImportDecl RdrName -> Bool
-#endif
     isHiddenImport imp =
       case ideclHiding imp of
         Just (True, _) -> True
         _              -> False
+#endif
 
 removeImport :: GhcMonad m => String -> m ()
 removeImport modName = do
@@ -485,7 +533,11 @@
       ic = hsc_IC hscEnv
       (clsInsts, famInsts) = ic_instances ic
       -- Remove duplicates
+#if MIN_VERSION_ghc(9,4,0)
+      clsInsts' = mkInstEnv $ nubBy instEq $ instEnvElts clsInsts
+#else
       clsInsts' = nubBy instEq clsInsts
+#endif
   in hscEnv { hsc_IC = ic { ic_instances = (clsInsts', famInsts) } }
   where
     instEq :: ClsInst -> ClsInst -> Bool
@@ -523,7 +575,11 @@
   maybeInfos <- mapM getInfo' names
 
   -- Filter out types that have parents in the same set. GHCi also does this.
+#if MIN_VERSION_ghc(9,6,0)
+  let infos = catMaybes $ nonEmptyToList maybeInfos
+#else
   let infos = catMaybes maybeInfos
+#endif
       allNames = mkNameSet $ map (getName . getInfoType) infos
       hasParent info =
         case tyThingParent_maybe (getInfoType info) of
diff --git a/src/IHaskell/Flags.hs b/src/IHaskell/Flags.hs
--- a/src/IHaskell/Flags.hs
+++ b/src/IHaskell/Flags.hs
@@ -29,6 +29,8 @@
               | RTSFlags [String]   -- ^ Options for the GHC runtime (e.g. heap-size limit
                                     --     or number of threads).
               | KernelDebug         -- ^ Spew debugging output from the kernel.
+              | KernelName String   -- ^ The IPython kernel directory name.
+              | DisplayName String  -- ^ The IPython display name.
               | Help                -- ^ Display help text.
               | Version             -- ^ Display version text.
               | CodeMirror String   -- ^ change codemirror mode (default=ihaskell)
@@ -115,6 +117,22 @@
   where
     addDebug (Args md prev) = Args md (KernelDebug : prev)
 
+kernelNameFlag :: Flag Args
+kernelNameFlag =
+  flagReq
+    ["kernel-name"]
+    (store KernelName)
+    "<name>"
+    "The directory name of the kernel."
+
+displayNameFlag :: Flag Args
+displayNameFlag =
+  flagReq
+    ["display-name"]
+    (store DisplayName)
+    "<name>"
+    "The display name of the kernel."
+
 kernelCodeMirrorFlag :: Flag Args
 kernelCodeMirrorFlag = flagReq ["codemirror"] (store CodeMirror) "<codemirror>"
         "Specify codemirror mode that is used for syntax highlighting (default: ihaskell)."
@@ -153,7 +171,7 @@
 installKernelSpec :: Mode Args
 installKernelSpec =
   mode "install" (Args InstallKernelSpec []) "Install the Jupyter kernelspec." noArgs
-    [ghcLibFlag, ghcRTSFlag, kernelDebugFlag, confFlag, installPrefixFlag, helpFlag, kernelStackFlag, kernelEnvFileFlag]
+    [ghcLibFlag, ghcRTSFlag, kernelDebugFlag, kernelNameFlag, displayNameFlag, confFlag, installPrefixFlag, helpFlag, kernelStackFlag, kernelEnvFileFlag]
 
 kernel :: Mode Args
 kernel = mode "kernel" (Args (Kernel Nothing) []) "Invoke the IHaskell kernel." kernelArg
diff --git a/src/IHaskell/IPython.hs b/src/IHaskell/IPython.hs
--- a/src/IHaskell/IPython.hs
+++ b/src/IHaskell/IPython.hs
@@ -8,7 +8,6 @@
     getIHaskellDir,
     getSandboxPackageConf,
     subHome,
-    kernelName,
     KernelSpecOptions(..),
     defaultKernelSpecOptions,
     installLabextension,
@@ -45,6 +44,8 @@
          , kernelSpecInstallPrefix :: Maybe String
          , kernelSpecUseStack :: Bool              -- ^ Whether to use @stack@ environments.
          , kernelSpecEnvFile :: Maybe FilePath
+         , kernelSpecKernelName :: String          -- ^ The IPython kernel name
+         , kernelSpecDisplayName :: String         -- ^ The IPython kernel display name
          }
 
 defaultKernelSpecOptions :: KernelSpecOptions
@@ -58,12 +59,10 @@
   , kernelSpecInstallPrefix = Nothing
   , kernelSpecUseStack = False
   , kernelSpecEnvFile = Nothing
+  , kernelSpecKernelName = "haskell"
+  , kernelSpecDisplayName = "Haskell"
   }
 
--- | The IPython kernel name.
-kernelName :: String
-kernelName = "haskell"
-
 ipythonCommand :: SH.Sh SH.FilePath
 ipythonCommand = do
   jupyterMay <- SH.which "jupyter"
@@ -134,6 +133,8 @@
   ihaskellPath <- getIHaskellPath
   confFile <- liftIO $ kernelSpecConfFile opts
 
+  let kernelName = kernelSpecKernelName opts
+
   let kernelFlags :: [String]
       kernelFlags =
         ["--debug" | kernelSpecDebug opts] ++
@@ -147,7 +148,7 @@
            ++ ["--stack" | kernelSpecUseStack opts]
 
   let kernelSpec = KernelSpec
-        { kernelDisplayName = "Haskell"
+        { kernelDisplayName = kernelSpecDisplayName opts
         , kernelLanguage = kernelName
         , kernelCommand = [ihaskellPath, "kernel", "{connection_file}"] ++ kernelFlags
         }
diff --git a/src/IHaskellPrelude.hs b/src/IHaskellPrelude.hs
--- a/src/IHaskellPrelude.hs
+++ b/src/IHaskellPrelude.hs
@@ -98,6 +98,7 @@
 import qualified Data.ByteString
 import qualified Data.ByteString.Lazy
 import qualified Data.Function
+import qualified Data.List.NonEmpty
 import qualified GHC.Exts
 import qualified System.IO
 import qualified System.IO.Strict
@@ -157,3 +158,6 @@
 
 print :: (MonadIO m, Show a) => a -> m ()
 print = liftIO . P.print
+
+nonEmptyToList :: Data.List.NonEmpty.NonEmpty a -> [a]
+nonEmptyToList = Data.List.NonEmpty.toList
diff --git a/src/tests/IHaskell/Test/Completion.hs b/src/tests/IHaskell/Test/Completion.hs
--- a/src/tests/IHaskell/Test/Completion.hs
+++ b/src/tests/IHaskell/Test/Completion.hs
@@ -14,8 +14,11 @@
 import           System.Environment (setEnv)
 import           System.Directory (setCurrentDirectory, getCurrentDirectory)
 
-#if MIN_VERSION_ghc(9,2,0)
+#if MIN_VERSION_ghc(9,6,0)
 import           GHC (getSessionDynFlags, setSessionDynFlags, DynFlags(..), GhcLink(..), setContext,
+                      parseImportDecl, interpreterBackend, Backend(..), InteractiveImport(..))
+#elif MIN_VERSION_ghc(9,2,0)
+import           GHC (getSessionDynFlags, setSessionDynFlags, DynFlags(..), GhcLink(..), setContext,
                       parseImportDecl, Backend(..), InteractiveImport(..))
 #else
 import           GHC (getSessionDynFlags, setSessionDynFlags, DynFlags(..), GhcLink(..), setContext,
@@ -67,7 +70,9 @@
 initCompleter :: Interpreter ()
 initCompleter = do
   flags <- getSessionDynFlags
-#if MIN_VERSION_ghc(9,2,0)
+#if MIN_VERSION_ghc(9,6,0)
+  _ <- setSessionDynFlags $ setWayDynFlag flags { backend = interpreterBackend, ghcLink = LinkInMemory }
+#elif MIN_VERSION_ghc(9,2,0)
   _ <- setSessionDynFlags $ setWayDynFlag flags { backend = Interpreter, ghcLink = LinkInMemory }
 #else
   _ <- setSessionDynFlags $ setWayDynFlag flags { hscTarget = HscInterpreted, ghcLink = LinkInMemory }
