diff --git a/mu-protobuf.cabal b/mu-protobuf.cabal
--- a/mu-protobuf.cabal
+++ b/mu-protobuf.cabal
@@ -1,5 +1,5 @@
 name:          mu-protobuf
-version:       0.4.0.3
+version:       0.4.1.0
 synopsis:
   Protocol Buffers serialization and gRPC schema import for Mu microservices
 
@@ -34,10 +34,11 @@
       base                    >=4.12  && <5
     , bytestring              >=0.10  && <0.11
     , compendium-client       >=0.2   && <0.3
+    , containers              >=0.6   && <0.7
     , http-client             >=0.6   && <0.7
     , http2-grpc-proto3-wire  >=0.1   && <0.2
     , language-protobuf       >=1.0.1 && <2
-    , mu-rpc                  >=0.4   && <0.5
+    , mu-rpc                  >=0.4   && <0.6
     , mu-schema               >=0.3   && <0.4
     , proto3-wire             >=1.1   && <2
     , servant-client-core     >=0.16  && <0.19
@@ -54,6 +55,7 @@
   build-depends:
       base         >=4.12  && <5
     , bytestring
+    , containers   >=0.6   && <0.7
     , mu-protobuf
     , mu-schema    >=0.3.0
     , proto3-wire
diff --git a/src/Mu/Adapter/ProtoBuf.hs b/src/Mu/Adapter/ProtoBuf.hs
--- a/src/Mu/Adapter/ProtoBuf.hs
+++ b/src/Mu/Adapter/ProtoBuf.hs
@@ -41,6 +41,7 @@
 import           Control.Applicative
 import qualified Data.ByteString          as BS
 import           Data.Int
+import qualified Data.Map                 as M
 import           Data.SOP                 (All)
 import qualified Data.Text                as T
 import qualified Data.Text.Lazy           as LT
@@ -337,10 +338,13 @@
   boolVal _ = False
 
 instance {-# OVERLAPS #-}
-         (ProtoBridgeOneFieldValue sch t, KnownNat (FindProtoBufId sch ty name), KnownBool (FindProtoBufPacked sch ty name))
+         ( ProtoBridgeOneFieldValue sch t
+         , KnownNat (FindProtoBufId sch ty name)
+         , KnownBool (FindProtoBufPacked sch ty name) )
          => ProtoBridgeField sch ty ('FieldDef name ('TList t)) where
   fieldToProto (Field (FList xs))
-    | boolVal (Proxy @(FindProtoBufPacked sch ty name)), supportsPacking (Proxy @(FieldValue sch t))
+    | boolVal (Proxy @(FindProtoBufPacked sch ty name))
+    , supportsPacking (Proxy @(FieldValue sch t))
     = packedFieldValueToProto fieldId xs
     | otherwise
     = foldMap (oneFieldValueToProto fieldId) xs
@@ -353,10 +357,40 @@
              | otherwise
              = base
 
-instance TypeError ('Text "maps are not currently supported")
+-- see https://developers.google.com/protocol-buffers/docs/proto3#maps
+{-
+message MapFieldEntry {
+  key_type key = 1;
+  value_type value = 2;
+}
+
+repeated MapFieldEntry map_field = N;
+-}
+instance ( KnownNat (FindProtoBufId sch ty name)
+         , ProtoBridgeOneFieldValue sch k
+         , ProtoBridgeOneFieldValue sch v
+         , Ord (FieldValue sch k) )
          => ProtoBridgeField sch ty ('FieldDef name ('TMap k v)) where
-  fieldToProto = error "maps are not currently supported"
-  protoToField = error "maps are not currently supported"
+  fieldToProto (Field (FMap mp))
+    = foldMap oneMapValueToProto (M.toAscList mp)
+    where fieldId = fromInteger $ natVal (Proxy @(FindProtoBufId sch ty name))
+          oneMapValueToProto (k, v)
+            = PBEnc.embedded fieldId $
+                oneFieldValueToProto 1 k <> oneFieldValueToProto 2 v
+  protoToField = Field . FMap . M.fromList <$> go
+    where fieldId = fromInteger $ natVal (Proxy @(FindProtoBufId sch ty name))
+          go = PBDec.repeated (
+                 PBDec.embedded'
+                   ((,) <$> fieldValueWithDefault 1
+                        <*> fieldValueWithDefault 2))
+                 `at` fieldId
+          fieldValueWithDefault innerFieldId
+            = case defaultOneFieldValue of
+                Nothing
+                  -> do r <- PBDec.one (Just <$> protoToOneFieldValue) Nothing `at` innerFieldId
+                        maybe empty pure r
+                Just d
+                  -> PBDec.one protoToOneFieldValue d `at` innerFieldId <|> pure d
 
 instance {-# OVERLAPS #-}
          (ProtoBridgeUnionFieldValue (FindProtoBufOneOfIds sch ty name) sch ts)
@@ -518,14 +552,14 @@
   packedFieldValueToProto = error "lists cannot be nested in protobuf"
   protoToPackedFieldValue = error "lists cannot be nested in protobuf"
 
-instance TypeError ('Text "maps are not currently supported")
+instance TypeError ('Text "maps cannot be nested in protobuf")
          => ProtoBridgeOneFieldValue sch ('TMap k v) where
-  defaultOneFieldValue = error "maps are not currently supported"
-  oneFieldValueToProto = error "maps are not currently supported"
-  protoToOneFieldValue = error "maps are not currently supported"
-  supportsPacking      = error "maps are not currently supported"
-  packedFieldValueToProto = error "maps are not currently supported"
-  protoToPackedFieldValue = error "maps are not currently supported"
+  defaultOneFieldValue = error "maps cannot be nested in protobuf"
+  oneFieldValueToProto = error "maps cannot be nested in protobuf"
+  protoToOneFieldValue = error "maps cannot be nested in protobuf"
+  supportsPacking      = error "maps cannot be nested in protobuf"
+  packedFieldValueToProto = error "maps cannot be nested in protobuf"
+  protoToPackedFieldValue = error "maps cannot be nested in protobuf"
 
 instance TypeError ('Text "nested unions are not currently supported")
          => ProtoBridgeOneFieldValue sch ('TUnion choices) where
diff --git a/test/ProtoBuf.hs b/test/ProtoBuf.hs
--- a/test/ProtoBuf.hs
+++ b/test/ProtoBuf.hs
@@ -10,6 +10,7 @@
 
 import qualified Data.ByteString      as BS
 import qualified Data.ByteString.Lazy as LBS
+import qualified Data.Map             as M
 import qualified Data.Text            as T
 import           GHC.Generics
 import qualified Proto3.Wire.Decode   as PBDec
@@ -26,7 +27,8 @@
             , age           :: Maybe Int
             , gender        :: Maybe Gender
             , address       :: MAddress
-            , lucky_numbers :: [Int] }
+            , lucky_numbers :: [Int]
+            , things        :: M.Map T.Text Int }
   deriving (Eq, Show, Generic)
   deriving (ToSchema ExampleSchema "person")
   deriving (FromSchema ExampleSchema "person")
@@ -60,7 +62,8 @@
      , 'AnnField "person" "age"       ('ProtoBufId 3 '[])
      , 'AnnField "person" "gender"    ('ProtoBufId 4 '[])
      , 'AnnField "person" "address"   ('ProtoBufId 5 '[])
-     , 'AnnField "person" "lucky_numbers" ('ProtoBufId 6 '[ '("packed", 'ProtoBufOptionConstantBool 'True) ]) ]
+     , 'AnnField "person" "lucky_numbers" ('ProtoBufId 6 '[ '("packed", 'ProtoBufOptionConstantBool 'True) ])
+     , 'AnnField "person" "things"    ('ProtoBufId 7 '[]) ]
 
 exampleAddress :: MAddress
 exampleAddress = MAddress "1111BB" "Spain"
@@ -69,9 +72,10 @@
 examplePerson1 = MPerson "Haskellio" "Gómez"
                          (Just 30) (Just Male)
                          exampleAddress [1,2,3]
+                         (M.fromList [("pepe", 1), ("juan", 2)])
 examplePerson2 = MPerson "Cuarenta" "Siete"
                          Nothing Nothing
-                         exampleAddress []
+                         exampleAddress [] M.empty
 
 main :: IO ()
 main = do -- Obtain the filenames
diff --git a/test/protobuf/example.proto b/test/protobuf/example.proto
--- a/test/protobuf/example.proto
+++ b/test/protobuf/example.proto
@@ -7,6 +7,7 @@
   gender gender = 4;
   address address = 5;
   repeated int32 lucky_numbers = 6 [packed=true];
+  map<string, int32> things = 7;
 }
 
 message address {
