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/composite-aeson-refined.cabal b/composite-aeson-refined.cabal
new file mode 100644
--- /dev/null
+++ b/composite-aeson-refined.cabal
@@ -0,0 +1,29 @@
+-- This file has been generated from package.yaml by hpack version 0.17.0.
+--
+-- see: https://github.com/sol/hpack
+
+name:           composite-aeson-refined
+version:        0.4.0.0
+synopsis:       composite-aeson support for Refined from the refined package
+description:    JsonFormat and DefaultJsonFormat for Refined
+category:       Records
+homepage:       https://github.com/ConferHealth/composite#readme
+author:         Confer Health, Inc
+maintainer:     oss@confer.care
+copyright:      2017 Confer Health, Inc.
+license:        BSD3
+build-type:     Simple
+cabal-version:  >= 1.10
+
+library
+  hs-source-dirs:
+      src
+  default-extensions: DataKinds FlexibleContexts FlexibleInstances GeneralizedNewtypeDeriving LambdaCase MultiParamTypeClasses MultiWayIf OverloadedStrings PatternSynonyms PolyKinds QuasiQuotes RankNTypes ScopedTypeVariables StandaloneDeriving StrictData TemplateHaskell TupleSections TypeFamilies TypeOperators ViewPatterns
+  ghc-options: -Wall -O2
+  build-depends:
+      base >= 4.7 && < 5
+    , composite-aeson
+    , refined
+  exposed-modules:
+      Composite.Aeson.Refined
+  default-language: Haskell2010
diff --git a/src/Composite/Aeson/Refined.hs b/src/Composite/Aeson/Refined.hs
new file mode 100644
--- /dev/null
+++ b/src/Composite/Aeson/Refined.hs
@@ -0,0 +1,18 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Composite.Aeson.Refined (refinedJsonFormat) where
+
+import Composite.Aeson (DefaultJsonFormat, defaultJsonFormat, JsonFormat(JsonFormat), JsonProfunctor(JsonProfunctor))
+import Refined (Predicate, Refined, refine, unrefine)
+
+-- |Given a @'JsonFormat' e a@, produce a @JsonFormat e ('Refined' p a)@ where @p@ is some 'Predicate' from the refined library for @a@.
+--
+-- This maps to the same JSON as the given 'JsonFormat', but when parsing it will apply 'refine' to assert that the incoming JSON value conforms to the
+-- predicate, failing to parse if not.
+refinedJsonFormat :: Predicate p a => JsonFormat e a -> JsonFormat e (Refined p a)
+refinedJsonFormat (JsonFormat (JsonProfunctor oa ia)) = JsonFormat $ JsonProfunctor o i
+  where
+    o = oa . unrefine
+    i = either fail pure . refine =<< ia
+
+instance (DefaultJsonFormat a, Predicate p a) => DefaultJsonFormat (Refined p a) where
+  defaultJsonFormat = refinedJsonFormat defaultJsonFormat
