diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -5,6 +5,13 @@
 ## Unreleased changes
 
 
+## Version 0.6.1.0
+
+-   Split `ELynx.Tools` into separate modules because the package will be reduced.
+-   Remove the following modules from `ELynx.Tools`: `Concurrent`,
+    `LinearAlgebra`, `List`, `Misc`, and `Numeric`.
+
+
 ## Version 0.6.0.0
 
 -   **elynx-tree:** remove parallel folds with layers (`parBranchFoldMapWithLayer`
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -69,13 +69,13 @@
 
 # Get help
 
-For example:
-
-    slynx --help
+    cabal exec slynx -- --help
+    # OR: stack exec slynx -- --help
+    # OR: slynx --help
 
     ELynx Suite version 0.6.0.0.
     Developed by Dominik Schrempf.
-    Compiled on September 3, 2021, at 20:56 pm, UTC.
+    Compiled on September 4, 2021, at 12:58 pm, UTC.
     
     Usage: slynx [-v|--verbosity VALUE] [-o|--output-file-basename NAME] 
                  [-f|--force] [--no-elynx-file] COMMAND
@@ -113,6 +113,7 @@
       - ProteinX (amino acids; including gaps)
       - ProteinS (amino acids; including gaps, and translation stops)
       - ProteinI (amino acids; including gaps, translation stops, and IUPAC codes)
+    
     ELynx
     -----
     A Haskell library and tool set for computational biology. The goal of ELynx is
@@ -126,6 +127,9 @@
     tlynx     Analyze, modify, and simulate phylogenetic trees.
     elynx     Validate and redo past analyses.
     
+    Get help for commands:
+      slynx --help
+    
     Get help for sub commands:
       slynx examine --help
 
@@ -134,11 +138,13 @@
 
 The documentation of sub commands can be accessed separately:
 
-    slynx simulate --help
+    cabal exec slynx -- simulate --help
+    # OR: stack exec slynx -- simulate --help
+    # OR: slynx simulate --help
 
     ELynx Suite version 0.6.0.0.
     Developed by Dominik Schrempf.
-    Compiled on September 3, 2021, at 20:56 pm, UTC.
+    Compiled on September 4, 2021, at 12:58 pm, UTC.
     
     Usage: slynx simulate (-t|--tree-file Name) [-s|--substitution-model MODEL] 
                           [-m|--mixture-model MODEL] [-e|--edm-file NAME] 
diff --git a/src/TLynx/Compare/Compare.hs b/src/TLynx/Compare/Compare.hs
--- a/src/TLynx/Compare/Compare.hs
+++ b/src/TLynx/Compare/Compare.hs
@@ -26,7 +26,10 @@
 import qualified Data.Set as S
 import qualified Data.Text as T
 import qualified Data.Text.IO as T
-import ELynx.Tools
+import ELynx.Tools.ELynx
+import ELynx.Tools.Environment
+import ELynx.Tools.Logger
+import ELynx.Tools.Options
 import ELynx.Tree
 import Graphics.Gnuplot.Simple
 import System.IO
diff --git a/src/TLynx/Compare/Options.hs b/src/TLynx/Compare/Options.hs
--- a/src/TLynx/Compare/Options.hs
+++ b/src/TLynx/Compare/Options.hs
@@ -17,7 +17,9 @@
   )
 where
 
-import ELynx.Tools
+import Data.Aeson
+import ELynx.Tools.Reproduction
+import GHC.Generics
 import Options.Applicative
 import TLynx.Parsers
 
diff --git a/src/TLynx/Connect/Connect.hs b/src/TLynx/Connect/Connect.hs
--- a/src/TLynx/Connect/Connect.hs
+++ b/src/TLynx/Connect/Connect.hs
@@ -22,7 +22,9 @@
 import qualified Data.ByteString.Lazy.Char8 as BL
 import Data.Default.Class
 import qualified Data.Set as S
-import ELynx.Tools
+import ELynx.Tools.ELynx
+import ELynx.Tools.Environment
+import ELynx.Tools.Logger
 import ELynx.Tree
 import System.IO
 import TLynx.Connect.Options
diff --git a/src/TLynx/Connect/Options.hs b/src/TLynx/Connect/Options.hs
--- a/src/TLynx/Connect/Options.hs
+++ b/src/TLynx/Connect/Options.hs
@@ -17,7 +17,9 @@
   )
 where
 
-import ELynx.Tools
+import Data.Aeson
+import ELynx.Tools.Reproduction
+import GHC.Generics
 import Options.Applicative
 import TLynx.Parsers
 
diff --git a/src/TLynx/Distance/Distance.hs b/src/TLynx/Distance/Distance.hs
--- a/src/TLynx/Distance/Distance.hs
+++ b/src/TLynx/Distance/Distance.hs
@@ -33,7 +33,10 @@
 import qualified Data.Text as T
 import qualified Data.Text.IO as T
 import qualified Data.Vector.Unboxed as V
-import ELynx.Tools
+import ELynx.Tools.ByteString
+import ELynx.Tools.ELynx
+import ELynx.Tools.Environment
+import ELynx.Tools.Logger
 import ELynx.Tree
 import Statistics.Sample
 import System.IO
diff --git a/src/TLynx/Distance/Options.hs b/src/TLynx/Distance/Options.hs
--- a/src/TLynx/Distance/Options.hs
+++ b/src/TLynx/Distance/Options.hs
@@ -20,10 +20,12 @@
   )
 where
 
+import Data.Aeson
 import qualified Data.Attoparsec.ByteString.Char8 as AC
 import qualified Data.ByteString.Char8 as BS
-import ELynx.Tools
+import ELynx.Tools.Reproduction
 import ELynx.Tree (Support (..), toSupportUnsafe)
+import GHC.Generics
 import Options.Applicative
 import TLynx.Parsers
 import Text.Printf
diff --git a/src/TLynx/Examine/Examine.hs b/src/TLynx/Examine/Examine.hs
--- a/src/TLynx/Examine/Examine.hs
+++ b/src/TLynx/Examine/Examine.hs
@@ -22,7 +22,10 @@
 import qualified Data.ByteString.Lazy.Char8 as BL
 import Data.Containers.ListUtils (nubOrd)
 import Data.List ((\\))
-import ELynx.Tools
+import ELynx.Tools.ByteString
+import ELynx.Tools.ELynx
+import ELynx.Tools.Environment
+import ELynx.Tools.Logger
 import ELynx.Tree
 import System.IO
   ( Handle,
diff --git a/src/TLynx/Examine/Options.hs b/src/TLynx/Examine/Options.hs
--- a/src/TLynx/Examine/Options.hs
+++ b/src/TLynx/Examine/Options.hs
@@ -17,7 +17,9 @@
   )
 where
 
-import ELynx.Tools
+import Data.Aeson
+import ELynx.Tools.Reproduction
+import GHC.Generics
 import Options.Applicative
 import TLynx.Parsers
 
diff --git a/src/TLynx/Grabble.hs b/src/TLynx/Grabble.hs
new file mode 100644
--- /dev/null
+++ b/src/TLynx/Grabble.hs
@@ -0,0 +1,41 @@
+-- |
+-- Module      :  TLynx.Grabble
+-- Description :  Grabble a list
+-- Copyright   :  (c) 2021 Dominik Schrempf
+-- License     :  GPL-3.0-or-later
+--
+-- Maintainer  :  dominik.schrempf@gmail.com
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- Creation date: Mon Sep  6 09:39:16 2021.
+module TLynx.Grabble
+  ( grabble,
+  )
+where
+
+import Control.Monad
+import Control.Monad.Primitive
+import Control.Monad.ST
+import Data.Vector (Vector)
+import qualified Data.Vector as V
+import qualified Data.Vector.Mutable as M
+import System.Random.MWC
+
+-- | @grabble xs m n@ is /O(m*n')/, where @n' = min n (length xs)@. Choose @n'@
+-- elements from @xs@, without replacement, and that @m@ times.
+grabble :: PrimMonad m => [a] -> Int -> Int -> Gen (PrimState m) -> m [[a]]
+grabble xs m n gen = do
+  swapss <- replicateM m $
+    forM [0 .. min (l - 1) n] $ \i -> do
+      j <- uniformR (i, l) gen
+      return (i, j)
+  return $ map (V.toList . V.take n . swapElems (V.fromList xs)) swapss
+  where
+    l = length xs - 1
+
+swapElems :: Vector a -> [(Int, Int)] -> Vector a
+swapElems xs swaps = runST $ do
+  mxs <- V.unsafeThaw xs
+  mapM_ (uncurry $ M.unsafeSwap mxs) swaps
+  V.unsafeFreeze mxs
diff --git a/src/TLynx/Options.hs b/src/TLynx/Options.hs
--- a/src/TLynx/Options.hs
+++ b/src/TLynx/Options.hs
@@ -11,14 +11,12 @@
 -- Portability :  portable
 --
 -- Creation date: Sat Sep  7 18:55:03 2019.
-module TLynx.Options
-  ( Arguments (..),
-    CommandArguments (..),
-    parseArguments,
-  )
-where
+module TLynx.Options (CommandArguments (..)) where
 
-import ELynx.Tools
+import Data.Aeson
+import ELynx.Tools.Options
+import ELynx.Tools.Reproduction
+import GHC.Generics
 import Options.Applicative
 import TLynx.Compare.Options
 import TLynx.Connect.Options
diff --git a/src/TLynx/Parsers.hs b/src/TLynx/Parsers.hs
--- a/src/TLynx/Parsers.hs
+++ b/src/TLynx/Parsers.hs
@@ -19,7 +19,7 @@
 where
 
 import Data.List
-import ELynx.Tools
+import ELynx.Tools.InputOutput
 import ELynx.Tree
 import Options.Applicative
 
@@ -74,7 +74,7 @@
             ++ "; default: Standard; for detailed help, see 'tlynx --help'"
         )
   where
-    nwfs = map show (allValues :: [NewickFormat])
+    nwfs = map show ([minBound ..] :: [NewickFormat])
     nwlist = intercalate ", " (init nwfs) <> ", or " <> last nwfs
 
 -- | Help for different 'NewickFormat's.
@@ -82,7 +82,7 @@
 newickHelp =
   map
     (toListItem . describeNewickFormat)
-    (allValues :: [NewickFormat])
+    ([minBound ..] :: [NewickFormat])
     ++ ["- Nexus file including Newick trees"]
   where
     toListItem = ("- Newick " ++)
diff --git a/src/TLynx/Shuffle/Options.hs b/src/TLynx/Shuffle/Options.hs
--- a/src/TLynx/Shuffle/Options.hs
+++ b/src/TLynx/Shuffle/Options.hs
@@ -17,7 +17,10 @@
   )
 where
 
-import ELynx.Tools
+import Data.Aeson
+import ELynx.Tools.Options
+import ELynx.Tools.Reproduction
+import GHC.Generics
 import Options.Applicative
 import TLynx.Parsers
 
diff --git a/src/TLynx/Shuffle/Shuffle.hs b/src/TLynx/Shuffle/Shuffle.hs
--- a/src/TLynx/Shuffle/Shuffle.hs
+++ b/src/TLynx/Shuffle/Shuffle.hs
@@ -25,7 +25,11 @@
 import Control.Monad.IO.Class (liftIO)
 import Control.Monad.Trans.Reader (ask)
 import qualified Data.ByteString.Lazy.Char8 as BL
-import ELynx.Tools
+import ELynx.Tools.Definitions
+import ELynx.Tools.ELynx
+import ELynx.Tools.Environment
+import ELynx.Tools.Logger
+import ELynx.Tools.Reproduction
 import ELynx.Tree
 import ELynx.Tree.Simulate.PointProcess
   ( PointProcess (PointProcess),
@@ -33,6 +37,7 @@
   )
 import System.IO (hClose)
 import System.Random.MWC (GenIO, initialize)
+import TLynx.Grabble
 import TLynx.Parsers
 import TLynx.Shuffle.Options
 
diff --git a/src/TLynx/Simulate/Options.hs b/src/TLynx/Simulate/Options.hs
--- a/src/TLynx/Simulate/Options.hs
+++ b/src/TLynx/Simulate/Options.hs
@@ -22,10 +22,13 @@
   )
 where
 
+import Data.Aeson
 import Data.List
 import Data.Maybe
-import ELynx.Tools
+import ELynx.Tools.Options
+import ELynx.Tools.Reproduction
 import ELynx.Tree.Simulate.PointProcess (TimeSpec (..))
+import GHC.Generics
 import Options.Applicative
 
 deriving instance Eq TimeSpec
diff --git a/src/TLynx/Simulate/Simulate.hs b/src/TLynx/Simulate/Simulate.hs
--- a/src/TLynx/Simulate/Simulate.hs
+++ b/src/TLynx/Simulate/Simulate.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TemplateHaskell #-}
 {-# LANGUAGE TupleSections #-}
 
@@ -31,6 +32,7 @@
   )
 import Control.Monad
 import Control.Monad.IO.Class
+import Control.Monad.Primitive
 import Control.Monad.Trans.Reader hiding (local)
 import Control.Parallel.Strategies
 import qualified Data.ByteString.Builder as BB
@@ -39,12 +41,36 @@
 import Data.Maybe
 import qualified Data.Sequence as Seq
 import qualified Data.Set as Set
-import ELynx.Tools
+import qualified Data.Vector.Unboxed as VU
+import Data.Word
+import ELynx.Tools.ELynx
+import ELynx.Tools.Environment
+import ELynx.Tools.Logger
+import ELynx.Tools.Reproduction
 import ELynx.Tree
 import qualified ELynx.Tree.Simulate.Coalescent as CS
 import qualified ELynx.Tree.Simulate.PointProcess as PP
 import System.Random.MWC
+import TLynx.Grabble
 import TLynx.Simulate.Options
+
+-- Split a generator.
+splitGen :: PrimMonad m => Int -> Gen (PrimState m) -> m [Gen (PrimState m)]
+splitGen n gen
+  | n <= 0 = return []
+  | otherwise = do
+    seeds :: [VU.Vector Word32] <- replicateM (n -1) $ uniformVector gen 256
+    fmap (gen :) (mapM initialize seeds)
+
+-- For a given number of capabilities and number of calculations, get chunk
+-- sizes. The chunk sizes will be as evenly distributed as possible and sum up
+-- to the number of calculations.
+getChunks :: Int -> Int -> [Int]
+getChunks c n = ns
+  where
+    n' = n `div` c
+    r = n `mod` c
+    ns = replicate r (n' + 1) ++ replicate (c - r) n'
 
 -- | Simulate phylogenetic trees using birth and death process.
 simulate :: ELynx SimulateArguments ()
diff --git a/src/TLynx/TLynx.hs b/src/TLynx/TLynx.hs
--- a/src/TLynx/TLynx.hs
+++ b/src/TLynx/TLynx.hs
@@ -15,7 +15,8 @@
   )
 where
 
-import ELynx.Tools
+import ELynx.Tools.ELynx
+import ELynx.Tools.Options
 import TLynx.Compare.Compare
 import TLynx.Connect.Connect
 import TLynx.Distance.Distance
diff --git a/tlynx.cabal b/tlynx.cabal
--- a/tlynx.cabal
+++ b/tlynx.cabal
@@ -1,6 +1,6 @@
 cabal-version:  2.2
 name:           tlynx
-version:        0.6.0.0
+version:        0.6.1.0
 synopsis:       Handle phylogenetic trees
 description:    Examine, compare, and simulate phylogenetic trees in a reproducible way. Please see the README on GitHub at <https://github.com/dschrempf/elynx>.
 category:       Bioinformatics
@@ -31,6 +31,7 @@
       TLynx.Distance.Options
       TLynx.Examine.Examine
       TLynx.Examine.Options
+      TLynx.Grabble
       TLynx.Options
       TLynx.Parsers
       TLynx.Shuffle.Options
@@ -59,6 +60,7 @@
     , mwc-random
     , optparse-applicative
     , parallel
+    , primitive
     , statistics
     , text
     , transformers
