diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,5 @@
+# Changelog for Monadoro
+
+1. Switch to literate Haskell in library.
+
+## Unreleased changes
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Patryk Kocielnik (c) 2019
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Author name here nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Monadoro.cabal b/Monadoro.cabal
new file mode 100644
--- /dev/null
+++ b/Monadoro.cabal
@@ -0,0 +1,76 @@
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.31.1.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 4b98957d0b69d80e1f8606e29e074682e5a5a99aaa68fbbc23cce5c67f631cea
+
+name:           Monadoro
+version:        0.1.1.0
+synopsis:       A minimalistic CLI Pomodoro timer, based on a library of the same purpose.
+description:    Please see the README on GitLab at <https://gitlab.com/kocielnik/monadoro#readme>
+category:       Tools
+homepage:       https://github.com/gitlab.com/kocielnik#readme
+bug-reports:    https://github.com/gitlab.com/kocielnik/issues
+author:         Patryk Kocielnik
+maintainer:     patryk@kocielnik.pl
+copyright:      2019 Patryk Kocielnik
+license:        MIT
+license-file:   LICENSE
+build-type:     Simple
+extra-source-files:
+    README.md
+    ChangeLog.md
+
+source-repository head
+  type: git
+  location: https://github.com/gitlab.com/kocielnik
+  subdir: monadoro
+
+library
+  exposed-modules:
+      Lib
+      Pomodoro
+      Timer
+  other-modules:
+      Paths_Monadoro
+  hs-source-dirs:
+      src
+  build-depends:
+      ansi-terminal >=0.8 && <1
+    , base >=4.7 && <5
+    , process >=1.6 && <2
+    , time >=1.8 && <2
+  default-language: Haskell2010
+
+executable monadoro
+  main-is: Main.hs
+  other-modules:
+      Paths_Monadoro
+  hs-source-dirs:
+      app
+  ghc-options: -threaded -rtsopts -with-rtsopts=-N
+  build-depends:
+      Monadoro
+    , ansi-terminal >=0.8 && <1
+    , base >=4.7 && <5
+    , process >=1.6 && <2
+    , time >=1.8 && <2
+  default-language: Haskell2010
+
+test-suite Monadoro-test
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  other-modules:
+      Paths_Monadoro
+  hs-source-dirs:
+      test
+  ghc-options: -threaded -rtsopts -with-rtsopts=-N
+  build-depends:
+      Monadoro
+    , ansi-terminal >=0.8 && <1
+    , base >=4.7 && <5
+    , process >=1.6 && <2
+    , time >=1.8 && <2
+  default-language: Haskell2010
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+# Monadoro
+
+A Pomodoro timer to track work time in 4-pomodoro sessions.
+
+To run, execute `monadoro`.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/app/Main.hs b/app/Main.hs
new file mode 100644
--- /dev/null
+++ b/app/Main.hs
@@ -0,0 +1,7 @@
+module Main where
+
+import Pomodoro ( worker )
+
+main :: IO ()
+main = worker
+
diff --git a/src/Lib.hs b/src/Lib.hs
new file mode 100644
--- /dev/null
+++ b/src/Lib.hs
@@ -0,0 +1,6 @@
+module Lib
+    ( someFunc
+    ) where
+
+someFunc :: IO ()
+someFunc = putStrLn "someFunc"
diff --git a/src/Pomodoro.lhs b/src/Pomodoro.lhs
new file mode 100644
--- /dev/null
+++ b/src/Pomodoro.lhs
@@ -0,0 +1,80 @@
+#!/usr/bin/env stack
+> --stack --install-ghc runghc --package markdown-unlit -- "-pgmL markdown-unlit"
+
+> {-# LANGUAGE OverloadedStrings #-}
+
+This is a command-line Pomodoro counter.
+
+> module Pomodoro (worker) where
+
+> import Control.Concurrent (threadDelay)
+> import System.Process (system, rawSystem)
+> import System.Console.ANSI (clearLine,
+>                             clearFromCursorToScreenEnd,
+>                             setCursorColumn,
+>                             hideCursor,
+>                             showCursor,
+>                             saveCursor,
+>                             restoreCursor,
+>                            )
+> import System.Environment (getArgs)
+> import System.IO (
+>                   hFlush,
+>                   stdout)
+> import Timer (secToTimestamp)
+>  
+> data Pomodoro = First | Second | Third | Fourth
+>     deriving (Eq, Ord, Show, Read, Bounded, Enum)
+>  
+> pom m = do
+>     putStr $ show m ++ " pomodoro" ++ " | "
+>     saveCursor
+>     wait_seconds $ 25 * 60 + 1
+>     restoreCursor
+>     putStrLn "Finished, take a 5 minute rest."
+
+> to_work = do
+>     saveCursor
+>     putStr "Get back to work"
+>     delay 2
+>     restoreCursor
+>     clearLine
+> pomodoro Fourth = do
+>     pom Fourth
+>     putStrLn "Take a 30-minute rest now. You just completed 4 pomodoros."
+>     putStrLn "Thank you for tracking your time with Haskomodoro."
+> pomodoro m = do
+>     pom m
+>     delay $ 5 * 60
+>     to_work
+>     pomodoro $ succ m
+>  
+> wait_seconds :: Int -> IO()
+> wait_seconds 0 = do
+>     putStr ""
+> wait_seconds n = do
+>     restoreCursor
+>     putStr $ secToTimestamp $ n - 1
+>     hFlush stdout
+>     delay 1
+>     wait_seconds $ n - 1
+
+> delay :: Int -> IO()
+> delay n = del n
+> 
+> del :: Int -> IO()
+> del n = do
+>     threadDelay $ n * 1000 * 1000
+>
+> no_del :: Int -> IO()
+> no_del n = do
+>     return ()
+> 
+> worker :: IO()
+> worker = do
+>     pomodoro First
+>
+> main :: IO()
+> main = do
+>     worker
+
diff --git a/src/Timer.hs b/src/Timer.hs
new file mode 100644
--- /dev/null
+++ b/src/Timer.hs
@@ -0,0 +1,30 @@
+#!/usr/bin/env stack
+--stack --install-ghc runghc
+
+{-# LANGUAGE OverloadedStrings #-}
+
+module Timer where
+
+import Data.Time.Clock.POSIX
+import Data.Time.Format
+
+{-| Given an integer number of seconds, secToTimestamp
+ returns the corresponding time in MM:SS.
+
+>>> secToTimestamp 0
+"00:00"
+>>> secToTimestamp 1500
+"25:00"
+>>> secToTimestamp 3000
+"50:00"
+-}
+
+secToTimestamp :: Int -> String
+secToTimestamp = formatTime defaultTimeLocale "%M:%S" . posixSecondsToUTCTime . fromIntegral
+
+main :: IO ()
+main = do
+    putStrLn $ secToTimestamp 0
+    putStrLn $ secToTimestamp 1500
+    putStrLn $ secToTimestamp 3000
+
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = putStrLn "Test suite not yet implemented"
