diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,5 @@
+# Revision history for prettyprinter-vty
+
+## 0.1.0.0  -- 2017-06-05
+
+* First version. Released on an unsuspecting world.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,13 @@
+Copyright (c) 2017 Eric Mertens
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
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/prettyprinter-vty.cabal b/prettyprinter-vty.cabal
new file mode 100644
--- /dev/null
+++ b/prettyprinter-vty.cabal
@@ -0,0 +1,22 @@
+name:                prettyprinter-vty
+version:             0.1.0.0
+synopsis:            prettyprinter backend for vty
+description:         prettyprinter backend for vty
+license:             ISC
+license-file:        LICENSE
+author:              Eric Mertens
+maintainer:          emertens@gmail.com
+copyright:           2017 Eric Mertens
+category:            Graphics
+build-type:          Simple
+extra-source-files:  ChangeLog.md
+cabal-version:       >=1.10
+tested-with:         GHC==8.0.2, GHC==8.2.1
+
+library
+  exposed-modules:     Data.Text.Prettyprint.Doc.Render.Vty
+  build-depends:       base >=4.9 && <4.11,
+                       prettyprinter >=1.0.1 && <1.1,
+                       vty >=5.15.1 && < 5.16
+  hs-source-dirs:      src
+  default-language:    Haskell2010
diff --git a/src/Data/Text/Prettyprint/Doc/Render/Vty.hs b/src/Data/Text/Prettyprint/Doc/Render/Vty.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Text/Prettyprint/Doc/Render/Vty.hs
@@ -0,0 +1,54 @@
+{-|
+Module      : Data.Text.Prettyprint.Doc.Render.Vty
+Description : Rending prettyprinter Doc to Vty image
+Copyright   : (c) Eric Mertens, 2017
+License     : ISC
+Maintainer  : emertens@gmail.com
+
+-}
+module Data.Text.Prettyprint.Doc.Render.Vty
+  ( render, renderSDS
+  , VtyDocError(..)
+  ) where
+
+import Control.Exception
+import Graphics.Vty.Attributes
+import Graphics.Vty.Image
+import Data.Text.Prettyprint.Doc
+
+-- | Errors that can occur due to bugs in the layout logic
+data VtyDocError
+  = VtyDocFail   -- ^ SimpleDocStream contained 'SFail'
+  | VtyDocBadAnn -- ^ SimpleDocStream had too many 'SAnnPop'
+  deriving (Eq, Ord, Show, Read)
+
+-- | 'displayException' provides human readable description.
+instance Exception VtyDocError where
+  displayException VtyDocFail   = "Encountered failure in simple document stream while rendering to VTY"
+  displayException VtyDocBadAnn = "Encountered mismatched annotations while rendering to VTY"
+
+-- | Render a document as a VTY image using 'defaultLayoutOptions'.
+--
+-- Throws: 'VtyDocError'
+render :: Doc Attr -> Image
+render = renderSDS . layoutPretty defaultLayoutOptions
+
+-- | Render a document stream as a VTY image.
+--
+-- Throws: 'VtyDocError'
+renderSDS :: SimpleDocStream Attr -> Image
+renderSDS = go defAttr [] emptyImage
+
+go :: Attr -> [Attr] -> Image -> SimpleDocStream Attr -> Image
+go attr stack line d =
+  case d of
+    SFail         -> throw VtyDocFail
+    SEmpty        -> line
+    SChar c x     -> go attr stack (line <|> char attr c) x
+    SText _ txt x -> go attr stack (line <|> text' attr txt) x
+    SLine n x     -> line <-> go attr stack (string mempty (replicate n ' ')) x
+    SAnnPush a x  -> go a (attr:stack) line x
+    SAnnPop x     ->
+      case stack of
+        []   -> throw VtyDocBadAnn
+        a:as -> go a as line x
