diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,8 @@
+# 0.6.2
+
+* `encode` now renders attributes in alphabetical order.
+
+
 # 0.6.1
 
 * Documentation improvements.
diff --git a/lib/Xmlbf.hs b/lib/Xmlbf.hs
--- a/lib/Xmlbf.hs
+++ b/lib/Xmlbf.hs
@@ -74,6 +74,7 @@
 import Data.Function (fix)
 import Data.Functor.Identity (Identity(Identity), runIdentity)
 import qualified Data.HashMap.Strict as HM
+import qualified Data.Map.Strict as Map
 import Data.Sequence (Seq)
 import qualified Data.Sequence as Seq
 import qualified Data.Text as T
@@ -554,6 +555,8 @@
 --
 -- Also, it doesn't render CDATA sections. Instead, all text is escaped as
 -- necessary.
+--
+-- Element attributes are rendered in alphabetical order.
 encode :: [Node] -> BB.Builder
 encode xs = mconcat (map encodeNode xs)
   where
@@ -564,13 +567,15 @@
          -- This ugly code is so that we make sure we always bind concatenation
          -- to the right with as little effort as possible, using (<>).
          "<" <> encodeUtf8 t
-             <> encodeAttrs (">" <> encode cs <> "</" <> encodeUtf8 t <> ">") as
+             <> encodeAttrs (">" <> encode cs <> "</" <> encodeUtf8 t <> ">")
+                            (mapFromHashMap as)
     {-# INLINE encodeNode #-}
-    encodeAttrs :: BB.Builder -> HM.HashMap T.Text T.Text -> BB.Builder
-    encodeAttrs = HM.foldlWithKey'
-      (\o k v -> " " <> encodeUtf8 k <> "=\"" <> encodeXmlUtf8 v <> "\"" <> o)
+    encodeAttrs :: BB.Builder -> Map.Map T.Text T.Text -> BB.Builder
+    encodeAttrs = Map.foldrWithKey
+      (\k v o -> " " <> encodeUtf8 k <> "=\"" <> encodeXmlUtf8 v <> "\"" <> o)
     {-# INLINE encodeAttrs #-}
 
+
 --------------------------------------------------------------------------------
 --------------------------------------------------------------------------------
 -- Node fixpoint
@@ -737,4 +742,9 @@
    fixed5 x = BBP.liftFixedToBounded
      (const x BBP.>$< BBP.word8 BBP.>*< BBP.word8
               BBP.>*< BBP.word8 BBP.>*< BBP.word8 BBP.>*< BBP.word8)
+
+mapFromHashMap :: Ord k => HM.HashMap k v -> Map.Map k v
+mapFromHashMap = HM.foldrWithKey' Map.insert Map.empty
+{-# INLINE mapFromHashMap #-}
+
 --}
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -85,13 +85,13 @@
       bsEncode (X.element "x" [("a","y")] [])
         @?= "<x a=\"y\"></x>"
 
-  , HU.testCase "xml: <x b=\"\" a=\"y\"></x>" $ do
+  , HU.testCase "xml: <x a=\"y\" b=\"\"></x>" $ do
       bsEncode (X.element "x" [("a","y"), ("b","")] [])
-        @?= "<x b=\"\" a=\"y\"></x>"
+        @?= "<x a=\"y\" b=\"\"></x>"
 
-  , HU.testCase "xml: <x b=\"z\" a=\"y\"></x>" $ do
+  , HU.testCase "xml: <x a=\"y\" b=\"z\"></x>" $ do
       bsEncode (X.element "x" [("a","y"), ("b","z")] [])
-        @?= "<x b=\"z\" a=\"y\"></x>"
+        @?= "<x a=\"y\" b=\"z\"></x>"
 
   , HU.testCase "xml: <x>foo</x>" $ do
       bsEncode (X.element "x" [] (X.text "foo"))
diff --git a/xmlbf.cabal b/xmlbf.cabal
--- a/xmlbf.cabal
+++ b/xmlbf.cabal
@@ -1,5 +1,5 @@
 name: xmlbf
-version: 0.6.1
+version: 0.6.2
 synopsis: XML back and forth! Parser, renderer, ToXml, FromXml, fixpoints.
 description: XML back and forth! Parser, renderer, ToXml, FromXml, fixpoints.
 homepage: https://gitlab.com/k0001/xmlbf
@@ -8,7 +8,7 @@
 license-file: LICENSE
 author: Renzo Carbonara
 maintainer: ren§ren*zone
-copyright: Copyright 2017-2019 Renzo Carbonara
+copyright: Copyright 2017 Renzo Carbonara
 category: Text, XML
 build-type: Simple
 extra-source-files: ChangeLog.md README.md
