diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2014 - 2015 Alexander Thiemann <mail@athiemann.net>
+Copyright (c) 2014 - 2016 Alexander Thiemann <mail@athiemann.net>
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -31,4 +31,4 @@
 ### License
 
 Released under the MIT license.
-(c) 2014 - 2015 Alexander Thiemann
+(c) 2014 - 2016 Alexander Thiemann
diff --git a/digestive-bootstrap.cabal b/digestive-bootstrap.cabal
--- a/digestive-bootstrap.cabal
+++ b/digestive-bootstrap.cabal
@@ -1,12 +1,12 @@
 name:                digestive-bootstrap
-version:             0.1.0.1
+version:             0.3.0.0
 synopsis:            Speed up form designing using digestive functors and bootstrap
 description:         Generate bootstrap forms out of digestive views
 license:             MIT
 license-file:        LICENSE
 author:              Alexander Thiemann <mail@athiemann.net>
 maintainer:          Alexander Thiemann <mail@athiemann.net>
-copyright:           (c) 2014 - 2015 Alexander Thiemann
+copyright:           (c) 2014 - 2016 Alexander Thiemann
 category:            Web
 build-type:          Simple
 cabal-version:       >=1.10
diff --git a/src/Text/Digestive/Bootstrap.hs b/src/Text/Digestive/Bootstrap.hs
--- a/src/Text/Digestive/Bootstrap.hs
+++ b/src/Text/Digestive/Bootstrap.hs
@@ -2,16 +2,14 @@
 {-# LANGUAGE OverloadedStrings #-}
 module Text.Digestive.Bootstrap
     ( FormMeta (..), FormElement (..), FormElementCfg (..)
-    , StdMethod (..)
+    , FormSection (..), FormComponent (..)
+    , StdMethod (..), NumberUnit
     , renderForm
     )
 where
 
 import Data.Maybe
-#if MIN_VERSION_base(4,8,0)
-#else
 import Data.Monoid
-#endif
 import Network.HTTP.Types.Method
 import Text.Blaze.Bootstrap
 import Text.Blaze.Html5
@@ -41,18 +39,30 @@
 -- | Configuration for a form element
 data FormElement
    = FormElement
-   { fe_name :: T.Text
-   , fe_label :: Maybe T.Text
-   , fe_cfg :: FormElementCfg
+   { fe_name :: !T.Text
+   , fe_label :: !(Maybe T.Text)
+   , fe_placeholder :: !(Maybe T.Text)
+   , fe_cfg :: !FormElementCfg
    }
 
+data FormSection
+    = FormSection
+    { fs_title :: !(Maybe T.Text)
+    , fs_help :: !(Maybe T.Text)
+    , fs_elements :: ![FormElement]
+    }
+
+data FormComponent
+    = FCSection !FormSection
+    | FCHtmlSection !H.Html
+
 -- | Meta information for a HTML form
 data FormMeta
    = FormMeta
    { fm_method :: StdMethod
    , fm_target :: T.Text
-   , fm_elements :: [FormElement]
-   , fm_submitText :: T.Text
+   , fm_components :: [FormComponent]
+   , fm_submitValue :: Html
    }
 
 -- | Render a form defined by 'FormMeta' information and
@@ -60,29 +70,61 @@
 renderForm :: FormMeta -> View Html -> Html
 renderForm formMeta formView =
     H.form ! role "form" ! method formMethod ! action formAction $
-     do mapM_ (renderElement formView) (fm_elements formMeta)
-        formSubmit (toHtml $ fm_submitText formMeta)
+     do mapM_ (renderComponent formView) (fm_components formMeta)
+        formSubmit (fm_submitValue formMeta)
     where
       formMethod = toValue (T.decodeUtf8 $ renderStdMethod (fm_method formMeta))
       formAction = toValue $ fm_target formMeta
 
+renderComponent :: View Html -> FormComponent -> Html
+renderComponent formView comp =
+    case comp of
+      FCSection fs -> renderSection formView fs
+      FCHtmlSection bdy -> bdy
+
+renderSection :: View Html -> FormSection -> Html
+renderSection formView formSection =
+    H.div ! class_ "form-section" $
+    do case fs_title formSection of
+         Nothing -> mempty
+         Just x -> H.h3 ! class_ "form-section-title" $ toHtml x
+       case fs_help formSection of
+         Nothing -> mempty
+         Just x -> H.p ! class_ "form-section-help" $ toHtml x
+       mapM_ (renderElement formView) (fs_elements formSection)
+
 renderElement :: View Html -> FormElement -> Html
 renderElement formView formElement =
-    formGroup $
+    wrapper $
     do case errors (fe_name formElement) formView of
          [] -> mempty
          errorMsgs ->
-             alertBox BootAlertDanger $ H.ul $ mapM_ (H.li . toHtml) errorMsgs
-       case fe_label formElement of
-         Just lbl ->
-             H.label ! for (toValue $ fe_name formElement) $ toHtml lbl
-         Nothing ->
-             mempty
-       let ct = buildFun (fe_name formElement) formView ! class_ "form-control" ! placeholder (toValue $ fromMaybe "" $ fe_label formElement)
-       if hasAddon
-       then H.div ! class_ "input-group" $ (ct >>= \_ -> groupAddonAfter)
-       else ct
+             alertBox BootAlertDanger $ H.ul ! class_ "form-errors" $ mapM_ (H.li . toHtml) errorMsgs
+       case fe_cfg formElement of
+         InputCheckbox ->
+             H.label $
+             do (inputCheckbox (fe_name formElement) formView) <> " "
+                case fe_label formElement of
+                  Nothing -> mempty
+                  Just lbl -> H.toHtml lbl
+         _ ->
+             do case fe_label formElement of
+                  Just lbl ->
+                      H.label ! for (toValue $ fe_name formElement) $ toHtml lbl
+                  Nothing ->
+                      mempty
+                let ct =
+                        buildFun (fe_name formElement) formView
+                        ! class_ "form-control"
+                        ! placeholder (toValue . fromMaybe "" . fe_placeholder $ formElement)
+                if hasAddon
+                then H.div ! class_ "input-group" $ (ct >>= \_ -> groupAddonAfter)
+                else ct
     where
+      wrapper x =
+          case fe_cfg formElement of
+            InputCheckbox -> H.div ! class_ "checkbox" $ x
+            _ -> formGroup x
       (hasAddon, groupAddonAfter) =
           case fe_cfg formElement of
             InputNumber (Just numberUnit) ->
