diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,3 @@
+# Changelog for scoped-instances
+
+## Unreleased changes
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Estatico Studios LLC (c) 2020
+
+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 Estatico Studios LLC 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,66 @@
+# generic-override
+
+For the associated blog post describing how this works, see
+[Overriding Type Class Instances](http://caryrobbins.com/dev/overriding-type-class-instances-2/).
+
+-------------------------
+
+This library provides the ability to override instances used by generic derivation.
+
+## Example
+
+```haskell
+-- Needed for constructing our 'Override' type in the DerivingVia clause.
+import Data.Override (Override(Override), As)
+-- Provides aeson support for generic-override (lives in generic-override-aeson).
+import Data.Override.Aeson ()
+-- Basic imports we need for the example.
+import Data.Aeson (ToJSON(toJSON))
+import Data.Text (Text)
+import qualified Data.Text as Text
+
+-- | A simple record type. We'll use generic derivation for the 'ToJSON' instance
+-- but override the instances used by derivation for the 'String' and 'baz'
+-- fields.
+data MyRec = MyRec
+  { foo :: Int
+  , bar :: String
+  , baz :: Text
+  } deriving stock (Show, Eq, Generic)
+    deriving (ToJSON)
+      via Override MyRec
+            '[ -- Derive the 'String' field via 'CharArray'.
+               String `As` CharArray
+               -- Derive the 'baz' field via 'Uptext'.
+             , "baz" `As` Uptext
+             ]
+
+-- | Newtype wrapper to override 'ToJSON Text' instances with ones that
+-- encode the 'Text' as uppercase.
+newtype Uptext = Uptext { unUptext :: Text }
+
+instance ToJSON Uptext where
+  toJSON = toJSON . Text.toUpper . unUptext
+
+-- | Newtype wrapper to override 'ToJSON String' instances with ones that
+-- encode the 'String' as a JSON array of characters.
+newtype CharArray = CharArray { unCharArray :: String }
+
+instance ToJSON CharArray where
+  toJSON = toJSON . map (:[]) . unCharArray
+```
+
+Let's serialize an example `MyRec` to JSON -
+
+```haskell
+% ghci
+> :{
+  Data.ByteString.Lazy.Char8.putStrLn
+    $ Data.Aeson.encode
+    $ Data.Aeson.toJSON MyRec { foo = 12, bar = "hi", baz = "bye" }
+  :}
+{"foo":12,"bar":["h","i"],"baz":"BYE"}
+```
+
+For more examples, see the test suite in
+[generic-override-aeson](./aeson/test/Test.hs).
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/generic-override.cabal b/generic-override.cabal
new file mode 100644
--- /dev/null
+++ b/generic-override.cabal
@@ -0,0 +1,33 @@
+cabal-version: 1.12
+name: generic-override
+version: 0.0.0.0
+license: BSD3
+license-file: LICENSE
+copyright: 2020 Estatico Studios LLC
+maintainer: carymrobbins@gmail.com
+author: Cary Robbins
+homepage: https://github.com/estatico/generic-override#readme
+bug-reports: https://github.com/estatico/generic-override/issues
+synopsis: Provides functionality for overriding instances for generic derivation
+description:
+    Please see the README on GitHub at <https://github.com/estatico/generic-override#readme>
+category: Generics
+build-type: Simple
+extra-source-files:
+    README.md
+    ChangeLog.md
+
+source-repository head
+    type: git
+    location: https://github.com/estatico/generic-override
+
+library
+    exposed-modules:
+        Data.Override
+        Data.Override.Internal
+    hs-source-dirs: src
+    other-modules:
+        Paths_generic_override
+    default-language: Haskell2010
+    build-depends:
+        base >=4.7 && <5
diff --git a/src/Data/Override.hs b/src/Data/Override.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Override.hs
@@ -0,0 +1,9 @@
+module Data.Override (module X) where
+
+import Data.Override.Internal as X
+  ( Override(Override), unOverride
+  , Overridden(Overridden), unOverridden
+  , As
+  , Using
+  , override
+  )
diff --git a/src/Data/Override/Internal.hs b/src/Data/Override/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Override/Internal.hs
@@ -0,0 +1,100 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE KindSignatures #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+module Data.Override.Internal where
+
+import Data.Type.Bool (If)
+import Data.Type.Equality (type (==))
+import GHC.Generics
+import GHC.TypeLits (Symbol)
+
+-- | The feature of this library. For use with DerivingVia.
+-- Apply it to a type 'a' and supply a type-level list of instance
+-- overrides 'xs'.
+newtype Override a (xs :: [*]) = Override a
+  deriving stock (Show, Eq)
+
+-- | Unwrap an 'Override' value.
+unOverride :: Override a xs -> a
+unOverride (Override a) = a
+
+-- | Construct an 'Override' using a proxy of overrides.
+override :: a -> proxy xs -> Override a xs
+override a _ = Override a
+
+-- | Used to construct a type-level override. Usually used infix.
+-- The 'o' should be either a type (kind '*') or a type-level string
+-- (kind 'Symbol').
+data As (o :: k) n
+
+-- | Used at the leaf nodes of a generic 'Rep'
+newtype Overridden (ms :: Maybe Symbol) a (xs :: [*]) = Overridden a
+
+-- | Unwrap an 'Overridden' value.
+unOverridden :: Overridden ms a xs -> a
+unOverridden (Overridden a) = a
+
+-- | Same as 'override' but for 'Overridden' types.
+overridden
+  :: forall a (ms :: Maybe Symbol) (xs :: [*]) proxy0 proxy1.
+     a -> proxy0 ms -> proxy1 xs -> Overridden ms a xs
+overridden a _ _ = Overridden a
+
+instance (Generic a, GOverride xs (Rep a)) => Generic (Override a xs) where
+  type Rep (Override a xs) = OverrideRep xs (Rep a)
+  from = overrideFrom @xs . from . unOverride
+  to = Override . to . overrideTo @xs
+
+-- | Type class used to build the 'Generic' instance for 'Override'.
+class GOverride (xs :: [*]) (f :: * -> *) where
+  -- | Analogous to 'Rep'; rewrites the type for a given 'Rep' and injects
+  -- 'Overridden' at the leaves.
+  type OverrideRep xs f :: * -> *
+  overrideFrom :: f x -> OverrideRep xs f x
+  overrideTo :: OverrideRep xs f x -> f x
+
+instance (GOverride xs f) => GOverride xs (M1 D c f) where
+  type OverrideRep xs (M1 D c f) = M1 D c (OverrideRep xs f)
+  overrideFrom (M1 x) = M1 (overrideFrom @xs x)
+  overrideTo (M1 x) = M1 (overrideTo @xs x)
+
+instance (GOverride xs f) => GOverride xs (M1 C c f) where
+  type OverrideRep xs (M1 C c f) = M1 C c (OverrideRep xs f)
+  overrideFrom (M1 x) = M1 (overrideFrom @xs x)
+  overrideTo (M1 x) = M1 (overrideTo @xs x)
+
+instance (GOverride xs f, GOverride xs g) => GOverride xs (f :*: g) where
+  type OverrideRep xs (f :*: g) = OverrideRep xs f :*: OverrideRep xs g
+  overrideFrom (f :*: g) = overrideFrom @xs f :*: overrideFrom @xs g
+  overrideTo (f :*: g) = overrideTo @xs f :*: overrideTo @xs g
+
+instance GOverride xs (M1 S ('MetaSel ms su ss ds) (K1 R c)) where
+  type OverrideRep xs (M1 S ('MetaSel ms su ss ds) (K1 R c)) =
+    M1 S ('MetaSel ms su ss ds) (K1 R (Overridden ms c xs))
+  overrideFrom (M1 (K1 x)) = M1 (K1 (Overridden @ms x))
+  overrideTo (M1 (K1 (Overridden x))) = M1 (K1 x)
+
+-- | Type family used to determine which override from 'xs'
+-- to replace 'x' with, if any. The 'ms' holds the field name
+-- for 'x', if applicable.
+type family Using (ms :: Maybe Symbol) (x :: *) (xs :: [*]) where
+  -- No matching override found.
+  Using ms x '[] = x
+
+  -- Override the matching field.
+  Using ms x (As (o :: Symbol) n ': xs) =
+    If (ms == 'Just o) n (Using ms x xs)
+
+  -- Override the matching type.
+  Using ms x (As (o :: *) n ': xs) =
+    If (x == o) n (Using ms x xs)
