diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,6 @@
-# 0.2.0.14 (2017-07-10)
+# 0.2.0.16 (2017-07-10)
+    * Improvements to the layout engine to always produce a grid. Experimental.
+# 0.2.0.15 (2017-07-10)
     * Expose Vertically and Horizontally for use with ApplicativeDo
 # 0.2.0.14 (2017-07-01)
     * Improved rendering of field names in generic editors.
diff --git a/src/Graphics/UI/Threepenny/Editors/Base.hs b/src/Graphics/UI/Threepenny/Editors/Base.hs
--- a/src/Graphics/UI/Threepenny/Editors/Base.hs
+++ b/src/Graphics/UI/Threepenny/Editors/Base.hs
@@ -1,7 +1,9 @@
 {-# LANGUAGE DeriveFunctor     #-}
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE OverloadedLists   #-}
 {-# LANGUAGE TupleSections     #-}
 {-# LANGUAGE TypeFamilies      #-}
+{-# LANGUAGE ViewPatterns #-}
 {-# OPTIONS_GHC  #-}
 module Graphics.UI.Threepenny.Editors.Base
   ( -- * Editors
@@ -28,11 +30,15 @@
   , Compose(..)
   )where
 
-import           Control.Monad
+import           Data.Foldable (length)
 import           Data.Functor.Compose
 import           Data.Maybe
+import           Data.Monoid
+import           Data.Sequence (Seq)
+import qualified Data.Sequence as Seq
+import           GHC.Exts (IsList(..))
 import           Graphics.UI.Threepenny.Attributes
-import           Graphics.UI.Threepenny.Core
+import           Graphics.UI.Threepenny.Core as UI
 import           Graphics.UI.Threepenny.Elements
 import           Graphics.UI.Threepenny.Events
 import           Graphics.UI.Threepenny.Widgets
@@ -54,42 +60,31 @@
 instance Widget (Editor a) where
   getElement = editorElement
 
-data Layout
-  = Horizontal [Layout]
-  | Vertical [Layout]
-  | Single Element
+newtype Layout
+  = Grid (Seq (Seq (Maybe Element)))-- ^ A non empty list of rows, where all the rows are assumed to have the same length
 
 vertical, horizontal :: Layout -> Layout -> Layout
-vertical (Vertical xx) y = Vertical (xx ++ [y])
-vertical x (Vertical yy) = Vertical (x:yy)
-vertical x y             = Vertical [x,y]
+vertical (Grid rows@(length.head.toList -> l1)) (Grid rows'@(length.head.toList -> l2)) =
+    Grid $ fmap pad1 rows <> fmap pad2 rows'
+  where
+    pad l1 l2 | l1 >= l2   = id
+              | otherwise = (<> Seq.replicate (l2-l1) Nothing)
+    pad1 = pad l1 l2
+    pad2 = pad l2 l1
 
-horizontal (Horizontal xx) y = Horizontal (xx ++ [y])
-horizontal x (Horizontal yy) = Horizontal (x : yy)
-horizontal x y               = Horizontal [x,y]
+horizontal (Grid rows@(length.head.toList -> l1)) (Grid rows'@(length.head.toList -> l2)) =
+    Grid $ Seq.zipWith (<>) (pad1 rows) (pad2 rows')
+  where
+    pad l1 l2 | l1 >= l2 = id
+              | otherwise = \x -> let padding = Seq.replicate (length $ head $ toList x) Nothing in x <> Seq.replicate (l2-l1) padding
+    pad1 = pad l1 l2
+    pad2 = pad l2 l1
 
 single :: Element -> Layout
-single = Single
-
-getHorizontal :: Layout -> [Layout]
-getHorizontal (Horizontal h) = h
-getHorizontal other = [other]
-
-getVertical :: Layout -> [Layout]
-getVertical (Vertical h) = h
-getVertical other = [other]
-
-getSingleOrGrid :: Layout -> UI Element
-getSingleOrGrid (Single e) = return e
-getSingleOrGrid other = runLayout other
-
-getGridLayout :: Layout -> [[Layout]]
-getGridLayout (Vertical hh) = fmap getHorizontal hh
-getGridLayout (Horizontal vv) = getZipList $ sequenceA $ fmap (ZipList . getVertical) $ vv
-getGridLayout other = getGridLayout $ Vertical [other]
+single x = Grid [[Just x]]
 
 runLayout :: Layout -> UI Element
-runLayout = mapM (mapM getSingleOrGrid) . getGridLayout >=> grid . fmap (fmap return)
+runLayout (Grid rows) = grid (toList $ fmap (fmap (maybe new return). toList) rows)
 
 data EditorDef a = EditorDef
   { editorDefTidings :: Tidings a
@@ -214,7 +209,7 @@
   nestedEditorDef <-
     new # sink children ((\x -> [maybe (error "editorSum") editorElement (build x)]) <$> tag')
   --
-  let composed = Vertical [single (getElement l), single nestedEditorDef]
+  let composed = vertical (single (getElement l)) (single nestedEditorDef)
   -- the result event fires when any of the nested editors or the tag selector fire.
   let editedEvents = fmap (edited . snd) options
       eTag = filterJust $ rumors (userSelection l)
diff --git a/threepenny-editors.cabal b/threepenny-editors.cabal
--- a/threepenny-editors.cabal
+++ b/threepenny-editors.cabal
@@ -3,7 +3,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           threepenny-editors
-version:        0.2.0.15
+version:        0.2.0.16
 synopsis:       Composable algebraic editors
 description:    This package provides a type class 'Editable' and combinators to
                 easily put together form-like editors for algebraic datatypes.
@@ -37,6 +37,7 @@
   ghc-options: -Wall -Wno-name-shadowing
   build-depends:
       base >= 4.7 && < 5
+    , containers
     , data-default
     , generics-sop
     , profunctors
