diff --git a/yesod-examples.cabal b/yesod-examples.cabal
--- a/yesod-examples.cabal
+++ b/yesod-examples.cabal
@@ -1,5 +1,5 @@
 Name:                yesod-examples
-Version:             0.5.0
+Version:             0.5.0.1
 Synopsis:            Example programs using the Yesod Web Framework.
 Description:         These are the same examples and tutorials found on the documentation site.
 Homepage:            http://docs.yesodweb.com/
@@ -17,7 +17,7 @@
 Executable helloworld
   Main-is:             yesod/helloworld.lhs
   Build-depends:       base >= 4 && < 5,
-                       yesod >= 0.5.0 && < 0.6
+                       yesod >= 0.5.0.1 && < 0.6
 
 Executable blog
   Main-is:             yesod/tutorial/blog.lhs
@@ -42,6 +42,13 @@
 
 Executable widgets
   Main-is:             yesod/tutorial/widgets.lhs
+
+Executable form
+  Main-is:             yesod/tutorial/form.lhs
+
+Executable mkToForm
+  Main-is:             yesod/tutorial/mkToForm.hs
+  Build-depends:       time
 
 Executable persistent-synopsis
   Main-is:             persistent/synopsis.lhs
diff --git a/yesod/tutorial/form.lhs b/yesod/tutorial/form.lhs
new file mode 100644
--- /dev/null
+++ b/yesod/tutorial/form.lhs
@@ -0,0 +1,48 @@
+Forms can be a tedious part of web development since they require synchronization of code in many different areas: the HTML form declaration, parsing of the form and reconstructing a datatype from the raw values. The Yesod form library simplifies things greatly. We'll start off with a basic application.
+
+
+> {-# LANGUAGE TypeFamilies, QuasiQuotes, OverloadedStrings #-}
+> import Yesod
+> import Control.Applicative
+> data FormExample = FormExample
+> type Handler = GHandler FormExample FormExample
+> mkYesod "FormExample" [$parseRoutes|
+> / RootR GET
+> |]
+> instance Yesod FormExample where approot _ = ""
+
+Next, we'll declare a Person datatype with a name and age. After that, we'll create a formlet. A formlet is a declarative approach to forms. It takes a Maybe value and constructs either a blank form, a form based on the original value, or a form based on the values submitted by the user. It also attempts to construct a datatype, failing on validation errors.
+
+> data Person = Person { name :: String, age :: Int }
+>     deriving Show
+> personFormlet p = fieldsToTable $ Person
+>     <$> stringField "Name" (fmap name p)
+>     <*> intField "Age" (fmap age p)
+
+We use an applicative approach and stay mostly declarative. The "fmap name p" bit is just a way to get the name from within a value of type "Maybe Person".
+
+> getRootR :: Handler RepHtml
+> getRootR = do
+>     (res, wform, enctype) <- runFormGet $ personFormlet Nothing
+
+We use runFormGet to bind to GET (query-string) parameters; we could also use runFormPost. The "Nothing" is the initial value of the form. You could also supply a "Just Person" value if you like. There is a three-tuple returned, containing the parsed value, the HTML form as a widget and the encoding type for the form.
+
+We use a widget for the form since it allows embedding CSS and Javascript code in forms directly. This allows unobtrusive adding of rich Javascript controls like date pickers.
+
+>     defaultLayout $ do
+>         setTitle "Form Example"
+>         form <- extractBody wform
+
+extractBody returns the HTML of a widget and "passes" all of the other declarations (the CSS, Javascript, etc) up to the parent widget. The rest of this is just standard Hamlet code and our main function.
+
+>         addBody [$hamlet|
+> %p Last result: $show.res$
+> %form!enctype=$enctype$
+>     %table
+>         ^form^
+>         %tr
+>             %td!colspan=2
+>                 %input!type=submit
+> |]
+> 
+> main = basicHandler 3000 FormExample
diff --git a/yesod/tutorial/mkToForm.hs b/yesod/tutorial/mkToForm.hs
new file mode 100644
--- /dev/null
+++ b/yesod/tutorial/mkToForm.hs
@@ -0,0 +1,72 @@
+{-# LANGUAGE TypeFamilies, QuasiQuotes, GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+import Yesod
+import Yesod.Helpers.Crud
+import Yesod.Form.Jquery
+import Yesod.Form.Nic
+import Database.Persist.Sqlite
+import Database.Persist.TH
+import Data.Time (Day)
+
+share2 mkToForm mkPersist [$persist|
+Entry
+    title String
+    day Day Desc toFormField=YesodJquery.jqueryDayField
+    content Html toFormField=YesodNic.nicHtmlField
+    deriving
+|]
+
+instance Item Entry where
+    itemTitle = entryTitle
+
+data Blog = Blog { pool :: ConnectionPool }
+
+type EntryCrud = Crud Blog Entry
+
+mkYesod "Blog" [$parseRoutes|
+/ RootR GET
+/entry/#EntryId EntryR GET
+/admin AdminR EntryCrud defaultCrud
+|]
+
+instance Yesod Blog where
+    approot _ = "http://localhost:3000"
+
+instance YesodPersist Blog where
+    type YesodDB Blog = SqlPersist
+    runDB db = fmap pool getYesod >>= runSqlPool db
+
+instance YesodJquery Blog
+instance YesodNic Blog
+
+getRootR = do
+    entries <- runDB $ selectList [] [EntryDayDesc] 0 0
+    defaultLayout $ do
+        setTitle $ string "Yesod Blog Tutorial Homepage"
+        addBody [$hamlet|
+%h1 Archive
+%ul
+    $forall entries entry
+        %li
+            %a!href=@EntryR.fst.entry@ $entryTitle.snd.entry$
+%p
+    %a!href=@AdminR.CrudListR@ Admin
+|]
+
+getEntryR entryid = do
+    entry <- runDB $ get404 entryid
+    defaultLayout $ do
+        setTitle $ string $ entryTitle entry
+        addBody [$hamlet|
+%h1 $entryTitle.entry$
+%h2 $show.entryDay.entry$
+$entryContent.entry$
+|]
+
+withBlog f = withSqlitePool "blog.db3" 8 $ \pool -> do
+    flip runSqlPool pool $ runMigration $ do
+        migrate (undefined :: Entry)
+    f $ Blog pool
+
+main = withBlog $ basicHandler 3000
