diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,10 @@
 
+0.6
+---
+
+Changes:
+ * The `askAspell` function is now thread-safe.
+
 0.5
 ---
 
diff --git a/aspell-pipe.cabal b/aspell-pipe.cabal
--- a/aspell-pipe.cabal
+++ b/aspell-pipe.cabal
@@ -1,5 +1,5 @@
 name:                aspell-pipe
-version:             0.5
+version:             0.6
 synopsis:            Pipe-based interface to the Aspell program
 description:         A pipe-based interface to the Aspell program (no
                      dynamic linking required).
diff --git a/src/Text/Aspell.hs b/src/Text/Aspell.hs
--- a/src/Text/Aspell.hs
+++ b/src/Text/Aspell.hs
@@ -25,6 +25,7 @@
 import qualified Control.Exception as E
 import Control.Monad (forM, when, void)
 import qualified Control.Concurrent.Async as A
+import Control.Concurrent.MVar (MVar, newMVar, withMVar)
 import Data.Monoid ((<>))
 import Data.Maybe (fromJust)
 import Text.Read (readMaybe)
@@ -40,6 +41,7 @@
            , aspellStdin          :: Handle
            , aspellStdout         :: Handle
            , aspellIdentification :: T.Text -- ^ startup-reported version string
+           , aspellLock           :: MVar ()
            }
 
 instance Show Aspell where
@@ -58,12 +60,12 @@
 
 -- | A spelling mistake.
 data Mistake =
-    Mistake { mistakeWord         :: T.Text
+    Mistake { mistakeWord :: T.Text
             -- ^ The original word in misspelled form.
-            , mistakeNearMisses   :: Int
+            , mistakeNearMisses :: Int
             -- ^ The number of alternative correct spellings that were
             -- counted.
-            , mistakeOffset       :: Int
+            , mistakeOffset :: Int
             -- ^ The offset, starting at zero, in the original input
             -- where this misspelling occurred.
             , mistakeAlternatives :: [T.Text]
@@ -74,13 +76,13 @@
 -- | An Aspell option.
 data AspellOption =
     UseDictionary T.Text
-    -- ^ Use the specified dictionary (see aspell -d).
+    -- ^ Use the specified dictionary (see @aspell -d@).
     | RawArg T.Text
-    -- ^ Provide a command-line argument directly to aspell.
+    -- ^ Provide a command-line argument directly to @aspell@.
     deriving (Show, Eq)
 
 -- | Start Aspell with the specified options. Returns either an error
--- message on failure or an Aspell handle on success.
+-- message on failure or an 'Aspell' handle on success.
 --
 -- Any 'RawArg's provided in the option list are provided to @aspell@ as
 -- command-line arguments in the order provided.
@@ -116,10 +118,13 @@
                     case validIdent ident of
                         False -> fail ("Unexpected identification string: " <> T.unpack ident)
                         True -> do
+                            mv <- newMVar ()
+
                             let as = Aspell { aspellProcessHandle  = ph
                                             , aspellStdin          = inH
                                             , aspellStdout         = outH
                                             , aspellIdentification = ident
+                                            , aspellLock           = mv
                                             }
 
                             -- Enable terse mode with aspell to improve performance.
@@ -170,10 +175,14 @@
 stopAspell :: Aspell -> IO ()
 stopAspell = P.terminateProcess . aspellProcessHandle
 
--- | Submit user input to Aspell for spell-checking. Returns an
--- AspellResponse for each line of user input.
+-- | Submit input text to Aspell for spell-checking. The input text may
+-- contain multiple lines. This returns an 'AspellResponse' for each
+-- line.
+--
+-- This function is thread-safe and will block until other callers
+-- finish.
 askAspell :: Aspell -> T.Text -> IO [AspellResponse]
-askAspell as t = do
+askAspell as t = withMVar (aspellLock as) $ const $ do
     -- Send the user's input. Prefix with "^" to ensure that the line is
     -- checked even if it contains metacharacters.
     forM (T.lines t) $ \theLine -> do
