diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2015, Thomas M. DuBuisson
+
+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 Thomas M. DuBuisson 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/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,41 @@
+# friday-juicypixels
+
+This library facilitates conversion between [friday](https://github.com/RaphaelJ/friday)
+(an all-Haskell image manipulation library) and
+[JuicyPixels](https://github.com/Twinside/Juicy.Pixels) (an all-Haskell encoder/decoder
+library for many image formats). Combining these two libraries is useful for adding basic
+image manipulation capabilities of many image formats to a Haskell application without
+requiring any C libraries/headers to be installed.
+
+**NOTE:** Expect this library's API to break, as it is still very young.
+
+
+### Compared to `friday-devil`
+
+The `friday-devil` package provides a storage backend to `friday` by calling the
+[DevIL](https://github.com/DentonW/DevIL) library. It is much more mature, and probably
+a lot faster (though benchmarks have yet to prove this).
+
+This package is not in the spirit of `friday-devil` which is a more native bridge than
+conversion .  As such, it should probabably be called something different like
+`juicy-friday`.
+
+
+### TODO
+
+* Make it into a storage backend that automatically converts all formats and
+  color spaces supported by `JuicyPixels` to the internal representations
+  supported by `friday`.
+* Add some benchmarks. Include `friday-devil` and ImageMagik.
+* Add more specs.
+
+Done:
+
+* Conversion between JP and Friday for cheap using `coerce` and `unsafeCoerce`, yay!
+* Basic test suite.
+
+
+### License
+
+Released under a 3-clause BSD license.
+
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/Vision/Image/JuicyPixels.hs b/Vision/Image/JuicyPixels.hs
new file mode 100644
--- /dev/null
+++ b/Vision/Image/JuicyPixels.hs
@@ -0,0 +1,60 @@
+{-# LANGUAGE ViewPatterns #-}
+
+module Vision.Image.JuicyPixels where
+
+import Vision.Image
+import Vision.Primitive
+import Codec.Picture as JP
+import Foreign.ForeignPtr
+import Data.Vector.Storable as V
+
+fcast :: Vector (PixelBaseComponent Pixel8) -> Vector GreyPixel
+fcast v = unsafeFromForeignPtr (castForeignPtr fp) o l where (fp,o,l) = unsafeToForeignPtr v
+
+jcast :: Vector GreyPixel -> Vector (PixelBaseComponent Pixel8)
+jcast v = unsafeFromForeignPtr (castForeignPtr fp) o l where (fp,o,l) = unsafeToForeignPtr v
+
+-- XXX friday is 4 bytes per elem (1/4 the elem) while JP is 1 byte per
+-- elem for 4x the length!  We can make fcast total at
+-- the cost of an O(n) copy.  Do so and document.
+jcastRGBA :: Vector RGBAPixel -> Vector (PixelBaseComponent PixelRGBA8)
+jcastRGBA v = unsafeFromForeignPtr (castForeignPtr fp) (4*o) (4*l) where (fp,o,l) = unsafeToForeignPtr v
+
+fcastRGBA :: Vector (PixelBaseComponent PixelRGBA8) -> Vector RGBAPixel
+fcastRGBA v
+    | o `rem` 4 /= 0 = error "Can not cast a JuicyPixel image constructed via a vector with non zero offset (mod 4)."
+    | otherwise = unsafeFromForeignPtr (castForeignPtr fp) (o`div`4) (l`div`4)
+ where (fp,o,l) = unsafeToForeignPtr v
+
+jcastRGB :: Vector RGBPixel -> Vector (PixelBaseComponent PixelRGB8)
+jcastRGB v = unsafeFromForeignPtr (castForeignPtr fp) (3*o) (3*l) where (fp,o,l) = unsafeToForeignPtr v
+
+fcastRGB :: Vector (PixelBaseComponent PixelRGB8) -> Vector RGBPixel
+fcastRGB v
+    | o `rem` 3 /= 0 = error "Can not cast a JuicyPixel image constructed via a vector with non zero offset (mod 3)."
+    | otherwise = unsafeFromForeignPtr (castForeignPtr fp) (o`div`3) (l`div`3)
+ where (fp,o,l) = unsafeToForeignPtr v
+
+toFridayGrey :: JP.Image Pixel8 -> Grey
+toFridayGrey (JP.Image w h vec) =
+    Manifest (Z :. h :. w) (fcast vec)
+
+toJuicyGrey :: Grey -> JP.Image Pixel8
+toJuicyGrey (compute -> Manifest (Z :. h :. w) vec) =
+    JP.Image w h (jcast vec)
+
+toFridayRGB :: JP.Image PixelRGB8 -> RGB
+toFridayRGB (JP.Image w h vec) =
+    Manifest (Z :. h :. w) (fcastRGB vec)
+
+toJuicyRGB :: RGB -> JP.Image PixelRGB8
+toJuicyRGB (compute -> Manifest (Z :. h :. w) vec) =
+    JP.Image w h (jcastRGB vec)
+
+toFridayRGBA :: JP.Image PixelRGBA8 -> RGBA
+toFridayRGBA (JP.Image w h vec) =
+    Manifest (Z :. h :. w) (fcastRGBA vec)
+
+toJuicyRGBA :: RGBA -> JP.Image PixelRGBA8
+toJuicyRGBA (compute -> Manifest (Z :. h :. w) vec) =
+    JP.Image w  h (jcastRGBA vec)
diff --git a/friday-juicypixels.cabal b/friday-juicypixels.cabal
new file mode 100644
--- /dev/null
+++ b/friday-juicypixels.cabal
@@ -0,0 +1,51 @@
+name:                friday-juicypixels
+version:             0.1.0.2
+synopsis:            Converts between the Friday and JuicyPixels image types
+-- description:
+homepage:            github.com/TomMD/friday-juicypixels
+license:             BSD3
+license-file:        LICENSE
+author:              Thomas M. DuBuisson
+maintainer:          tommd@galois.com
+-- copyright:
+homepage:            https://github.com/TomMD/friday-juicypixels
+bug-reports:         https://github.com/TomMD/friday-juicypixels/issues
+stability:           alpha
+category:            Codec
+build-type:          Simple
+extra-source-files:  README.md
+cabal-version:       >= 1.18
+
+source-repository head
+  type:             git
+  location:         git://github.com/TomMD/friday-juicypixels.git
+
+library
+  default-language:    Haskell2010
+  exposed-modules:     Vision.Image.JuicyPixels
+  -- other-modules:
+  other-extensions:    ViewPatterns
+  build-depends:       base            >= 4.8     &&  <  4.9
+                     , friday          >= 0.2     &&  <  0.3
+                     , JuicyPixels
+                     , vector
+  -- hs-source-dirs:
+  default-language:    Haskell2010
+  ghc-options:         -Wall
+
+test-suite test
+    default-language:  Haskell2010
+    type:              exitcode-stdio-1.0
+    main-is:           Spec.hs
+    hs-source-dirs:    test
+    ghc-options:       -Wall
+    -- TODO: remove other-modules after stack can properly detect when to rebuild
+    other-modules:     Spec
+
+    build-depends: base
+                 , friday
+                 , JuicyPixels
+                 , bytestring
+                 , file-embed
+                 , hspec
+                 , friday-juicypixels
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,31 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+import Test.Hspec
+
+import Codec.Picture as JP
+import qualified Data.ByteString
+import Data.FileEmbed
+
+import Vision.Image.JuicyPixels
+
+
+rgba8Png :: Data.ByteString.ByteString
+rgba8Png = $(embedFile "test/rgba8.png")
+
+
+main :: IO ()
+main = hspec spec
+
+spec :: Spec
+spec = do
+  describe "RGBA conversion" $ do
+    it "should not modify the image when converting from Juicy to Friday and back" $
+        let result = decodeImage rgba8Png in case result of
+            Right (ImageRGBA8 img) ->
+                let fridayImg    = toFridayRGBA img
+                    juicyImg     = toJuicyRGBA fridayImg
+                    orig         = encodeDynamicPng $ ImageRGBA8 img
+                    converted    = encodeDynamicPng $ ImageRGBA8 juicyImg
+                in  orig `shouldBe` converted
+            Left _ -> error "Image decoding error"
+            _      -> error "Unexpected color space"
