diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,31 @@
+Copyright 2012 Roel van Dijk
+
+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.
+
+    * The name of Roel van Dijk and the names of contributors may NOT
+      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/README.markdown b/README.markdown
new file mode 100644
--- /dev/null
+++ b/README.markdown
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/src/System/ProgressBar.hs b/src/System/ProgressBar.hs
new file mode 100644
--- /dev/null
+++ b/src/System/ProgressBar.hs
@@ -0,0 +1,149 @@
+{-# LANGUAGE NoImplicitPrelude, PackageImports, UnicodeSyntax #-}
+
+module System.ProgressBar
+    ( -- * Progress bars
+      progressBar
+    , mkProgressBar
+      -- * Labels
+    , Label
+    , noLabel
+    , msg
+    , percentage
+    , exact
+    ) where
+
+import "base" Data.Bool     ( otherwise )
+import "base" Data.Function ( ($) )
+import "base" Data.List     ( null, length, genericLength, genericReplicate )
+import "base" Data.Ord      ( min, max )
+import "base" Data.Ratio    ( (%) )
+import "base" Data.String   ( String )
+import "base" Prelude       ( (+), (-), round, floor )
+import "base" System.IO     ( IO, putStr, putChar )
+import "base" Text.Printf   ( printf )
+import "base" Text.Show     ( show )
+import "base-unicode-symbols" Data.Bool.Unicode ( (∧) )
+import "base-unicode-symbols" Data.Eq.Unicode   ( (≢) )
+import "base-unicode-symbols" Prelude.Unicode   ( ℤ, ℚ, (⋅) )
+
+
+-- | Print a progress bar
+--
+-- Erases the current line! (by outputting '\r') Does not print a
+-- newline '\n'. Subsequent invocations will overwrite the previous
+-- output.
+--
+-- Remember to set the correct buffering mode for stdout:
+--
+-- > import System.IO ( hSetBuffering, BufferMode(NoBuffering), stdout )
+-- > hSetBuffering stdout NoBuffering
+progressBar ∷ Label -- ^ Prefixed label.
+            → Label -- ^ Postfixed label.
+            → ℤ     -- ^ Total progress bar width in characters.
+            → ℤ     -- ^ Amount of work completed.
+            → ℤ     -- ^ Total amount of work.
+            → IO ()
+progressBar mkPreLabel mkPostLabel width todo done = do
+    putChar '\r'
+    putStr $ mkProgressBar mkPreLabel mkPostLabel width todo done
+
+-- | Renders a progress bar
+--
+-- >>> mkProgressBar (msg "Working") percentage 40 30 100
+-- "Working [=======>.................]  30%"
+mkProgressBar ∷ Label -- ^ Prefixed label.
+              → Label -- ^ Postfixed label.
+              → ℤ     -- ^ Total progress bar width in characters.
+              → ℤ     -- ^ Amount of work completed.
+              → ℤ     -- ^ Total amount of work.
+              → String
+mkProgressBar mkPreLabel mkPostLabel width todo done =
+    printf "%s%s[%s%s%s]%s%s"
+           preLabel
+           prePad
+           (genericReplicate completed '=')
+           (if remaining ≢ 0 ∧ completed ≢ 0 then ">" else "")
+           (genericReplicate (remaining - if completed ≢ 0 then 1 else 0)
+                             '.'
+           )
+           postPad
+           postLabel
+  where
+    -- Amount of work completed.
+    fraction ∷ ℚ
+    fraction | done ≢ 0  = todo % done
+             | otherwise = 0 % 1
+
+    -- Amount of characters available to visualize the progress.
+    effectiveWidth = max 0 $ width - usedSpace
+    usedSpace = 2 + genericLength preLabel
+                  + genericLength postLabel
+                  + genericLength prePad
+                  + genericLength postPad
+
+    -- Number of characters needed to represent the amount of work
+    -- that is completed. Note that this can not always be represented
+    -- by an integer.
+    numCompletedChars ∷ ℚ
+    numCompletedChars = fraction ⋅ (effectiveWidth % 1)
+
+    completed, remaining ∷ ℤ
+    completed = min effectiveWidth $ floor numCompletedChars
+    remaining = effectiveWidth - completed
+
+    preLabel, postLabel ∷ String
+    preLabel  = mkPreLabel  todo done
+    postLabel = mkPostLabel todo done
+
+    prePad, postPad ∷ String
+    prePad  = pad preLabel
+    postPad = pad postLabel
+
+    pad ∷ String → String
+    pad s | null s    = ""
+          | otherwise = " "
+
+
+-- | A label that can be pre- or postfixed to a progress bar.
+type Label = ℤ → ℤ → String
+
+-- | The empty label.
+--
+-- >>> noLabel 30 100
+-- ""
+noLabel ∷ Label
+noLabel = msg ""
+
+-- | A label consisting of a static string.
+--
+-- >>> msg "foo" 30 100
+-- "foo"
+msg ∷ String → Label
+msg s _ _ = s
+
+-- | A label which displays the progress as a percentage.
+--
+-- Constant width property:
+-- &#x2200; d t : &#x2115;. d &#x2264; t &#x2192; length (percentage d t) &#x2261; 4
+--
+-- >>> percentage 30 100
+-- " 30%"
+
+-- ∀ d t : ℕ. d ≤ t → length (percentage d t) ≡ 3
+percentage ∷ Label
+percentage done todo = printf "%3i%%" (round (done % todo ⋅ 100) ∷ ℤ)
+
+-- | A label which displays the progress as a fraction of the total
+-- amount of work.
+--
+-- Equal width property:
+-- &#x2200; d&#x2081; d&#x2082; t : &#x2115;. d&#x2081; &#x2264; d&#x2082; &#x2264; t &#x2192; length (exact d&#x2081; t) &#x2261; length (exact d&#x2082; t)
+--
+-- >>> exact 30 100
+-- " 30/100"
+
+-- ∀ d₁ d₂ t : ℕ. d₁ ≤ d₂ ≤ t → length (exact d₁ t) ≡ length (exact d₂ t)
+exact ∷ Label
+exact done total = printf "%*i/%s" (length totalStr) done totalStr
+  where
+    totalStr = show total
diff --git a/terminal-progress-bar.cabal b/terminal-progress-bar.cabal
new file mode 100644
--- /dev/null
+++ b/terminal-progress-bar.cabal
@@ -0,0 +1,71 @@
+name:          terminal-progress-bar
+version:       0.0.1
+cabal-version: >=1.8
+build-type:    Simple
+stability:     provisional
+author:        Roel van Dijk <vandijk.roel@gmail.com>
+maintainer:    Roel van Dijk <vandijk.roel@gmail.com>
+copyright:     2012 Roel van Dijk <vandijk.roel@gmail.com>
+license:       BSD3
+license-file:  LICENSE
+category:      System, User Interfaces
+homepage:      https://github.com/roelvandijk/terminal-progress-bar
+bug-reports:   https://github.com/roelvandijk/terminal-progress-bar/issues
+synopsis:      A simple progress bar in the terminal
+description:
+  A progress bar is used to convey the progress of a task. This
+  package implements a very simple textual progress bar.
+  .
+  See the module 'System.ProgressBar' on how to use the progress bar
+  or build the package with the -fexample flag for a small example
+  program.
+  .
+  The animated progress bar depends entirely on the interpretation of
+  the carriage return character (\'\r\'). If your terminal interprets
+  it as something else then "move cursor to beginning of line", the
+  animation won't work.
+  .
+  Note: Due to a bug in \"cabal haddock\" you will have to manually
+  uncomment the example section in the cabal file. But uncommenting
+  that section will result in \"cabal haddock\" failing.
+
+extra-source-files: LICENSE, README.markdown
+
+source-repository head
+  type:     git
+  location: git://github.com/roelvandijk/terminal-progress-bar.git
+
+flag example
+  description: Build a small example program.
+  default: False
+
+library
+    hs-source-dirs: src
+    build-depends: base                 >= 3.0.3.1 && < 4.6
+                 , base-unicode-symbols >= 0.2.2.3 && < 0.3
+    exposed-modules: System.ProgressBar
+    ghc-options: -Wall
+
+test-suite test-terminal-progress-bar
+  type: exitcode-stdio-1.0
+  main-is: test.hs
+  hs-source-dirs: test
+  ghc-options: -Wall
+  build-depends: base                  >= 3.0.3.1 && < 4.6
+               , base-unicode-symbols  >= 0.2.2.3 && < 0.3
+               , HUnit                 >= 1.2.4.2 && < 1.3
+               , terminal-progress-bar == 0.0.1
+               , test-framework        >= 0.3.3   && < 0.5
+               , test-framework-hunit  >= 0.2.6   && < 0.3
+
+-- executable example
+--   main-is: example.hs
+--   hs-source-dirs: .
+--   if flag(example)
+--     build-depends: base                  >= 3.0.3.1 && < 4.6
+--                  , base-unicode-symbols  >= 0.2.2.3 && < 0.3
+--                  , terminal-progress-bar == 0.0.1
+--     buildable: True
+--   else
+--     buildable: False
+
