diff --git a/registry.cabal b/registry.cabal
--- a/registry.cabal
+++ b/registry.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: e92b2f66ceff7a38e91de8e96c196577dec1046ec2f078503644b8bcb01419cb
+-- hash: e8a0bcc6a337a5f2490898d33671fd1ee6e62d9e3f3f3ce38f7668448b2616a7
 
 name:           registry
-version:        0.1.3.6
+version:        0.1.4.0
 synopsis:       data structure for assembling components
 description:    This library provides a "Registry" which is a data structure containing a list of functions and values representing dependencies in a directed acyclic graph. A `make` function can then be used to create a value of a specific type out of the registry.
                 You can start with the [README](https://github.com/etorreborre/registry/blob/master/README.md) for a full description of the library.
@@ -39,6 +39,7 @@
       Data.Registry.Registry
       Data.Registry.RIO
       Data.Registry.Solver
+      Data.Registry.State
       Data.Registry.Statistics
       Data.Registry.TH
       Data.Registry.Warmup
@@ -53,6 +54,7 @@
     , containers >=0.5 && <0.7
     , exceptions >=0.8 && <0.11
     , hashable >=1.2 && <1.3
+    , mmorph >=1.0 && <2
     , mtl >=2.0 && <3
     , protolude >=0.2 && <0.3
     , resourcet >=1.1 && <1.3
@@ -106,6 +108,7 @@
     , hedgehog <0.7
     , hedgehog-corpus <0.2
     , io-memoize <1.2
+    , mmorph >=1.0 && <2
     , mtl >=2.0 && <3
     , multimap <1.3
     , protolude >=0.2 && <0.3
diff --git a/src/Data/Registry.hs b/src/Data/Registry.hs
--- a/src/Data/Registry.hs
+++ b/src/Data/Registry.hs
@@ -13,6 +13,7 @@
 import           Data.Registry.Lift       as M -- Lift functions into a monadic context
 import           Data.Registry.Make       as M -- Various "make" functions to create components from a registry
 import           Data.Registry.Registry   as M -- The Registry data structure
+import           Data.Registry.State      as M -- Stateful modifications of a registry
 import           Data.Registry.RIO        as M -- A monad for instantiating components (managing resources, handling startup)
 import           Data.Registry.Solver     as M -- Type-level constraints to check if we can make a component from a registry
 import           Data.Registry.Warmup     as M -- A small DSL for describing the warmup actions of a component
diff --git a/src/Data/Registry/State.hs b/src/Data/Registry/State.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Registry/State.hs
@@ -0,0 +1,38 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+
+module Data.Registry.State where
+
+import           Control.Monad.Morph
+import           Data.Registry.Internal.Types
+import           Data.Registry.Lift
+import           Data.Registry.Registry
+import           Data.Registry.Solver
+import           Protolude
+
+-- | Run some registry modifications in the StateT monad
+runS :: (MFunctor m, Monad n) => Registry ins out -> m (StateT (Registry ins out) n) a -> m n a
+runS r = hoist (`evalStateT` r)
+
+-- | Add an element to the registry without changing its type
+addFunTo :: forall m a b ins out . (ApplyVariadic m a b, Typeable a, Typeable b, IsSubset (Inputs b) ins, Contains (Output b) out) => a -> Registry ins out -> Registry ins out
+addFunTo = modifyRegistry @b . funTo @m
+
+-- | Add an element to the registry without changing its type, in the State monad
+addFunS :: (Typeable a, IsSubset (Inputs a) ins, Contains (Output a) out, MonadState (Registry ins out) m) => a -> m ()
+addFunS = modify . addFun
+
+-- | Add an element to the registry without changing its type, in the State monad
+addToS :: forall n a b m ins out . (ApplyVariadic n a b, Typeable a, Typeable b, Typeable a, IsSubset (Inputs b) ins, Contains (Output b) out, MonadState (Registry ins out) m) => a -> m ()
+addToS = modify . addFunTo @n @a @b
+
+-- | Add an element to the registry without changing its type
+addFun :: (Typeable a, IsSubset (Inputs a) ins, Contains (Output a) out) => a -> Registry ins out -> Registry ins out
+addFun = modifyRegistry . fun
+
+-- | Register modifications of elements which types are already in the registry
+modifyRegistry :: (Typeable a, IsSubset (Inputs a) ins, Contains (Output a) out) => Typed a -> Registry ins out -> Registry ins out
+modifyRegistry (TypedValue v) (Registry (Values vs) functions specializations modifiers) =
+  Registry (Values (v : vs)) functions specializations modifiers
+
+modifyRegistry (TypedFunction f) (Registry (Values vs) (Functions fs) specializations modifiers) =
+  Registry (Values vs) (Functions (f : fs)) specializations modifiers
