diff --git a/src/sequence_io/pulseq_io/components.jl b/src/sequence_io/pulseq_io/components.jl
index cd5b38b750af18bffb5b1dc82b926ea80e5c197a..fd189e2d95ee60e73fb621d3a4bdd2655c3a32e5 100644
--- a/src/sequence_io/pulseq_io/components.jl
+++ b/src/sequence_io/pulseq_io/components.jl
@@ -15,13 +15,13 @@ struct PulseqComponents
     pulses:: Dict{Int, PulseqRFPulse}
     grads:: Dict{Int, AnyPulseqGradient}
     adc:: Dict{Int, PulseqADC}
-    extensions:: Dict{Int, PulseqExtension}
+    extensions:: Dict{Int, Any}
     PulseqComponents(shapes, pulses, grads, adc, extensions) = new(
         _convert_to_dict(shapes, PulseqShape),
         _convert_to_dict(pulses, PulseqRFPulse),
         _convert_to_dict(grads, AnyPulseqGradient),
         _convert_to_dict(adc, PulseqADC),
-        _convert_to_dict(extensions, PulseqExtension),
+        _convert_to_dict(extensions, Any),
     )
 end
 
diff --git a/src/sequence_io/pulseq_io/extensions.jl b/src/sequence_io/pulseq_io/extensions.jl
new file mode 100644
index 0000000000000000000000000000000000000000..2984c877da57c2f48f6c287826f36f109087b48a
--- /dev/null
+++ b/src/sequence_io/pulseq_io/extensions.jl
@@ -0,0 +1,55 @@
+"""
+Defines the Pulseq IO extension interface with default implementations
+"""
+module Extensions
+import ..Types: PulseqExtension, PulseqExtensionDefinition
+
+struct UnknownExtensionMapper
+    ext::PulseqExtensionDefinition
+end
+
+Base.getindex(mapper::UnknownExtensionMapper, i::Int) = PulseqExtension(mapper.ext, i)
+
+"""
+    parse_extension(ext::PulseqExtensionDefinition{name})
+
+Parse a Pulseq extension definition into a dictionary-like object
+that maps integer reference IDs to any object describing the extension.
+
+This can be overriden to support the reading of a specific extension type.
+For example, to define a parser for an extension with the name "LABELSET":
+```
+function PulseqIO.parse_extension(ext::PulseqExtensionDefinition{:LABELSET})
+    ...
+end
+```
+"""
+function parse_extension(ext::PulseqExtensionDefinition{N}) where {N}
+    @warn "Parsing unknown extension: {N}"
+    return UnknownExtensionMapper(ext)
+end
+
+
+"""
+    get_extension_name(obj)
+
+Get the name under which the given `obj` should be stored in a Pulseq extension.
+
+To write an object to a Pulseq file extension, 
+one needs to define both this function and [`add_extension_definition`](@ref).
+"""
+get_extension_name(ext::PulseqExtension{N}) where {N} = N
+
+"""
+    add_extension_definition!(content::Vector{String}, obj)
+
+Add the object to the extension definition and returns the reference index.
+
+The extension definition is passed on as a vector of strings.
+This vector can be appended to, when adding a new object.
+
+If the object is already in the `definition` the reference index of the already existing object should be returned instead.
+"""
+add_extension_definition!(content::Vector{String}, ext::PulseqExtension) = ext.index
+
+end
\ No newline at end of file
diff --git a/src/sequence_io/pulseq_io/parsers/extensions.jl b/src/sequence_io/pulseq_io/parsers/extensions.jl
index e75298c096e09f624f27efa03b59e417f2d8d9b1..fac6d32595def5f32e8b0e38b8f3f14624666b40 100644
--- a/src/sequence_io/pulseq_io/parsers/extensions.jl
+++ b/src/sequence_io/pulseq_io/parsers/extensions.jl
@@ -1,14 +1,16 @@
+import ..Extensions: parse_extension, get_extension_name, add_extension_definition!
+
 function parse_section(section::PulseqSection{:extensions}; kwargs...)
     current_extension = -1
     pre_amble = true
     linked_list = Dict{Int, NTuple{3, Int}}()
-    extensions = Dict{Int, PulseqExtension}()
+    extensions = Dict{Int, PulseqExtensionDefinition}()
     for line in section.content
         if startswith(line, "extension ")
             pre_amble = false
             (_, name, str_id) = split(line)
             current_extension = int(str_id)
-            extensions[current_extension] = PulseqExtension(name, String[])
+            extensions[current_extension] = PulseqExtensionDefinition{name}(String[])
         elseif pre_ample
             (id, type, ref, next) = int.(split(line))
             linked_list[id] = (type=type, ref=ref, next=next)
@@ -17,15 +19,69 @@ function parse_section(section::PulseqSection{:extensions}; kwargs...)
         end
     end
 
+    extension_mappers = Dict(key => parse_extension(ext) for (key, ext) in extensions)
+
     function get_extension_list(key::Int)
         if iszero(key)
             return Tuple{PulseqExtension, Int}[]
         else
             base = get_extension_list(linked_list[key].next)
-            pushfirst!(base, (extensions[linked_list[key].type], linked_list[key].ref))
+            pushfirst!(base, extension_mappers[linked_list[key].type][linked_list[key].ref])
             return base
         end
     end
 
     return Dict(key => get_extension_list(key) for key in keys(linked_list))
+end
+
+function gen_section(comp:: PulseqComponents, ::Val{:extensions})
+    definitions = Dict{Symbol, PulseqExtensionDefinition}()
+    extensions_ref_id = Dict{Any, Int}()
+    for ext_vec in comp.extensions
+        for ext in ext_vec
+            name = get_extension_name(ext)
+            if !(name in keys(definitions))
+                definitions[name] = PulseqExtensionDefinition{name}(String[])
+            end
+            extensions_ref_id[ext] = add_extension_definition!(definitions[name].content, ext)
+        end
+    end
+
+    definitions_order = [keys(definitions)...]
+
+    extension_vec_id = Dict{Vector, Int}()
+
+    labels = Tuple{Int, Int, Int}[]
+    function add_extension_vec!(ext_vec::Vector)
+        if length(ext_vec) == 0
+            return 0
+        end
+        next_id = add_extension_vec!(ext_vec[2:end])
+        ext = ext_vec[1]
+        type_id = findfirst(get_extension_name(ext), definitions_order)
+        ref_id = extensions_ref_id[ext]
+        all_ids = (type_id, ref_id, next_id)
+        if all_ids in labels
+            extension_vec_id[ext_vec] = findfirst(lables, all_ids)
+        else
+            push!(labels, all_ids)
+            extension_vec_id[ext_vec] = length(lables)
+        end
+    end
+    add_extension_definition!.(values(comp.extensions))
+
+    content = String[]
+    for (id0, (id1, id2, id3)) in enumerate(labels)
+        push!(content, "$id0 $id1 $id2 $id3")
+    end
+    push!(content, "")
+
+    for (index, name) in enumerate(definitions_order)
+        def = definitions[name]
+        push!(content, "extension $(string(name)) $(string(index))")
+        append!(content, def.content)
+        push!(content, "")
+    end
+
+    return PulseqSection{:extensions}(content)
 end
\ No newline at end of file
diff --git a/src/sequence_io/pulseq_io/pulseq_io.jl b/src/sequence_io/pulseq_io/pulseq_io.jl
index 278e20775d3f9439eb7fe5ac9e4ad1d7ab2e2224..e2170991e9b5d1627aa7733dcfc1ccb8f0a12e9f 100644
--- a/src/sequence_io/pulseq_io/pulseq_io.jl
+++ b/src/sequence_io/pulseq_io/pulseq_io.jl
@@ -6,6 +6,7 @@ The translation of these types into MRIBuilder types is defined in "../pulseq.jl
 """
 module PulseqIO
 include("types.jl")
+include("extensions.jl")
 include("basic_parsers.jl")
 include("sections_io.jl")
 include("components.jl")
@@ -13,6 +14,7 @@ include("parsers/parsers.jl")
 include("parse_sections.jl")
 
 import .Types: PulseqSequence
+import .Extensions: parse_extension, get_extension_name, add_extension_definition!
 
 
 """
diff --git a/src/sequence_io/pulseq_io/types.jl b/src/sequence_io/pulseq_io/types.jl
index 3aa40897171687fde9ed213eed36e51a161d7fca..d093917b74f544fd98ed3317c4ce9bc568b1bc83 100644
--- a/src/sequence_io/pulseq_io/types.jl
+++ b/src/sequence_io/pulseq_io/types.jl
@@ -94,18 +94,17 @@ end
 
 Abstract definition of an unknown Pulseq extension.
 """
-struct PulseqExtensionDefinition
-    name :: String
+struct PulseqExtensionDefinition{N}
     content :: Vector{String}
 end
 
 """
     PulseqExtension(definition::PulseqExtensionDefinition, id::Int)
 
-Reference to a specific implementation of the [`PulseqExtensionDefinition`](@ref).
+Reference to a specific implementation of a [`PulseqExtensionDefinition`](@ref).
 """
-struct PulseqExtension <: AnyPulseqComponent
-    definition::PulseqExtensionDefinition
+struct PulseqExtension{N} <: AnyPulseqComponent
+    definition::PulseqExtensionDefinition{N}
     id :: Int
 end