diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Revision history for record-sugar
+
+## 0.1.0.0 -- YYYY-mm-dd
+
+* First version. Released on an unsuspecting world.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2019 Solonarv
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# record-sugar
+Syntax sugar for vinyl records using overloaded labels.
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/examples/Example.hs b/examples/Example.hs
new file mode 100644
--- /dev/null
+++ b/examples/Example.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE OverloadedLabels #-}
+module Example where
+
+import Data.Vinyl.Core
+import Data.Vinyl.Functor
+import Data.Vinyl.Sugar
+
+john :: Rec ElField ['("name", String), '("age", Int)]
+john = rec_
+  #age 30
+  #name "John Doe"
+
+john' :: Rec ElField ['("bornAt", String), '("name", String), '("age", Int)]
+john' = extend_ john
+  #bornAt "Zurich, Switzerland"
diff --git a/lib/Data/Vinyl/Sugar.hs b/lib/Data/Vinyl/Sugar.hs
new file mode 100644
--- /dev/null
+++ b/lib/Data/Vinyl/Sugar.hs
@@ -0,0 +1,127 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+{-# LANGUAGE UndecidableInstances #-}
+{-|
+Provides "syntax sugar" for constructing @vinyl@ records with
+named fields, using GHC's OverloadedLabels extension.
+
+This lets you create records using the following syntax,
+clearly associating each field's name with its value:
+
+@
+john :: 'V.Rec' 'V.ElField' ['("name", String), '("age", Int)]
+john = 'rec_'
+  #age 30
+  #name "John Doe"
+@
+
+You can also extend an existing record using 'extend_':
+
+@
+john' :: 'V.Rec' 'V.ElField' ['("bornAt", String), '("name", String), '("age", Int)]
+john' = 'extend_' john
+  #bornAt "Zurich, Switzerland"
+@
+-}
+module Data.Vinyl.Sugar
+  (
+  -- * Record-construction sugar
+    rec_
+  , extend_
+  -- * Extending the syntax sugar
+  , NamedField(..)
+  , RecSugarTy(..)
+  -- * Auxiliary types
+  , FieldLabel(..)
+  ) where
+
+import Data.Kind
+import Foreign.Storable (Storable)
+import GHC.OverloadedLabels
+import GHC.TypeLits
+
+import qualified Data.Vinyl.ARec as V
+import qualified Data.Vinyl.Core as V
+import qualified Data.Vinyl.Functor as V
+import qualified Data.Vinyl.SRec as V
+import qualified Data.Vinyl.TypeLevel as V
+
+-- | A simple proxy for type-level strings.
+data FieldLabel (s :: Symbol) = FieldLabel
+  deriving (Eq, Ord, Enum)
+
+instance s ~ s' => IsLabel s (FieldLabel s') where
+  fromLabel = FieldLabel
+
+{- |
+Specifies how to convert a labeled value into an element of a
+vinyl record. The only default instance is for @'Vinyl.ElField'@,
+but you can define additional instances for your own interpretation
+functors.
+-}
+class NamedField (s :: Symbol) (r :: k) (f :: k -> Type) (a :: Type)
+  | r -> s
+  , r f -> a
+  where
+  {- |
+  Convert a value into a vinyl record element. You can imagine that
+  this has the following type:
+
+@
+toNamedField :: KnownSymbol s => a -> ElField '(s, a)
+@
+  -}
+  toNamedField :: a -> f r
+
+instance (KnownSymbol s, s ~ s') => NamedField s' '(s, a) V.ElField a where
+  toNamedField = V.Field
+
+{- |
+The workhorse class of this package. Implements a polyvariadic
+function that builds up a @'V.Rec'@ and converts it into
+the desired output type.
+
+You can enable @rec_@ syntax for your own types by writing additional
+@RecSugarTy@ instances, adding a base case to @'rec''@. Example:
+
+@
+data MyFunctor r -- elided
+
+newtype MyRec rs = MyRec { unMyRec :: 'V.Rec' MyFunctor rs }
+
+instance 'RecSugarTy' ('V.Rec' MyFunctor rs) (MyRec rs) where
+  rec' = MyRec
+@
+-}
+class RecSugarTy e o | o -> e where
+  rec' :: e -> o
+
+instance RecSugarTy (V.Rec f rs) (V.Rec f rs) where
+  rec' = id
+
+instance (NamedField s r f a, RecSugarTy (V.Rec f (r:rs)) o, lbl ~ FieldLabel s) => RecSugarTy (V.Rec f rs) (lbl -> a -> o) where
+  rec' rs _lbl a = rec' (toNamedField a V.:& rs)
+
+instance V.NatToInt (V.RLength rs) => RecSugarTy (V.Rec f rs) (V.ARec f rs) where
+  rec' = V.toARec
+
+instance Storable (V.Rec f rs) => RecSugarTy (V.Rec f rs) (V.SRec f rs) where
+  rec' = V.toSRec
+
+{- |
+Create a record by adding fields to the empty record. This is the
+function you will use most of the time.
+-}
+rec_ :: RecSugarTy (V.Rec f '[]) o => o
+rec_ = rec' V.RNil
+
+{- |
+Create a record by extending an existing record.
+-}
+extend_ :: RecSugarTy (V.Rec f rs) o => V.Rec f rs -> o
+extend_ = rec'
diff --git a/vinyl-named-sugar.cabal b/vinyl-named-sugar.cabal
new file mode 100644
--- /dev/null
+++ b/vinyl-named-sugar.cabal
@@ -0,0 +1,32 @@
+cabal-version:       2.2
+-- Initial package description 'record-sugar.cabal' generated by 'cabal
+-- init'.  For further documentation, see
+-- http://haskell.org/cabal/users-guide/
+
+name:                vinyl-named-sugar
+version:             0.1.0.0
+synopsis:            Syntax sugar for vinyl records using overloaded labels.
+description:         Provides @rec_ \#foo fooVal \#bar barVal@ syntax for constructing @vinyl@ records.
+homepage:            https://github.com/Solonarv/record-sugar#readme
+bug-reports:         https://github.com/Solonarv/record-sugar/issues
+license:             MIT
+license-file:        LICENSE
+author:              Solonarv
+maintainer:          nstamm@gmx.de
+copyright:           2019 Solonarv
+category:            Data
+extra-source-files:  CHANGELOG.md, README.md, examples/*.hs
+
+source-repository head
+  type:                git
+  location:            https://github.com/Solonarv/record-sugar
+
+library
+  exposed-modules:     Data.Vinyl.Sugar
+  -- other-modules:
+  other-extensions:    DataKinds FlexibleContexts FlexibleInstances FunctionalDependencies
+                       PolyKinds TypeFamilies TypeOperators
+  build-depends:       base >= 4.10 && < 4.13
+                     , vinyl >= 0.9 && < 0.11
+  hs-source-dirs:      lib
+  default-language:    Haskell2010
