diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,9 @@
 # Revision history for greskell
 
+## 0.2.3.0  -- 2019-01-01
+
+* Add Extra module.
+
 ## 0.2.2.0  -- 2018-11-23
 
 * Add new `AsLabel` module.
diff --git a/greskell.cabal b/greskell.cabal
--- a/greskell.cabal
+++ b/greskell.cabal
@@ -1,5 +1,5 @@
 name:                   greskell
-version:                0.2.2.0
+version:                0.2.3.0
 author:                 Toshio Ito <debug.ito@gmail.com>
 maintainer:             Toshio Ito <debug.ito@gmail.com>
 license:                BSD3
@@ -32,7 +32,8 @@
                         Data.Greskell.Binder,
                         Data.Greskell.Graph,
                         Data.Greskell.GTraversal,
-                        Data.Greskell.AsLabel
+                        Data.Greskell.AsLabel,
+                        Data.Greskell.Extra
   -- other-modules:        
   build-depends:        base >=4.9.0.0 && <4.13,
                         greskell-core >=0.1.2.0 && <0.2,
@@ -55,7 +56,8 @@
   other-modules:        Data.Greskell.BinderSpec,
                         Data.Greskell.GTraversalSpec,
                         Data.Greskell.GremlinSpec,
-                        Data.Greskell.GraphSpec
+                        Data.Greskell.GraphSpec,
+                        Data.Greskell.ExtraSpec
   build-depends:        base, text, aeson,  unordered-containers,
                         greskell, greskell-core,
                         hspec >=2.2.3,
diff --git a/src/Data/Greskell.hs b/src/Data/Greskell.hs
--- a/src/Data/Greskell.hs
+++ b/src/Data/Greskell.hs
@@ -5,6 +5,11 @@
 --
 -- Data.Greskell is a Haskell support to use the Gremlin graph query
 -- language. For more information, see [project README](https://github.com/debug-ito/greskell).
+--
+-- This module re-exports most modules from greskell and greskell-core
+-- packages. The following modules are excluded from re-export:
+--
+-- - "Data.Greskell.Extra": extra utility functions.
 module Data.Greskell
        (
          module Data.Greskell.Greskell,
diff --git a/src/Data/Greskell/Extra.hs b/src/Data/Greskell/Extra.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Greskell/Extra.hs
@@ -0,0 +1,41 @@
+-- |
+-- Module: Data.Greskell.Extra
+-- Description: Extra utility functions implemented by Greskell
+-- Maintainer: Toshio Ito <debug.ito@gmail.com>
+--
+-- Extra utility functions implemented by Greskell.
+--
+-- @since 0.2.3.0
+module Data.Greskell.Extra
+  ( writePropertyKeyValues,
+    writeAllProperties
+  ) where
+
+import Data.Aeson (ToJSON)
+import Data.Greskell.Binder (Binder, newBind)
+import Data.Greskell.Graph
+  ( PropertyMap(..), Property(..), Element
+  )
+import qualified Data.Greskell.Graph as Graph
+import Data.Greskell.GTraversal (Walk, SideEffect, gProperty)
+import Data.Monoid (mconcat)
+import Data.Text (Text)
+
+-- | Make a series of @.property@ steps to write the given key-value
+-- pairs as properties.
+--
+-- @since 0.2.3.0
+writePropertyKeyValues :: (ToJSON v, Element e) => [(Text, v)] -> Binder (Walk SideEffect e e)
+writePropertyKeyValues pairs = fmap mconcat $ mapM toPropStep pairs
+  where
+    toPropStep (key, value) = fmap (gProperty $ Graph.key key) $ newBind value
+
+-- | Make a series of @.property@ steps to write all properties in the
+-- given 'PropertyMap'.
+--
+-- @since 0.2.3.0
+writeAllProperties :: (PropertyMap m, Property p, ToJSON v, Element e)
+                   => m p v -> Binder (Walk SideEffect e e)
+writeAllProperties ps = writePropertyKeyValues $ map toPair $ allProperties ps
+  where
+    toPair prop = (propertyKey prop, propertyValue prop)
diff --git a/test/Data/Greskell/ExtraSpec.hs b/test/Data/Greskell/ExtraSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Data/Greskell/ExtraSpec.hs
@@ -0,0 +1,48 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Data.Greskell.ExtraSpec (main,spec) where
+
+import Data.Monoid (mempty, (<>))
+import Data.Text (Text)
+import Test.Hspec
+
+import Data.Aeson (Value(..))
+import Data.Greskell.Binder (Binder, Binding, runBinder)
+import Data.Greskell.Extra (writePropertyKeyValues)
+import Data.Greskell.Graph (AVertex)
+import Data.Greskell.Greskell (toGremlin)
+import Data.Greskell.GTraversal (Walk, WalkType)
+import qualified Data.HashMap.Strict as HM
+
+main :: IO ()
+main = hspec spec
+
+runBoundWalk :: WalkType c => Binder (Walk c AVertex AVertex) -> (Text, Binding)
+runBoundWalk = doFst . runBinder
+  where
+    doFst (w, b) = (toGremlin w, b)
+
+spec :: Spec
+spec = do
+  describe "writePropertyKeyValues" $ do
+    specify "empty" $ do
+      let input :: [(Text, ())]
+          input = []
+      (runBoundWalk $ writePropertyKeyValues input) `shouldBe` ("__.identity()", mempty)
+    specify "one prop" $ do
+      let input :: [(Text, Int)]
+          input = [("age", 24)]
+      (runBoundWalk $ writePropertyKeyValues input)
+        `shouldBe` ( "__.property(\"age\",__v0).identity()",
+                     HM.fromList [("__v0", Number 24)]
+                   )
+    specify "multiple props" $ do
+      let input :: [(Text, Value)]
+          input = [("age", Number 24), ("name", String "Toshio"), ("foo", String "bar")]
+      (runBoundWalk $ writePropertyKeyValues input)
+        `shouldBe` ( "__.property(\"age\",__v0).property(\"name\",__v1)"
+                     <> ".property(\"foo\",__v2).identity()",
+                     HM.fromList [ ("__v0", Number 24),
+                                   ("__v1", String "Toshio"),
+                                   ("__v2", String "bar")
+                                 ]
+                   )
