diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,11 @@
 # Changelog for spirv-reflect-yaml
 
+## [0.3] - 2024-07-07
+
+* Update types and parser to `vulkan-sdk-1.3.283.0`.
+
+[0.3]: https://gitlab.com/dpwiz/spirv-reflect/-/tree/v0.3-yaml
+
 ## [0.2] - 2022-09-04
 
 * Update loader to match FFI types.
diff --git a/lib/Data/SpirV/Reflect/Yaml/Parsers.hs b/lib/Data/SpirV/Reflect/Yaml/Parsers.hs
--- a/lib/Data/SpirV/Reflect/Yaml/Parsers.hs
+++ b/lib/Data/SpirV/Reflect/Yaml/Parsers.hs
@@ -2,7 +2,10 @@
 
 import Prelude hiding (id)
 
+import Control.Applicative ((<|>))
 import Data.Functor ((<&>))
+import Data.Maybe (catMaybes)
+import Data.SpirV.Enum qualified as SpirV
 import Data.Text (Text)
 import Data.Vector (Vector)
 import Data.Vector qualified as Vector
@@ -16,11 +19,13 @@
 import Data.SpirV.Reflect.DescriptorBinding qualified as DescriptorBinding
 import Data.SpirV.Reflect.DescriptorSet (DescriptorSet)
 import Data.SpirV.Reflect.DescriptorSet qualified as DescriptorSet
-import Data.SpirV.Reflect.Enums qualified as Enums
+import Data.SpirV.Reflect.Enums qualified as Reflect
 import Data.SpirV.Reflect.InterfaceVariable (InterfaceVariable)
 import Data.SpirV.Reflect.InterfaceVariable qualified as InterfaceVariable
 import Data.SpirV.Reflect.Module (Module)
 import Data.SpirV.Reflect.Module qualified as Module
+import Data.SpirV.Reflect.SpecializationConstant (SpecializationConstant)
+import Data.SpirV.Reflect.SpecializationConstant qualified as SpecializationConstant
 import Data.SpirV.Reflect.Traits qualified as Traits
 import Data.SpirV.Reflect.TypeDescription (TypeDescription)
 import Data.SpirV.Reflect.TypeDescription qualified as TypeDescription
@@ -32,7 +37,7 @@
 
 moduleP :: NodeParser Module
 moduleP = YAML.withMap "Module" \m -> do
-  generator               <- m .: "generator" <&> Enums.Generator
+  generator               <- m .: "generator" <&> Reflect.Generator
   entry_point_name        <- m .: "entry_point_name"
   entry_point_id          <- m .: "entry_point_id"
   source_language         <- m .: "source_language"
@@ -44,29 +49,35 @@
   input_variables         <- m .? "input_variables" `seqOf` interfaceVariableP
   output_variables        <- m .? "output_variables" `seqOf` interfaceVariableP
   push_constants          <- m .? "push_constants" `seqOf` blockVariableP
+  spec_constants          <- m .? "spec_constants" `seqOf` specializationConstantP
   pure Module.Module{..}
 
 descriptorBindingP :: NodeParser DescriptorBinding
 descriptorBindingP = YAML.withMap "DescriptorBinding" \m -> do
-  spirv_id               <- m .? "spirv_id"
-  name                   <- m .: "name"
-  binding                <- m .: "binding"
-  input_attachment_index <- m .: "input_attachment_index"
-  set                    <- m .: "set"
-  descriptor_type        <- m .: "descriptor_type" <&> Enums.DescriptorType
-  resource_type          <- m .: "resource_type" <&> Enums.ResourceFlagBits
-  image                  <- m .: "image" >>= traitsImageP
-  block                  <- m .? "block" >>= traverse blockVariableP
-  array                  <- m .: "array" >>= traitsArrayP
-  count                  <- m .? "count"
-  accessed               <- m .: "accessed"
-  uav_counter_id         <- m .: "uav_counter_id"
-  uav_counter_binding    <- m .? "uav_counter_binding" >>= traverse descriptorBindingP
-  type_description       <- m .? "type_description" >>= traverse typeDescriptionP
-  word_offset            <- m .: "word_offset" >>= descriptorBindingWordOffsetP
-  decoration_flags       <- m .? "decoration_flags" <&> maybe Enums.DECORATION_NONE Enums.DecorationFlagBits
+  spirv_id                    <- m .? "spirv_id"
+  name                        <- m .| "name"
+  binding                     <- m .: "binding"
+  input_attachment_index      <- m .: "input_attachment_index"
+  set                         <- m .: "set"
+  descriptor_type             <- m .: "descriptor_type" <&> Reflect.DescriptorType
+  resource_type               <- m .: "resource_type" <&> Reflect.ResourceFlagBits
+  image                       <- m .: "image" >>= traitsImageP
+  block                       <- m .? "block" >>= traverse blockVariableP
+  array                       <- m .: "array" >>= traitsArrayP
+  count                       <- m .? "count"
+  accessed                    <- m .: "accessed"
+  uav_counter_id              <- m .: "uav_counter_id"
+  uav_counter_binding         <- m .? "uav_counter_binding" >>= traverse descriptorBindingP
+  byte_address_buffer_offsets <- m .? "byte_address_buffer_offsets" `seqOf` YAML.withInt "byte_address_buffer_offset" (pure . fromInteger)
+  type_description            <- m .? "type_description" >>= traverse typeDescriptionP
+  word_offset                 <- m .: "word_offset" >>= descriptorBindingWordOffsetP
+  decoration_flags            <- m .? "decoration_flags" <&> maybe Reflect.DECORATION_NONE Reflect.DecorationFlagBits
+  user_type                   <- m .? "user_type" >>= traverse userTypeP
   pure DescriptorBinding.DescriptorBinding{..}
 
+userTypeP :: NodeParser Reflect.UserType
+userTypeP = YAML.withStr "UserType" $ maybe (fail "Unknown UserType") pure . Reflect.userTypeId
+
 descriptorBindingWordOffsetP :: NodeParser DescriptorBinding.WordOffset
 descriptorBindingWordOffsetP = YAML.withMap "DescriptorBinding.WordOffset" \m -> do
   binding <- m .: "binding"
@@ -75,14 +86,16 @@
 
 typeDescriptionP :: NodeParser TypeDescription
 typeDescriptionP = YAML.withMap "TypeDescription" \m -> do
-  id                 <- m .? "id"
-  op                 <- m .? "op" <&> fmap Enums.Op
-  type_name          <- m .? "type_name"
-  struct_member_name <- m .? "struct_member_name"
-  storage_class      <- m .: "storage_class" <&> Enums.StorageClass
-  type_flags         <- m .? "type_flags" <&> maybe Enums.TYPE_FLAG_UNDEFINED Enums.TypeFlagBits
-  traits             <- m .: "traits" >>= traverse typeDescriptionTraitsP
-  members            <- m .? "members" `seqOf` typeDescriptionP
+  id                      <- m .? "id"
+  op                      <- m .? "op" <&> fmap SpirV.Op
+  type_name               <- m .? "type_name"
+  struct_member_name      <- m .? "struct_member_name"
+  storage_class           <- m .: "storage_class" <&> SpirV.StorageClass
+  type_flags              <- m .? "type_flags" <&> maybe Reflect.TYPE_FLAG_UNDEFINED Reflect.TypeFlagBits
+  traits                  <- m .: "traits" >>= traverse typeDescriptionTraitsP <&> \ts -> if ts == Just TypeDescription.emptyTraits then Nothing else ts
+  copied                  <- m .? "copied" -- BUG: YAML has no "copied" field
+  members                 <- m .? "members" `seqOfMaybes` alt forwardPointerP (fmap Just . typeDescriptionP) -- BUG: YAML uses `[forward pointer]` marker for recursive structures.
+  struct_type_description <- m .? "struct_type_description" >>= traverse typeDescriptionP
   pure TypeDescription.TypeDescription{..}
 
 typeDescriptionTraitsP :: NodeParser TypeDescription.Traits
@@ -103,14 +116,20 @@
   spirv_id         <- m .? "spirv_id"
   name             <- m .? "name"
   location         <- m .: "location"
-  storage_class    <- m .: "storage_class" <&> Enums.StorageClass
+  component        <- m .? "component"
+  storage_class    <- m .: "storage_class" <&> SpirV.StorageClass
   semantic         <- m .: "semantic"
-  decoration_flags <- m .: "decoration_flags" <&> Enums.DecorationFlagBits
-  built_in         <- m .: "built_in" <&> Enums.BuiltIn
+  decoration_flags <- m .: "decoration_flags" <&> Reflect.DecorationFlagBits
   numeric          <- m .: "numeric" >>= traitsNumericP
   array            <- m .: "array" >>= traitsArrayP
-  members          <- m .? "members" `seqOf` interfaceVariableP
-  format           <- m .: "format" <&> Enums.Format
+  members          <- m .? "members" `seqOfMaybes` alt (fmap Just . interfaceVariableP) recursiveP
+  built_in <-
+    -- BUG: https://github.com/KhronosGroup/SPIRV-Reflect/issues/269
+    if null members then
+      m .? "built_in" <&> fmap SpirV.BuiltIn
+    else
+      pure Nothing
+  format           <- m .: "format" <&> Reflect.Format
   type_description <- m .? "type_description" >>= traverse typeDescriptionP
   word_offset      <- m .: "word_offset" >>= interfaceVariableWordOffsetP
   pure InterfaceVariable.InterfaceVariable{..}
@@ -128,13 +147,26 @@
   absolute_offset  <- m .: "absolute_offset"
   size             <- m .: "size"
   padded_size      <- m .: "padded_size"
-  decorations      <- m .: "decorations" <&> Enums.DecorationFlagBits
+  decorations      <- m .: "decorations" <&> Reflect.DecorationFlagBits
   numeric          <- m .: "numeric" >>= traitsNumericP
   array            <- m .: "array" >>= traitsArrayP
-  members          <- m .? "members" `seqOf` blockVariableP
+  members          <- m .? "members" `seqOfMaybes` alt recursiveP (fmap Just . blockVariableP)
   type_description <- m .? "type_description" >>= traverse typeDescriptionP
+  word_offset      <- m .? "word_offset" >>= traverse blockVariableWordOffsetP
   pure BlockVariable.BlockVariable{..}
 
+blockVariableWordOffsetP :: NodeParser BlockVariable.WordOffset
+blockVariableWordOffsetP = YAML.withMap "BlockVariable.WordOffset" \m -> do
+  offset <- m .: "offset"
+  pure BlockVariable.WordOffset{..}
+
+specializationConstantP :: NodeParser SpecializationConstant
+specializationConstantP = YAML.withMap "SpecializationConstant" \m -> do
+  spirv_id    <- m .? "spirv_id"
+  constant_id <- m .: "constant_id"
+  name        <- m .? "name"
+  pure SpecializationConstant.SpecializationConstant{..}
+
 --------------
 
 traitsNumericP :: NodeParser Traits.Numeric
@@ -146,8 +178,8 @@
 
 traitsScalarP :: NodeParser Traits.Scalar
 traitsScalarP = YAML.withMap "Scalar" \m -> do
-  width      <- m .: "width"
-  signedness <- m .: "signedness"
+  width  <- m .: "width"
+  signed <- m .: "signedness" <&> (/= (0 :: Word))
   pure Traits.Scalar{..}
 
 traitsVectorP :: NodeParser Traits.Vector
@@ -166,23 +198,36 @@
 traitsArrayP = YAML.withMap "Array" \m -> do
   dims_count <- m .: "dims_count"
   dims       <- m .: "dims" <&> Storable.fromList
-  stride     <- m .? "stride"
+  stride     <- m .? "stride" <&> \stride -> if stride == Just 0 then Nothing else stride
   pure Traits.Array{..}
 
 traitsImageP :: NodeParser Traits.Image
 traitsImageP = YAML.withMap "Image" \m -> do
-  dim          <- m .: "dim" <&> Enums.Dim
+  dim          <- m .: "dim" <&> SpirV.Dim
   depth        <- m .: "depth"
   arrayed      <- m .: "arrayed"
   ms           <- m .: "ms"
   sampled      <- m .: "sampled"
-  image_format <- m .: "image_format" <&> Enums.ImageFormat
+  image_format <- m .: "image_format" <&> SpirV.ImageFormat
   pure Traits.Image{..}
 
+recursiveP :: NodeParser (Maybe a)
+recursiveP = \case
+  YAML.Sequence _pos _tag [YAML.Scalar _pos2 (YAML.SStr "recursive")] -> pure Nothing
+  _ -> fail "Unexpected token"
+
+forwardPointerP :: NodeParser (Maybe a)
+forwardPointerP = \case
+  YAML.Sequence _pos _tag [YAML.Scalar _pos2 (YAML.SStr "forward pointer")] -> pure Nothing
+  _ -> fail "Unexpected token"
+
 type NodeParser a =
   YAML.Node YAML.Pos ->
   YAML.Parser a
 
+alt :: NodeParser a -> NodeParser a -> NodeParser a
+alt a b n = a n <|> b n
+
 (.?)
   :: YAML.FromYAML a
   => YAML.Mapping YAML.Pos
@@ -190,6 +235,13 @@
   -> YAML.Parser (Maybe a)
 o .? v = o YAML..:? v
 
+(.|)
+  :: (YAML.FromYAML a, Monoid a)
+  => YAML.Mapping YAML.Pos
+  -> Text
+  -> YAML.Parser a
+o .| v = o YAML..:? v YAML..!= mempty
+
 seqOf
   :: YAML.Parser (Maybe (YAML.Node YAML.Pos))
   -> NodeParser a
@@ -199,4 +251,15 @@
     Nothing ->
       pure mempty
     Just items ->
-      YAML.withSeq "seqOf" (traverse nodeP . Vector.fromList) items
+      YAML.withSeq "seqOf" (fmap Vector.fromList . traverse nodeP) items
+
+seqOfMaybes
+  :: YAML.Parser (Maybe (YAML.Node YAML.Pos))
+  -> NodeParser (Maybe a)
+  -> YAML.Parser (Vector a)
+seqOfMaybes mappingP nodeP =
+  mappingP >>= \case
+    Nothing ->
+      pure mempty
+    Just items ->
+      YAML.withSeq "seqOf" (fmap (Vector.fromList . catMaybes) . traverse nodeP) items
diff --git a/spirv-reflect-yaml.cabal b/spirv-reflect-yaml.cabal
--- a/spirv-reflect-yaml.cabal
+++ b/spirv-reflect-yaml.cabal
@@ -1,11 +1,11 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.34.4.
+-- This file has been generated from package.yaml by hpack version 0.36.0.
 --
 -- see: https://github.com/sol/hpack
 
 name:           spirv-reflect-yaml
-version:        0.2
+version:        0.3
 synopsis:       YAML loader for spirv-reflect tool.
 category:       Graphics
 author:         IC Rainbow
@@ -52,7 +52,8 @@
       HsYAML
     , base >=4.7 && <5
     , bytestring
-    , spirv-reflect-types >=0.2
+    , spirv-enum ==0.1.*
+    , spirv-reflect-types ==0.3.*
     , text
     , vector
   default-language: Haskell2010
@@ -86,6 +87,6 @@
     , spirv-reflect-yaml
     , tasty
     , tasty-hunit
+  default-language: Haskell2010
   if !flag(tests)
     buildable: False
-  default-language: Haskell2010
