diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,3 @@
+# Changelog for cursor-brick
+
+## Unreleased changes
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2019 Tom Sydney Kerckhove
+
+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/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/cursor-brick.cabal b/cursor-brick.cabal
new file mode 100644
--- /dev/null
+++ b/cursor-brick.cabal
@@ -0,0 +1,44 @@
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.31.1.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 7d8cfb93a2e1e9e9cbfb16cbe022245b498e38c2b591cb9da187759a356bee6f
+
+name:           cursor-brick
+version:        0.0.0.0
+description:    Please see the README on GitHub at <https://github.com/NorfairKing/cursor-brick#readme>
+homepage:       https://github.com/NorfairKing/cursor-brick#readme
+bug-reports:    https://github.com/NorfairKing/cursor-brick/issues
+author:         Tom Sydney Kerckhove
+maintainer:     syd@cs-syd.eu
+copyright:      Copyright: (c) 2019 Tom Sydney Kerckhove
+license:        MIT
+license-file:   LICENSE
+build-type:     Simple
+extra-source-files:
+    ChangeLog.md
+
+source-repository head
+  type: git
+  location: https://github.com/NorfairKing/cursor-brick
+
+library
+  exposed-modules:
+      Cursor.Brick
+      Cursor.Brick.Forest
+      Cursor.Brick.List
+      Cursor.Brick.List.NonEmpty
+      Cursor.Brick.Map
+      Cursor.Brick.Map.KeyValue
+      Cursor.Brick.Tree
+  other-modules:
+      Paths_cursor_brick
+  hs-source-dirs:
+      src
+  build-depends:
+      base >=4.7 && <5
+    , brick
+    , cursor
+  default-language: Haskell2010
diff --git a/src/Cursor/Brick.hs b/src/Cursor/Brick.hs
new file mode 100644
--- /dev/null
+++ b/src/Cursor/Brick.hs
@@ -0,0 +1,7 @@
+module Cursor.Brick
+  ( module Cursor.Brick.List
+  , module Cursor.Brick.List.NonEmpty
+  ) where
+
+import Cursor.Brick.List
+import Cursor.Brick.List.NonEmpty
diff --git a/src/Cursor/Brick/Forest.hs b/src/Cursor/Brick/Forest.hs
new file mode 100644
--- /dev/null
+++ b/src/Cursor/Brick/Forest.hs
@@ -0,0 +1,61 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Cursor.Brick.Forest where
+
+import Control.Monad
+
+import Cursor.Forest
+import Cursor.Tree
+
+import Brick.Types
+import Brick.Widgets.Core
+
+import Cursor.Brick.List.NonEmpty
+import Cursor.Brick.Tree
+
+horizontalForestCursorWidgetM ::
+     Monad m
+  => (CTree b -> m (Widget n))
+  -> (TreeCursor a b -> m (Widget n))
+  -> (CTree b -> m (Widget n))
+  -> ForestCursor a b
+  -> m (Widget n)
+horizontalForestCursorWidgetM prevFunc curFunc nextFunc =
+  horizontalNonEmptyCursorWidgetM prevFunc curFunc nextFunc . forestCursorListCursor
+
+horizontalForestCursorWidget ::
+     (CTree b -> Widget n)
+  -> (TreeCursor a b -> Widget n)
+  -> (CTree b -> Widget n)
+  -> ForestCursor a b
+  -> Widget n
+horizontalForestCursorWidget prevFunc curFunc nextFunc =
+  horizontalNonEmptyCursorWidget prevFunc curFunc nextFunc . forestCursorListCursor
+
+verticalForestCursorWidgetM ::
+     Monad m
+  => (CTree b -> m (Widget n))
+  -> (TreeCursor a b -> m (Widget n))
+  -> (CTree b -> m (Widget n))
+  -> ForestCursor a b
+  -> m (Widget n)
+verticalForestCursorWidgetM prevFunc curFunc nextFunc =
+  verticalNonEmptyCursorWidgetM prevFunc curFunc nextFunc . forestCursorListCursor
+
+verticalForestCursorWidget ::
+     (CTree b -> Widget n)
+  -> (TreeCursor a b -> Widget n)
+  -> (CTree b -> Widget n)
+  -> ForestCursor a b
+  -> Widget n
+verticalForestCursorWidget prevFunc curFunc nextFunc =
+  verticalNonEmptyCursorWidget prevFunc curFunc nextFunc . forestCursorListCursor
+
+forestCursorWidgetM ::
+     ([CTree b] -> TreeCursor a b -> [CTree b] -> m (Widget n)) -> ForestCursor a b -> m (Widget n)
+forestCursorWidgetM = foldForestCursor
+
+forestCursorWidget ::
+     ([CTree b] -> TreeCursor a b -> [CTree b] -> Widget n) -> ForestCursor a b -> Widget n
+forestCursorWidget = foldForestCursor
diff --git a/src/Cursor/Brick/List.hs b/src/Cursor/Brick/List.hs
new file mode 100644
--- /dev/null
+++ b/src/Cursor/Brick/List.hs
@@ -0,0 +1,14 @@
+{-# LANGUAGE RecordWildCards #-}
+
+module Cursor.Brick.List where
+
+import Cursor.List
+
+import Brick.Types as B
+import Brick.Widgets.Core as B
+
+listCursorWidgetM :: ([a] -> [a] -> m (Widget n)) -> ListCursor a -> m (Widget n)
+listCursorWidgetM = foldListCursor
+
+listCursorWidget :: ([a] -> [a] -> Widget n) -> ListCursor a -> Widget n
+listCursorWidget = foldListCursor
diff --git a/src/Cursor/Brick/List/NonEmpty.hs b/src/Cursor/Brick/List/NonEmpty.hs
new file mode 100644
--- /dev/null
+++ b/src/Cursor/Brick/List/NonEmpty.hs
@@ -0,0 +1,48 @@
+{-# LANGUAGE RecordWildCards #-}
+
+module Cursor.Brick.List.NonEmpty where
+
+import Cursor.List.NonEmpty
+
+import Brick.Types as B
+import Brick.Widgets.Core as B
+
+horizontalNonEmptyCursorWidgetM ::
+     Applicative f
+  => (b -> f (Widget n))
+  -> (a -> f (Widget n))
+  -> (b -> f (Widget n))
+  -> NonEmptyCursor a b
+  -> f (Widget n)
+horizontalNonEmptyCursorWidgetM beforeFunc curFunc afterFunc =
+  nonEmptyCursorWidgetM $ \befores current afters ->
+    hBox <$> sequenceA (concat [map beforeFunc befores, [curFunc current], map afterFunc afters])
+
+horizontalNonEmptyCursorWidget ::
+     (b -> Widget n) -> (a -> Widget n) -> (b -> Widget n) -> NonEmptyCursor a b -> Widget n
+horizontalNonEmptyCursorWidget beforeFunc curFunc afterFunc =
+  nonEmptyCursorWidget $ \befores current afters ->
+    hBox $ concat [map beforeFunc befores, [curFunc current], map afterFunc afters]
+
+verticalNonEmptyCursorWidgetM ::
+     Applicative f
+  => (b -> f (Widget n))
+  -> (a -> f (Widget n))
+  -> (b -> f (Widget n))
+  -> NonEmptyCursor a b
+  -> f (Widget n)
+verticalNonEmptyCursorWidgetM beforeFunc curFunc afterFunc =
+  nonEmptyCursorWidgetM $ \befores current afters ->
+    vBox <$> sequenceA (concat [map beforeFunc befores, [curFunc current], map afterFunc afters])
+
+verticalNonEmptyCursorWidget ::
+     (b -> Widget n) -> (a -> Widget n) -> (b -> Widget n) -> NonEmptyCursor a b -> Widget n
+verticalNonEmptyCursorWidget beforeFunc curFunc afterFunc =
+  nonEmptyCursorWidget $ \befores current afters ->
+    vBox $ concat [map beforeFunc befores, [curFunc current], map afterFunc afters]
+
+nonEmptyCursorWidgetM :: ([b] -> a -> [b] -> m (Widget n)) -> NonEmptyCursor a b -> m (Widget n)
+nonEmptyCursorWidgetM = foldNonEmptyCursor
+
+nonEmptyCursorWidget :: ([b] -> a -> [b] -> Widget n) -> NonEmptyCursor a b -> Widget n
+nonEmptyCursorWidget = foldNonEmptyCursor
diff --git a/src/Cursor/Brick/Map.hs b/src/Cursor/Brick/Map.hs
new file mode 100644
--- /dev/null
+++ b/src/Cursor/Brick/Map.hs
@@ -0,0 +1,75 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Cursor.Brick.Map where
+
+import Control.Monad
+
+import Cursor.List.NonEmpty
+import Cursor.Map
+
+import Brick.Types
+import Brick.Widgets.Core
+
+import Cursor.Brick.List.NonEmpty
+import Cursor.Brick.Map.KeyValue
+
+horizontalMapCursorWidget ::
+     (k -> v -> Widget n)
+  -> (KeyValueCursor kc vc k v -> Widget n)
+  -> (k -> v -> Widget n)
+  -> MapCursor kc vc k v
+  -> Widget n
+horizontalMapCursorWidget beforeFunc curFunc afterFunc =
+  mapCursorWidget $ \befores current afters ->
+    hBox $
+    concat [map (uncurry beforeFunc) befores, [curFunc current], map (uncurry afterFunc) afters]
+
+horizontalMapCursorWidgetM ::
+     Applicative f
+  => (k -> v -> f (Widget n))
+  -> (KeyValueCursor kc vc k v -> f (Widget n))
+  -> (k -> v -> f (Widget n))
+  -> MapCursor kc vc k v
+  -> f (Widget n)
+horizontalMapCursorWidgetM beforeFunc curFunc afterFunc =
+  mapCursorWidgetM $ \befores current afters ->
+    hBox <$>
+    sequenceA
+      (concat [map (uncurry beforeFunc) befores, [curFunc current], map (uncurry afterFunc) afters])
+
+verticalMapCursorWidget ::
+     (k -> v -> Widget n)
+  -> (KeyValueCursor kc vc k v -> Widget n)
+  -> (k -> v -> Widget n)
+  -> MapCursor kc vc k v
+  -> Widget n
+verticalMapCursorWidget beforeFunc curFunc afterFunc =
+  mapCursorWidget $ \befores current afters ->
+    vBox $
+    concat [map (uncurry beforeFunc) befores, [curFunc current], map (uncurry afterFunc) afters]
+
+verticalMapCursorWidgetM ::
+     Applicative f
+  => (k -> v -> f (Widget n))
+  -> (KeyValueCursor kc vc k v -> f (Widget n))
+  -> (k -> v -> f (Widget n))
+  -> MapCursor kc vc k v
+  -> f (Widget n)
+verticalMapCursorWidgetM beforeFunc curFunc afterFunc =
+  mapCursorWidgetM $ \befores current afters ->
+    vBox <$>
+    sequenceA
+      (concat [map (uncurry beforeFunc) befores, [curFunc current], map (uncurry afterFunc) afters])
+
+mapCursorWidget ::
+     ([(k, v)] -> KeyValueCursor kc vc k v -> [(k, v)] -> Widget n)
+  -> MapCursor kc vc k v
+  -> Widget n
+mapCursorWidget = foldMapCursor
+
+mapCursorWidgetM ::
+     ([(k, v)] -> KeyValueCursor kc vc k v -> [(k, v)] -> m (Widget n))
+  -> MapCursor kc vc k v
+  -> m (Widget n)
+mapCursorWidgetM = foldMapCursor
diff --git a/src/Cursor/Brick/Map/KeyValue.hs b/src/Cursor/Brick/Map/KeyValue.hs
new file mode 100644
--- /dev/null
+++ b/src/Cursor/Brick/Map/KeyValue.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Cursor.Brick.Map.KeyValue where
+
+import Control.Monad
+
+import Cursor.List.NonEmpty
+import Cursor.Map
+
+import Brick.Types
+import Brick.Widgets.Core
+
+import Cursor.Brick.List.NonEmpty
+
+keyValueWidget ::
+     (kc -> v -> Widget n) -> (k -> vc -> Widget n) -> KeyValueCursor kc vc k v -> Widget n
+keyValueWidget = foldKeyValueCursor
+
+keyValueWidgetM ::
+     (kc -> v -> f (Widget n))
+  -> (k -> vc -> f (Widget n))
+  -> KeyValueCursor kc vc k v
+  -> f (Widget n)
+keyValueWidgetM = foldKeyValueCursor
diff --git a/src/Cursor/Brick/Tree.hs b/src/Cursor/Brick/Tree.hs
new file mode 100644
--- /dev/null
+++ b/src/Cursor/Brick/Tree.hs
@@ -0,0 +1,27 @@
+{-# LANGUAGE RecordWildCards #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Cursor.Brick.Tree where
+
+import Control.Monad
+
+import Cursor.Tree
+
+import Brick.Types
+import Brick.Widgets.Core
+
+treeCursorWidgetM ::
+     forall a b n m. Monad m
+  => ([CTree b] -> b -> [CTree b] -> Widget n -> m (Widget n))
+  -> (a -> CForest b -> m (Widget n))
+  -> TreeCursor a b
+  -> m (Widget n)
+treeCursorWidgetM = traverseTreeCursor
+
+treeCursorWidget ::
+     forall a b n.
+     ([CTree b] -> b -> [CTree b] -> Widget n -> Widget n)
+  -> (a -> CForest b -> Widget n)
+  -> TreeCursor a b
+  -> Widget n
+treeCursorWidget = foldTreeCursor
