diff --git a/Stack.cabal b/Stack.cabal
--- a/Stack.cabal
+++ b/Stack.cabal
@@ -1,22 +1,25 @@
 name:                Stack
-version:             0.2.0
-synopsis:            Stack data structure type
-description:         Please see README.md
+version:             0.3.0
+synopsis:            Stack data structure
+description:         A stack is a basic data structure that can be logically thought as linear structure represented by a real physical stack or pile, a structure where insertion and deletion of items takes place at one end called top of the stack.
+                     .
+                     <<https://upload.wikimedia.org/wikipedia/commons/b/b4/Lifo_stack.png>>
 homepage:            https://en.wikipedia.org/wiki/Stack_(abstract_data_type)
 license:             BSD3
 license-file:        LICENSE
 author:              Robert Walker
 maintainer:          rwlock404@yahoo.com
 copyright:           2016 Robert Walker
-category:            Web
+category:            Data Structures
 build-type:          Simple
 cabal-version:       >=1.10
 
 library
   hs-source-dirs:      src
-  exposed-modules:     Data.Stack
-  build-depends:       base >= 4.7 && < 5
+  exposed-modules:     Data.Stack, Control.Concurrent.STM.Stack, Control.Concurrent.Stack
+  build-depends:       base >= 4.7 && < 5, nats, stm
   default-language:    Haskell2010
+  ghc-options: -Wall
 
 source-repository head
   type:     git
diff --git a/src/Control/Concurrent/STM/Stack.hs b/src/Control/Concurrent/STM/Stack.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Concurrent/STM/Stack.hs
@@ -0,0 +1,84 @@
+-- | Provides a synchronized stack for use in the STM monad
+--
+-- See also "Control.Concurrent.Stack"
+module Control.Concurrent.STM.Stack (
+    Stack,
+    stackNew,
+    stackPush,
+    stackPeek,
+    stackTryPeek,
+    stackPop,
+    stackTryPop,
+    stackIsEmpty,
+    stackSize,
+  )
+  where
+
+import Control.Concurrent.STM.TVar
+import Control.Monad.STM
+import Numeric.Natural
+
+-- | Synchronized stack data type
+data Stack a = Stack (TVar [a])
+
+-- | Create new Stack
+stackNew :: STM (Stack a)
+stackNew = do
+    items <- newTVar []
+    return (Stack items)
+
+-- | Push item onto Stack
+stackPush :: Stack a -> a -> STM ()
+stackPush (Stack itemsVar) item = do
+    items <- readTVar itemsVar
+    writeTVar itemsVar (item:items)
+
+-- | Pop most recently added item without removing from the Stack
+stackTryPeek :: Stack a -> STM (Maybe a)
+stackTryPeek (Stack itemsVar) = do
+    items <- readTVar itemsVar
+    if null items
+        then return Nothing
+        else return (Just (head items))
+
+-- | Pop most recently added item without removing from the Stack
+--
+-- Automatically retries if stack is empty
+stackPeek :: Stack a -> STM a
+stackPeek (Stack itemsVar) = do
+    items <- readTVar itemsVar
+    if null items
+        then retry
+        else return (head items)
+
+-- | Pop most recently added item from Stack
+stackTryPop :: Stack a -> STM (Maybe a)
+stackTryPop (Stack itemsVar) = do
+    items <- readTVar itemsVar
+    if null items
+        then return Nothing
+        else do writeTVar itemsVar (tail items)
+                return (Just (head items))
+
+-- | Pop most recently added item from Stack
+--
+-- Automatically retries if stack is empty
+stackPop :: Stack a -> STM a
+stackPop (Stack itemsVar) = do
+    items <- readTVar itemsVar
+    if null items
+        then retry
+        else do writeTVar itemsVar (tail items)
+                return (head items)
+
+-- | Test if stack is empty
+stackIsEmpty :: Stack a -> STM Bool
+stackIsEmpty (Stack itemsVar) = do
+    items <- readTVar itemsVar
+    if null items then return True else return False
+
+-- | Compute number of elements contained in the Stack
+stackSize :: Stack a -> STM Natural
+stackSize (Stack itemsVar) = do
+    items <- readTVar itemsVar
+    return (fromIntegral (length items))
diff --git a/src/Control/Concurrent/Stack.hs b/src/Control/Concurrent/Stack.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Concurrent/Stack.hs
@@ -0,0 +1,57 @@
+-- | Provides a synchronized stack for use in the IO monad
+--
+-- See also "Control.Concurrent.STM.Stack"
+module Control.Concurrent.Stack (
+    Stack,
+    stackNew,
+    stackPush,
+    stackPeek,
+    stackTryPeek,
+    stackPop,
+    stackTryPop,
+    stackIsEmpty,
+    stackSize,
+  )
+  where
+
+import Control.Monad.STM
+import Numeric.Natural
+
+import qualified Control.Concurrent.STM.Stack as STM
+import Control.Concurrent.STM.Stack (Stack)
+
+-- | Create new Stack
+stackNew :: IO (Stack a)
+stackNew = atomically STM.stackNew
+
+-- | Push item onto Stack
+stackPush :: Stack a -> a -> IO ()
+stackPush stack item = atomically (STM.stackPush stack item)
+
+-- | Pop most recently added item without removing from the Stack
+stackTryPeek :: Stack a -> IO (Maybe a)
+stackTryPeek stack = atomically (STM.stackTryPeek stack)
+
+-- | Pop most recently added item without removing from the Stack
+--
+-- Blocks if stack is empty
+stackPeek :: Stack a -> IO a
+stackPeek stack = atomically (STM.stackPeek stack)
+
+-- | Pop most recently added item from Stack
+stackTryPop :: Stack a -> IO (Maybe a)
+stackTryPop stack = atomically (STM.stackTryPop stack)
+
+-- | Pop most recently added item from Stack
+--
+-- Blocks if stack is empty
+stackPop :: Stack a -> IO a
+stackPop stack = atomically (STM.stackPop stack)
+
+-- | Test if stack is empty
+stackIsEmpty :: Stack a -> IO Bool
+stackIsEmpty stack = atomically (STM.stackIsEmpty stack)
+
+-- | Compute number of elements contained in the Stack
+stackSize :: Stack a -> IO Natural
+stackSize stack = atomically (STM.stackSize stack)
diff --git a/src/Data/Stack.hs b/src/Data/Stack.hs
--- a/src/Data/Stack.hs
+++ b/src/Data/Stack.hs
@@ -1,6 +1,12 @@
--- | Abstract Stack data type
+-- | Stack data structure and associated operations
 --
--- <https://en.wikipedia.org/wiki/Stack_(abstract_data_type)>
+-- A stack is a basic data structure that can be logically thought as linear structure represented by a real physical stack or pile, a structure where insertion and deletion of items takes place at one end called top of the stack.
+--
+-- In other words, a 'Stack' is an abstract data type that serves as a collection of elements, with two principal operations: 'stackPush', which adds an element to the collection, and 'stackPop', which removes the most recently added element that was not yet removed.
+--
+-- <<https://upload.wikimedia.org/wikipedia/commons/b/b4/Lifo_stack.png>>
+--
+-- See also <https://en.wikipedia.org/wiki/Stack_(abstract_data_type)>
 module Data.Stack (
     Stack,
     stackNew,
@@ -12,6 +18,8 @@
   )
   where
 
+import Numeric.Natural
+
 -- | Abstract Stack data type
 data Stack a = Stack [a] deriving (Read,Show)
 
@@ -55,5 +63,5 @@
 --
 -- > stackSize stackNew == 0
 -- > (∀x)(∀s)((stackSize s == n) ⇒ (stackSize (stackPush s x) == n+1))
-stackSize :: Stack a -> Int
-stackSize (Stack items) = length items
+stackSize :: Stack a -> Natural
+stackSize (Stack items) = fromIntegral (length items)
