diff --git a/src/artist.coffee b/src/artist.coffee
index 942c446..61698e8 100644
--- a/src/artist.coffee
+++ b/src/artist.coffee
@@ -68,6 +68,8 @@ class Artist
     @current_octave_shift = 0
     @bend_start_index = null
     @bend_start_strings = null
+    @in_beam = false
+    @beam_notes = []
     @rendered = false
     @renderer_context = null
 
@@ -340,7 +342,11 @@ class Artist
       stave_note.addDotToAll()
 
     stave_note.setPlayNote(params.play_note) if params.play_note?
-    stave_notes.push stave_note
+    stave_note.beamset = @beamset  # adapted from https://github.com/0xfe/vextab/pull/124#issuecomment-833214140
+    if @in_beam
+      @beam_notes.push stave_note
+    else
+      stave_notes.push stave_note
 
   addTabNote: (spec, play_note=null) ->
     tab_notes = _.last(@staves).tab_notes
@@ -388,6 +394,31 @@ class Artist
     stave.tab_notes.push(bar_note)
     stave.note_notes.push(bar_note) if stave.note?
 
+  # adapted from https://github.com/0xfe/vextab/pull/124#issuecomment-833214140
+  setBeam: (action) ->
+    @beamset = action
+
+  openBeam: (type) ->
+    L "openBeam: ", type
+    if @in_beam
+      throw new Vex.RERR("ArtistError", "Already in beam")
+    @in_beam = true
+    @beam_notes = []
+
+  closeBeam: (type) ->
+    L "closeBeam: ", type
+    if not @in_beam
+      throw new Vex.RERR("ArtistError", "Not in beam")
+    b = new Vex.Flow.Beam(@beam_notes, true)
+    for n in @beam_notes
+      n.setBeam(b)
+      # _.last(@staves).note_notes.push b  # doesn't work
+      _.last(@staves).note_notes.push n
+
+    # @stave_articulations.push b
+    @in_beam = false
+    @beam_notes = []
+
   makeBend = (from_fret, to_fret) ->
     direction = Vex.Flow.Bend.UP
     text = ""
diff --git a/src/vextab.coffee b/src/vextab.coffee
index 8ab25c6..3fe6ec7 100644
--- a/src/vextab.coffee
+++ b/src/vextab.coffee
@@ -73,20 +73,23 @@ class VexTab
     return params
 
   parseCommand: (element) ->
-    if element.command is "bar"
-      @artist.addBar(element.type)
-
-    if element.command is "tuplet"
-      @artist.makeTuplets(element.params.tuplet, element.params.notes)
-
-    if element.command is "annotations"
-      @artist.addAnnotations(element.params)
-
-    if element.command is "rest"
-      @artist.addRest(element.params)
-
-    if element.command is "command"
-      @artist.runCommand(element.params, element._l, element._c)
+    switch element.command
+      when "bar"
+        @artist.addBar(element.type)
+      when "tuplet"
+        @artist.makeTuplets(element.params.tuplet, element.params.notes)
+      when "annotations"
+        @artist.addAnnotations(element.params)
+      when "rest"
+        @artist.addRest(element.params)
+      when "command"
+        @artist.runCommand(element.params, element._l, element._c)
+      when "open_beam"
+        @artist.openBeam(element.params)
+      when "close_beam"
+        @artist.closeBeam(element.params)
+      else
+        throw newError(element.command, "Invalid command '#{element.command}'")
 
   parseChord: (element) ->
     L "parseChord:", element
@@ -110,6 +113,13 @@ class VexTab
         @artist.setDuration(element.time, element.dot)
 
       if element.command
+        # Code here adapted from https://github.com/0xfe/vextab/pull/124#issuecomment-833214140
+        # open_beam and close_beam are not really command but state
+        # set beam state (this state would be saved in stavenote array)
+        if (element.command == "open_beam")
+          @artist.setBeam("open")
+        if (element.command == "close_beam")
+          @artist.setBeam("close")
         @parseCommand(element)
 
       if element.chord
diff --git a/tests/tests.coffee b/tests/tests.coffee
index b064313..e3289a4 100644
--- a/tests/tests.coffee
+++ b/tests/tests.coffee
@@ -53,6 +53,7 @@ class VexTabTests
     test "Rests in Tab", @restsInTab
     test "Multi String Tab", @multiStringTab
     test "Time Signature based Beaming", @timeSigBeaming
+    test "User Beaming", @beaming
     test "Override Fret-Note", @overrideFretNote
     test "Mixed Tuplets", @mixedTuplets
     test "Accidental Strategies", @accidentalStrategies
@@ -595,6 +596,21 @@ class VexTabTests
     """
     renderTest assert, "Time Signature based Beaming", code
 
+  @beaming: (assert) ->
+    code = """
+    tabstave notation=true tablature=true time=4/4
+    notes :32 [ 2/3 5/2 ] :q 5/1
+    """
+    renderTest assert, "User Beaming", code
+
+    # adapted from https://github.com/0xfe/vextab/pull/124#issuecomment-833214140
+    code = """
+tabstave notation=true tablature=false clef=treble time=4/4
+ notes  =|: :8 F/4  :q F/4   :8 F/4 [ tF/4  E/4 ] :q D/4
+ notes  | :qd D/4     :8 F/4 [ F/4  A/4 G/4  F/4 ]
+    """
+    renderTest assert, "User Beaming 2", code
+
   @multiStringTab: (assert) ->
     code = """
     tabstave key=A strings=4