diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@
 executable your-executable
   language:           Haskell2010
   default-extensions: NoImplicitPrelude
-  build-depends:      preliminaries >= 0.1.4 < 1
+  build-depends:      preliminaries >= 0.1.5 < 1
   …
 ```
 
diff --git a/preliminaries.cabal b/preliminaries.cabal
--- a/preliminaries.cabal
+++ b/preliminaries.cabal
@@ -1,5 +1,5 @@
 name:                preliminaries
-version:             0.1.4.0
+version:             0.1.5.0
 synopsis:            A larger alternative to the Prelude.
 description:         A GHC-only alternative to the Prelude with a large amount of imports available by default.
 homepage:            http://github.com/kerscher/preliminaries
@@ -59,10 +59,9 @@
                      , ExplicitNamespaces
   exposed-modules:     Preliminaries
   ghc-options:         -Wall
-                       -fno-warn-unused-imports
-                       -fno-warn-dodgy-exports
   build-depends:       classy-prelude-conduit     >= 1.0.0 && < 2
                      , abstract-par               >= 0.3.3 && < 1
+                     , base                       >= 4.9.0 && < 5
                      , bifunctors                 >= 5.4.1 && < 6
                      , data-default               >= 0.7.1 && < 1
                      , microlens-platform         >= 0.3.7 && < 1
diff --git a/source/Preliminaries.hs b/source/Preliminaries.hs
--- a/source/Preliminaries.hs
+++ b/source/Preliminaries.hs
@@ -26,7 +26,7 @@
 @
 …
 default-extensions: NoImplicitPrelude
-build-depends:      preliminaries >= 0.1.4 < 1
+build-depends:      preliminaries >= 0.1.5 < 1
 @
 
 And on each file, add @import Preliminaries@.
@@ -52,11 +52,11 @@
 , module Data.Conduit.TQueue
   -- * Parallelism
   {- |
-Using multiple available resource in a device to compute a result is what parallelism is about. Whenever you want to chop your data so that many cores calculate parts of it and bring about a result, you want what the imports here.
+Using multiple available resources in a device to compute a result is what parallelism is about. Whenever you want to chop your data so that many cores calculate parts of it and bring about a result, you want what the imports here.
 
 'Control.Monad.Par' provides fine-grained control, while 'Control.Monad.Parallel' provides a simple interface to create 'Control.Parallel.Strategies' to parallelise execution. In general it's easier to start with 'Parallel' and switch to 'Par' when more control is needed.
 
-Since the names used by both modules are similar, this module prefix `par` to all 'Control.Monad.Par' functions that would conflict with 'Control.Parallel'.
+Since the names used by both modules are similar, this module prefixes `par` to all 'Control.Monad.Par' functions that would conflict with 'Control.Parallel'.
   -}
 , module Control.Monad.Par
 , parFork
@@ -81,6 +81,15 @@
 , module Control.Monad.Reader
 , module Control.Monad.State.Lazy
 , module Control.Monad.Writer.Lazy
+  -- * System interface
+  {- |
+Terminate your programs with 'exitFailure' or 'exitSuccess'.
+
+You should ensure any scarce resources that outlive program termination are freed with appropriate 'Control.Exception.Safe' functions such as 'onException', 'bracket', 'bracket_', 'finally', 'withException', 'bracketOnError' or 'bracketOnError_'.
+  -}
+, module System.Environment
+, getEnvironmentMap
+, module System.Exit
   -- * Re-exports
 , module ClassyPrelude.Conduit
 , module Data.Biapplicative
@@ -122,6 +131,9 @@
 import Data.String.Conversions   (ConvertibleStrings, cs)
 import Lens.Micro.Platform
 import Lens.Micro.Contra
+import qualified System.Environment as SE
+import System.Environment        (getEnv, lookupEnv, setEnv, unsetEnv)
+import System.Exit               (exitFailure, exitSuccess)
 
 parFork :: Par () -> Par ()
 parFork = Par.fork
@@ -144,7 +156,18 @@
 parParMap :: (Traversable t, NFData b, ParFuture iv p) => (a -> b) -> t a -> p (t b)
 parParMap = Par.parMap
 
+-- | A synonym for 'Strategies.using'.
 thru :: a -> Strategy a -> a
 x `thru` strat = x `Strategies.using` strat
 
+-- | Retrieves the current list of environment variables as a 'Map' of keys for variable names and values for current assignment of each variable.
+--
+-- This is a single action. If you need to keep this structure in sync with system environment, it's your responsibility to call it again. Consider either calling a specific variable with 'getEnv' when you need it, or keep this structure in a 'TVar' and refresh it manually.
+getEnvironmentMap :: IO (Map String String)
+getEnvironmentMap = SE.getEnvironment >>= pure . mapFromList
+
+-- | This allows you to avoid parentheses in type declarations:
+--
+-- > f :: h (g (f a b)) -> g (h (f a b))
+-- > f :: h $ g $ f a b -> g $ h $ f a b
 type f $ x = f x
