diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Revision history for deriving-trans
+
+## 0.1.0.0 *19 Jun 2021*
+
+* First version. Released on an unsuspecting world.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2021, Felix Springer
+
+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 Felix Springer 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/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/deriving-trans.cabal b/deriving-trans.cabal
new file mode 100644
--- /dev/null
+++ b/deriving-trans.cabal
@@ -0,0 +1,50 @@
+name:                deriving-trans
+version:             0.1.0.0
+synopsis:            Derive transformer type classes with DerivingVia
+description:         MonadTrans is a prime example of a type class, that is not derivable with
+                     GeneralizedNewtypeDeriving.
+                     A simple way to still derive such an instance is by using DerivingVia.
+license:             BSD3
+license-file:        LICENSE
+author:              Felix Springer
+maintainer:          felixspringer149@gmail.com
+homepage:            https://github.com/jumper149/deriving-trans
+bug-reports:         https://github.com/jumper149/deriving-trans/issues
+category:            Control
+build-type:          Simple
+extra-source-files:  CHANGELOG.md
+cabal-version:       >= 1.10
+
+library
+  exposed-modules:     Control.Monad.Trans.Deriving
+  --other-modules:
+  build-depends:       base              >= 4.5     && < 5
+                     , lifted-base       >= 0.2.3.2 && < 0.2.4
+                     , monad-control     >= 1.0.2.0 && < 1.1
+                     , mtl               >= 2.2.2   && < 2.3
+                     , transformers      >= 0.5.6.2 && < 0.5.7
+                     , transformers-base >= 0.4.5.2 && < 0.5
+  hs-source-dirs:      src
+  default-language:    Haskell2010
+  default-extensions:  BangPatterns
+                       ConstraintKinds
+                       DataKinds
+                       DeriveFoldable
+                       DeriveFunctor
+                       DeriveGeneric
+                       DeriveTraversable
+                       DerivingStrategies
+                       DerivingVia
+                       EmptyDataDeriving
+                       FlexibleContexts
+                       FlexibleInstances
+                       FunctionalDependencies
+                       GeneralizedNewtypeDeriving
+                       MultiParamTypeClasses
+                       NamedFieldPuns
+                       OverloadedStrings
+                       RankNTypes
+                       StandaloneDeriving
+                       TypeApplications
+                       TypeFamilies
+  ghc-options:         -Wall
diff --git a/src/Control/Monad/Trans/Deriving.hs b/src/Control/Monad/Trans/Deriving.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/Trans/Deriving.hs
@@ -0,0 +1,67 @@
+{-# LANGUAGE QuantifiedConstraints, UndecidableInstances #-}
+
+module Control.Monad.Trans.Deriving (
+  Stack0T (..)
+, Stack1T (..)
+, Stack2T (..)
+, Stack3T (..)
+) where
+
+import Control.Monad.Base
+import Control.Monad.Trans
+import Control.Monad.Trans.Control
+import Data.Kind
+
+newtype Stack0T
+  (m :: Type -> Type)
+  (a :: Type)
+    = Stack0T { unStack0T :: m a }
+  deriving (Applicative, Functor, Monad, MonadBase b, MonadBaseControl b)
+
+instance MonadTrans Stack0T where
+  lift = Stack0T
+
+instance MonadTransControl Stack0T where
+  type StT Stack0T a = a
+  liftWith f = Stack0T $ f unStack0T
+  restoreT = Stack0T
+
+newtype Stack1T
+  (t :: (Type -> Type) -> Type -> Type)
+  (m :: Type -> Type)
+  (a :: Type)
+    = Stack1T { unStack1T :: t m a }
+  deriving (Applicative, Functor, Monad, MonadBase b, MonadBaseControl b, MonadTrans, MonadTransControl)
+
+newtype Stack2T
+  (t1 :: (Type -> Type) -> Type -> Type)
+  (t2 :: (Type -> Type) -> Type -> Type)
+  (m :: Type -> Type)
+  (a :: Type)
+    = Stack2T { unStack2T :: t1 (t2 m) a }
+  deriving (Applicative, Functor, Monad, MonadBase b, MonadBaseControl b)
+
+instance (forall m. Monad m => Monad (t2 m), MonadTrans t1, MonadTrans t2) => MonadTrans (Stack2T t1 t2) where
+  lift = Stack2T . lift . lift
+
+instance (forall m. Monad m => Monad (t2 m), MonadTransControl t1, MonadTransControl t2) => MonadTransControl (Stack2T t1 t2) where
+  type StT (Stack2T t1 t2) a = StT t2 (StT t1 a)
+  liftWith f = defaultLiftWith2 Stack2T unStack2T $ \x -> f x
+  restoreT = defaultRestoreT2 Stack2T
+
+newtype Stack3T
+  (t1 :: (Type -> Type) -> Type -> Type)
+  (t2 :: (Type -> Type) -> Type -> Type)
+  (t3 :: (Type -> Type) -> Type -> Type)
+  (m :: Type -> Type)
+  (a :: Type)
+    = Stack3T { unStack3T :: t1 (t2 (t3 m)) a }
+  deriving (Applicative, Functor, Monad, MonadBase b, MonadBaseControl b)
+
+instance (forall m. Monad m => Monad (t3 m), forall m. Monad m => Monad (t2 (t3 m)), MonadTrans t1, MonadTrans t2, MonadTrans t3) => MonadTrans (Stack3T t1 t2 t3) where
+  lift = Stack3T . lift . lift . lift
+
+instance (forall m. Monad m => Monad (t3 m), forall m. Monad m => Monad (t2 (t3 m)), MonadTransControl t1, MonadTransControl t2, MonadTransControl t3) => MonadTransControl (Stack3T t1 t2 t3) where
+  type StT (Stack3T t1 t2 t3) a = StT t3 (StT t2 (StT t1 a))
+  liftWith f = Stack3T $ liftWith $ \run -> liftWith $ \run' -> liftWith $ \ run'' -> f $ run'' . run' . run . unStack3T
+  restoreT = Stack3T . restoreT . restoreT . restoreT
