diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# 0.11
+
+- Removed `Region`s. Now using commands (`FrameCmd`, `ShadingCmd`, `DrawCmd` and `RenderCmd`). Safer
+  interface.
+
 ### 0.10.0.2
 
 - Fixed `Buffer` documentation.
diff --git a/luminance.cabal b/luminance.cabal
--- a/luminance.cabal
+++ b/luminance.cabal
@@ -1,5 +1,5 @@
 name:                luminance
-version:             0.10.0.2
+version:             0.11
 synopsis:            Type-safe, type-level and stateless graphics framework
 description:         This package exposes several modules to work with /GPUs/ in a stateless and
                      type-safe way. Currently, it uses OpenGL as backend hardware technology but
@@ -76,13 +76,11 @@
                      , Graphics.Luminance
                      , Graphics.Luminance.Blending
                      , Graphics.Luminance.Buffer
-                     , Graphics.Luminance.Cmd
                      , Graphics.Luminance.Core.Tuple
                      , Graphics.Luminance.Framebuffer
                      , Graphics.Luminance.Geometry
                      , Graphics.Luminance.Pixel
                      , Graphics.Luminance.Query
-                     , Graphics.Luminance.Region
                      , Graphics.Luminance.RenderCmd
                      , Graphics.Luminance.RW
                      , Graphics.Luminance.Shader
@@ -93,15 +91,14 @@
 
   other-modules:       Graphics.Luminance.Core.Blending
                      , Graphics.Luminance.Core.Buffer
-                     , Graphics.Luminance.Core.Cmd
                      , Graphics.Luminance.Core.Cubemap
                      , Graphics.Luminance.Core.CubemapArray
                      , Graphics.Luminance.Core.Debug
+                     , Graphics.Luminance.Core.Draw
                      , Graphics.Luminance.Core.Framebuffer
                      , Graphics.Luminance.Core.Geometry
                      , Graphics.Luminance.Core.Pixel
                      , Graphics.Luminance.Core.Query
-                     , Graphics.Luminance.Core.Region
                      , Graphics.Luminance.Core.RenderCmd
                      , Graphics.Luminance.Core.Renderbuffer
                      , Graphics.Luminance.Core.RW
diff --git a/src/Graphics/Luminance.hs b/src/Graphics/Luminance.hs
--- a/src/Graphics/Luminance.hs
+++ b/src/Graphics/Luminance.hs
@@ -16,16 +16,16 @@
 -- This library doesn’t expose any architectural patterns or designs. It’s up to you to design your
 -- program as you want and following your own plans. Because it’s a graphics and rendering API, you
 -- won’t find several common things you find in animations, games or simulations. If you need those
--- you’ll have to look for dedicated libraries instead.
+-- you’ll have to look for dedicated libraries instead or write your own.
 --
 -- One of the most important thing you have to keep in mind is the fact that luminance won’t
 -- provide you with anything else than working with the /GPU/. That is, it won’t even provide
 -- functions to open windows. That’s actually a good thing, because then you’ll be able to use it
--- with /any kind of windowing and system library you want to/!
+-- with /any kind of windowing and system library you want/!
 --
 -- The drawback is about safety. If you screw up setting up the OpenGL context, there’s no way
--- luminance will work. If users feel the need, a few dedicated packages will be uploaded, like
--- __luminance-glfw__ to add "GLFW-b" support for instance.
+-- luminance will work. A few dedicated packages will be uploaded, like __luminance-glfw__ to add
+-- "GLFW-b" support for instance.
 --
 -- = Getting started
 --
@@ -51,9 +51,11 @@
 -- @
 --
 -- That part just setup the window’s OpenGL hints so that we create a compatible context for
--- luminance. luminance will work with __OpenGL 4.5__ only, don’t even try to make it work with a
+-- luminance. That part is important as you need to select which OpenGL versions you want to use.
+-- luminance will work with __OpenGL 3.3__ and upper only, don’t even try to make it work with a
 -- lower implementation. We also disable the /forward compatibility/ because we don’t need it and
--- ask to stick to a /core/ profile.
+-- ask to stick to a /core/ profile. You’ll need to compile with the proper flags depending on what
+-- context you’d have choosen.
 --
 -- @
 --     case window of
@@ -102,9 +104,9 @@
 --
 -- luminance generalizes OpenGL concepts so that they’re made safer. In order to render something
 -- onto the screen, you have to understand what the screen truly is. It’s actually… a back buffer –
--- assuming we have double buffering enabled, which the case with "GLFW-b" by default. So rendering
--- to the screen is the same thing than rendering to the back buffer and ask "GLFW-b" to swap the
--- back buffer with the front buffer.
+-- assuming we have double buffering enabled, which is the case with "GLFW-b" by default. So
+-- rendering to the screen is the same thing than rendering to the back buffer and ask "GLFW-b" to
+-- swap the back buffer with the front buffer.
 --
 -- And guess what. luminance wraps the back buffer into a 'Framebuffer' object. You can access it
 -- through 'defaultFramebuffer'. That value will always represent the back buffer.
@@ -114,25 +116,21 @@
 -- In most graphics frameworks, rendering is the act of taking an object and getting it rendered.
 -- luminance follows a different path. Because of real world needs and, well, real applications, you
 -- cannot do that in luminance. Because, what serious application will render only __one__ object?
--- None. If so, then it’s an exception. We shouldn’t design our libraries and interface for the
+-- None. If so, then it’s an exception. We shouldn’t design our libraries and interfaces for the
 -- exceptions. We should build them for the most used case, which is, having a lot of objects in a
 -- scene.
 --
 -- That’s why luminance exposes the concept of /batched rendering/. The idea is that you have to
--- gather you objects in /batches/ and render them all at once. That enables a correct sharing of
--- resources – for instance, framebuffers or textures – and is very straight-forward to reason
+-- gather your objects in /batches/ and render them all at once. That enables a correct sharing of
+-- resources – for instance, framebuffers or shaders – and is very straight-forward to reason
 -- about.
 --
--- luminance has several types of batches, each for the type of shared information. You can – up to
--- now – shared two information between the rendered objects:
---
--- * /framebuffer/: that means you can create a 'FBBatch' that will gather several values under the
---   same 'Framebuffer';
--- * or /shaders/: that means you can create a 'SPBatch' that will gather several values under the
---   same shader 'Program'.
+-- Render batches are not directly exposed through the interface. Another concept is used instead:
+-- regions. Regions are used to bind resources and share them in a safe way. You can find two types
+-- of regions right now:
 --
--- The idea is that the 'SPBatch'es are stored in 'FBBatch'es. That creates a structure similar to
--- an AST luminance knows how to dispatch to the GPU.
+-- * /framebuffer/ regions ;
+-- * /shaders/ regions.
 --
 -- == About shader stages
 --
@@ -144,13 +142,13 @@
 -- * /geometry shader/
 -- * /fragment shader/
 --
--- Additionnaly, you can create /compute shaders/ but they’re not usable up to now.
---
 -- When creating a new shader, you have to pass a 'String' representing the source code. This will
 -- change in the end. An EDSL is planned to make things easier and safer, but in the waiting, you
 -- are stuck with 'String', I’m sorry.
 --
--- You have to write /GLSL450/-conformant code.
+-- You have to write either /GLSL330/ or /GLSL450/ conformant code. If you compile with the
+-- __gl45-bindless-textures__ flag, samplers will have an automatic qualifier to make them
+-- bindless.
 --
 -- == About uniforms
 --
@@ -302,13 +300,12 @@
     module Control.Some
   , module Graphics.Luminance.Blending
   , module Graphics.Luminance.Buffer
-  , module Graphics.Luminance.Cmd
   , module Graphics.Luminance.Core.Tuple
+  , module Graphics.Luminance.Core.Draw
   , module Graphics.Luminance.Framebuffer
   , module Graphics.Luminance.Geometry
   , module Graphics.Luminance.Pixel
   , module Graphics.Luminance.Query
-  , module Graphics.Luminance.Region
   , module Graphics.Luminance.RenderCmd
   , module Graphics.Luminance.RW
   , module Graphics.Luminance.Shader
@@ -319,13 +316,12 @@
 import Control.Some
 import Graphics.Luminance.Blending
 import Graphics.Luminance.Buffer
-import Graphics.Luminance.Cmd
 import Graphics.Luminance.Core.Tuple
+import Graphics.Luminance.Core.Draw
 import Graphics.Luminance.Framebuffer
 import Graphics.Luminance.Geometry
 import Graphics.Luminance.Pixel
 import Graphics.Luminance.Query
-import Graphics.Luminance.Region
 import Graphics.Luminance.RenderCmd
 import Graphics.Luminance.RW
 import Graphics.Luminance.Shader
diff --git a/src/Graphics/Luminance/Cmd.hs b/src/Graphics/Luminance/Cmd.hs
deleted file mode 100644
--- a/src/Graphics/Luminance/Cmd.hs
+++ /dev/null
@@ -1,22 +0,0 @@
------------------------------------------------------------------------------
--- |
--- Copyright   : (C) 2015, 2016 Dimitri Sabadie
--- License     : BSD3
---
--- Maintainer  : Dimitri Sabadie <dimitri.sabadie@gmail.com>
--- Stability   : experimental
--- Portability : portable
------------------------------------------------------------------------------
-
-module Graphics.Luminance.Cmd (
-  {-
-    -- * Command type
-    Cmd
-  , runCmd
-    -- * Available commands
-  , draw
-  , blit
-  -}
-  ) where
-
-import Graphics.Luminance.Core.Cmd
diff --git a/src/Graphics/Luminance/Core/Cmd.hs b/src/Graphics/Luminance/Core/Cmd.hs
deleted file mode 100644
--- a/src/Graphics/Luminance/Core/Cmd.hs
+++ /dev/null
@@ -1,55 +0,0 @@
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-
------------------------------------------------------------------------------
--- |
--- Copyright   : (C) 2015, 2016 Dimitri Sabadie
--- License     : BSD3
---
--- Maintainer  : Dimitri Sabadie <dimitri.sabadie@gmail.com>
--- Stability   : experimental
--- Portability : portable
------------------------------------------------------------------------------
-
-module Graphics.Luminance.Core.Cmd where
-
-import Control.Monad.IO.Class ( MonadIO(..) )
-import Graphics.Luminance.Core.Framebuffer
-import Graphics.Luminance.Core.RW ( Readable, Writable )
-import Graphics.Luminance.Core.Texture ( Filter )
-import Numeric.Natural ( Natural )
-
-{-
--- |Command type. Used to accumulate GPU commands. Use 'runCmd' to execute
--- the whole chain of commands.
-newtype Cmd a = Cmd (IO a) deriving (Applicative,Functor,Monad)
-
-runCmd :: (MonadIO m) => Cmd a -> m a
-runCmd (Cmd a) = liftIO a
-
--- |Draw a framebuffer batch and return the framebuffer’s output.
-draw :: FBBatch rw c d -> Cmd (Output c d)
-draw fbb = Cmd $ do
-  runFBBatch fbb
-  pure . framebufferOutput $ fbBatchFramebuffer fbb
-
--- |Blit a framebuffer batch onto a framebuffer and return the framebuffer’s output of the write
--- framebuffer.
-blit :: (Readable r,Writable w)
-     => Framebuffer r c0 d0
-     -> Framebuffer w c1 d1
-     -> Int
-     -> Int
-     -> Natural
-     -> Natural
-     -> Int
-     -> Int
-     -> Natural
-     -> Natural
-     -> FramebufferBlitMask
-     -> Filter
-     -> Cmd (Output c1 d1)
-blit r w rx ry rwidth rheight wx wy wwidth wheight mask flt = Cmd $ do
-  framebufferBlit r w rx ry rwidth rheight wx wy wwidth wheight mask flt
-  pure (framebufferOutput w)
-
--}
diff --git a/src/Graphics/Luminance/Core/Draw.hs b/src/Graphics/Luminance/Core/Draw.hs
new file mode 100644
--- /dev/null
+++ b/src/Graphics/Luminance/Core/Draw.hs
@@ -0,0 +1,100 @@
+-----------------------------------------------------------------------------
+-- |
+-- Copyright   : (C) 2015, 2016 Dimitri Sabadie
+-- License     : BSD3
+--
+-- Maintainer  : Dimitri Sabadie <dimitri.sabadie@gmail.com>
+-- Stability   : experimental
+-- Portability : portable
+-----------------------------------------------------------------------------
+
+module Graphics.Luminance.Core.Draw where
+
+import Control.Monad.IO.Class ( MonadIO(..) )
+import Data.Bits ( (.|.) )
+import Data.Foldable ( traverse_ )
+import Foreign.Ptr ( nullPtr )
+import Graphics.GL
+import Graphics.Luminance.Core.Blending ( setBlending )
+import Graphics.Luminance.Core.Debug ( debugGL )
+import Graphics.Luminance.Core.Framebuffer ( Framebuffer(..), Output, defaultFramebuffer )
+import Graphics.Luminance.Core.Geometry ( Geometry(..), VertexArray(..) )
+import Graphics.Luminance.Core.RW ( RW, Writable )
+import Graphics.Luminance.Core.RenderCmd ( RenderCmd(..) )
+import Graphics.Luminance.Core.Shader.Program ( Program(..), U'(..) )
+
+-- |Frame command.
+data FrameCmd rw c d a = FrameCmd {
+    frameCmdFramebuffer :: Framebuffer rw c d
+  , frameCmdShadingCmds :: [ShadingCmd rw c d a]
+  }
+
+-- |Build a 'FrameCmd' for the default framebuffer.
+defaultFrameCmd :: [ShadingCmd RW () () a] -> FrameCmd RW () () a
+defaultFrameCmd = FrameCmd defaultFramebuffer
+
+-- |Shading command.
+data ShadingCmd rw c d a = ShadingCmd {
+    shadingCmdProgram :: Program a
+  , shadingCmdUniforms :: a -> U'
+  , shadingCmdDrawCmds :: [DrawCmd rw c d a]
+  }
+
+-- |Draw command.
+newtype DrawCmd rw c d a = DrawCmd { drawCmd :: a -> (U',RenderCmd rw c d Geometry) }
+
+-- |Build a 'DrawCmd', updating the program’s interface.
+updateAndDraw :: (a -> U') -> RenderCmd rw c d Geometry -> DrawCmd rw c d a
+updateAndDraw update rdrCmd = DrawCmd $ \a -> (update a,rdrCmd)
+
+-- |Build a 'DrawCmd' without updating the program’s interface.
+pureDraw :: RenderCmd rw c d Geometry -> DrawCmd rw c d a
+pureDraw rdrCmd = DrawCmd $ const (mempty,rdrCmd)
+
+-- |Issue a draw to the GPU. Don’t be afraid of the type signature. Let’s explain it.
+--
+-- The first parameter is the framebuffer you want to perform the rendering in. It must be
+-- writable.
+--
+-- The second parameter is a list of /shading commands/. A shading command is composed of three
+-- parts:
+--
+-- * a 'Program' used for shading;
+-- * a @(a -> 'U'')@ uniform sink used to update uniforms in the program passed as first value;
+--   this is useful if you want to update uniforms only once per draw or for all render
+--   commands, like time, user event, etc.;
+-- * a list of /render commands/ function; that function enables you to update uniforms via the
+--   @(a -> 'U'')@ uniform sink for each render command that follows.
+--
+-- This function yields a value of type @'Output' m c d'@, which represents the output of the render
+-- – typically, textures or '()'.
+draw :: (MonadIO m,Writable w)
+     => FrameCmd w c d a
+     -> m (Output c d)
+draw fc = do
+  debugGL $ glBindFramebuffer GL_DRAW_FRAMEBUFFER (fromIntegral . framebufferID $ frameCmdFramebuffer fc)
+  debugGL $ glClear $ GL_DEPTH_BUFFER_BIT .|. GL_COLOR_BUFFER_BIT
+  traverse_ shade (frameCmdShadingCmds fc)
+  pure (framebufferOutput . frameCmdFramebuffer $ fc)
+
+shade :: (MonadIO m) => ShadingCmd rw c d a -> m ()
+shade shd = do
+    debugGL $ glUseProgram (programID prog)
+    liftIO . runU' $ (shadingCmdUniforms shd) iface
+    traverse_ (\drw -> uncurry render $ drawCmd drw iface) (shadingCmdDrawCmds shd)
+  where
+    prog = shadingCmdProgram shd
+    iface = programInterface prog
+
+render :: (MonadIO m) => U' -> RenderCmd rw c d Geometry -> m ()
+render u (RenderCmd blending depthTest geometry) = do
+  liftIO (runU' u)
+  setBlending blending
+  (if depthTest then glEnable else glDisable) GL_DEPTH_TEST
+  case geometry of
+    DirectGeometry (VertexArray vid mode vbNb) -> do
+      debugGL $ glBindVertexArray vid
+      debugGL $ glDrawArrays mode 0 vbNb
+    IndexedGeometry (VertexArray vid mode ixNb) -> do
+      debugGL $ glBindVertexArray vid
+      debugGL $ glDrawElements mode ixNb GL_UNSIGNED_INT nullPtr
diff --git a/src/Graphics/Luminance/Core/Geometry.hs b/src/Graphics/Luminance/Core/Geometry.hs
--- a/src/Graphics/Luminance/Core/Geometry.hs
+++ b/src/Graphics/Luminance/Core/Geometry.hs
@@ -88,7 +88,7 @@
     -- vertex buffer
     vreg :: Buffer W v <- createBuffer $ newRegion (fromIntegral vertNb)
     writeWhole vreg vertices
-    liftIO $ glVertexArrayVertexBuffer vid vertexBindingIndex (bufferID reg) 0 (fromIntegral $ sizeOf (undefined :: v))
+    liftIO $ glVertexArrayVertexBuffer vid vertexBindingIndex (bufferID vreg) 0 (fromIntegral $ sizeOf (undefined :: v))
     _ <- setFormatV vid 0 0 (Proxy :: Proxy v)
     -- element buffer, if required
     case indices of
diff --git a/src/Graphics/Luminance/Core/Region.hs b/src/Graphics/Luminance/Core/Region.hs
deleted file mode 100644
--- a/src/Graphics/Luminance/Core/Region.hs
+++ /dev/null
@@ -1,65 +0,0 @@
-{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-{-# LANGUAGE PolyKinds #-}
-
------------------------------------------------------------------------------
--- |
--- Copyright   : (C) 2015, 2016 Dimitri Sabadie
--- License     : BSD3
---
--- Maintainer  : Dimitri Sabadie <dimitri.sabadie@gmail.com>
--- Stability   : experimental
--- Portability : portable
------------------------------------------------------------------------------
-
-module Graphics.Luminance.Core.Region where
-
-import Control.Monad.IO.Class ( MonadIO(..) )
-import Control.Monad.Trans ( MonadTrans(..) )
-import Control.Some ( Some(..) )
-import Data.Bits
-import Foreign.Ptr ( nullPtr )
-import Graphics.GL
-import Graphics.Luminance.Core.Blending ( setBlending )
-import Graphics.Luminance.Core.Debug
-import Graphics.Luminance.Core.Framebuffer ( Framebuffer(..) )
-import Graphics.Luminance.Core.Geometry ( Geometry(..), VertexArray(..) )
-import Graphics.Luminance.Core.Shader.Program ( Program(..), )
-import Graphics.Luminance.Core.RenderCmd ( RenderCmd(..) )
-
--- |A 'Region' is a monad transformer used to create relationships between two monadic layers
--- and ensure GPU safety.
-newtype Region r m a = Region { runRegion :: m a } deriving (Applicative,Functor,Monad,MonadIO)
-
-instance MonadTrans (Region r) where
-  lift = Region
-
--- |The /GPU/ main 'Region'. This 'Region' is the highest and more general you can find. You’ll need
--- to enter it if you want to enter any /GPU/ specific regions.
-gpuRegion :: Region () m a -> m a
-gpuRegion = runRegion
-
--- |The 'Framebuffer' 'Region'. This 'Region' binds a 'Framebuffer' for all children regions.
-newFrame :: (MonadIO m) => Framebuffer rw c d -> Region Framebuffer m a -> Region () m a
-newFrame fb fbRegion = do
-  liftIO . debugGL $ glBindFramebuffer GL_DRAW_FRAMEBUFFER (fromIntegral $ framebufferID fb)
-  liftIO . debugGL $ glClear $ GL_DEPTH_BUFFER_BIT .|. GL_COLOR_BUFFER_BIT
-  lift (runRegion fbRegion)
-
--- |The 'Program' 'Region'. This 'Region' binds a 'Program' for all children regions.
-newShading :: (MonadIO m) => Some Program -> Region Program m a -> Region Framebuffer m a
-newShading (Some prog) progRegion = do
-  liftIO . debugGL $ glUseProgram (programID prog)
-  lift (runRegion progRegion)
-
--- |Draw the 'Geometry' held by a 'RenderCmd'.
-drawGeometry :: (MonadIO m) => RenderCmd rw c d Geometry -> Region Program m ()
-drawGeometry (RenderCmd blending depthTest geometry) = do
-  setBlending blending
-  (if depthTest then glEnable else glDisable) GL_DEPTH_TEST
-  case geometry of
-    DirectGeometry (VertexArray vid mode vbNb) -> do
-      debugGL $ glBindVertexArray vid
-      debugGL $ glDrawArrays mode 0 vbNb
-    IndexedGeometry (VertexArray vid mode ixNb) -> do
-      debugGL $ glBindVertexArray vid
-      debugGL $ glDrawElements mode ixNb GL_UNSIGNED_INT nullPtr
diff --git a/src/Graphics/Luminance/Region.hs b/src/Graphics/Luminance/Region.hs
deleted file mode 100644
--- a/src/Graphics/Luminance/Region.hs
+++ /dev/null
@@ -1,21 +0,0 @@
------------------------------------------------------------------------------
--- |
--- Copyright   : (C) 2015, 2016 Dimitri Sabadie
--- License     : BSD3
---
--- Maintainer  : Dimitri Sabadie <dimitri.sabadie@gmail.com>
--- Stability   : experimental
--- Portability : portable
------------------------------------------------------------------------------
-
-module Graphics.Luminance.Region (
-    -- * Regions
-    Region
-  , gpuRegion
-  , newFrame
-  , newShading
-    -- * Drawing
-  , drawGeometry
-  ) where
-
-import Graphics.Luminance.Core.Region
diff --git a/src/Graphics/Luminance/Shader/Program.hs b/src/Graphics/Luminance/Shader/Program.hs
--- a/src/Graphics/Luminance/Shader/Program.hs
+++ b/src/Graphics/Luminance/Shader/Program.hs
@@ -19,10 +19,10 @@
   , U
   , U'
   , (.=)
+  , updateUniforms
   , UniformInterface
   , UniformName(..)
   , SomeUniformName(..)
-  , updateUniforms
     -- * Uniform block
   , UniformBlock
   , UB(..)
