diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 18788bedb5..ddafa73aef 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -245,4 +245,8 @@ module ApplicationHelper
   def prerender_custom_emojis(html, custom_emojis, other_options = {})
     EmojiFormatter.new(html, custom_emojis, other_options.merge(animate: prefers_autoplay?)).to_s
   end
+
+  def prerender_custom_emojis_from_hash(html, custom_emojis_hash)
+    prerender_custom_emojis(html, JSON.parse([custom_emojis_hash].to_json, object_class: OpenStruct))
+  end
 end
diff --git a/app/helpers/formatting_helper.rb b/app/helpers/formatting_helper.rb
index d390b9bc96..b99c82969c 100644
--- a/app/helpers/formatting_helper.rb
+++ b/app/helpers/formatting_helper.rb
@@ -18,6 +18,10 @@ module FormattingHelper
     html_aware_format(status.text, status.local?, preloaded_accounts: [status.account] + (status.respond_to?(:active_mentions) ? status.active_mentions.map(&:account) : []))
   end
 
+  def emoji_name_format(emoji_reaction, status)
+    html_aware_format(emoji_reaction['url'].present? ? ":#{emoji_reaction['name']}:" : emoji_reaction['name'], status.local?)
+  end
+
   def rss_status_content_format(status)
     html = status_content_format(status)
 
@@ -45,7 +49,7 @@ module FormattingHelper
     prerender_custom_emojis(
       safe_join([before_html, html, after_html]),
       status.emojis,
-      style: 'width: 1.1em; height: 1.1em; object-fit: contain; vertical-align: middle; margin: -.2ex .15em .2ex'
+      style: 'min-width: 1.1em; height: 1.1em; object-fit: contain; vertical-align: middle; margin: -.2ex .15em .2ex'
     ).to_str
   end
 
diff --git a/app/javascript/mastodon/features/compose/components/poll_form.jsx b/app/javascript/mastodon/features/compose/components/poll_form.jsx
index c5a8f8ca7f..5c04aa2937 100644
--- a/app/javascript/mastodon/features/compose/components/poll_form.jsx
+++ b/app/javascript/mastodon/features/compose/components/poll_form.jsx
@@ -160,7 +160,7 @@ class PollForm extends ImmutablePureComponent {
         </ul>
 
         <div className='poll__footer'>
-          <button type='button' disabled={options.size >= 4} className='button button-secondary' onClick={this.handleAddOption}><Icon id='plus' /> <FormattedMessage {...messages.add_option} /></button>
+          <button type='button' disabled={options.size >= 8} className='button button-secondary' onClick={this.handleAddOption}><Icon id='plus' /> <FormattedMessage {...messages.add_option} /></button>
 
           {/* eslint-disable-next-line jsx-a11y/no-onchange */}
           <select value={expiresIn} onChange={this.handleSelectDuration}>
diff --git a/app/lib/emoji_formatter.rb b/app/lib/emoji_formatter.rb
index a9785d5f90..ed42fcb636 100644
--- a/app/lib/emoji_formatter.rb
+++ b/app/lib/emoji_formatter.rb
@@ -62,7 +62,12 @@ class EmojiFormatter
   private
 
   def emoji_map
-    @emoji_map ||= custom_emojis.each_with_object({}) { |e, h| h[e.shortcode] = [full_asset_url(e.image.url), full_asset_url(e.image.url(:static))] }
+    # from emoji_reactions_grouped_by_name (status_stat)
+    if !custom_emojis.first&.image.present?
+      return @emoji_map ||= custom_emojis.each_with_object({}) { |e, h| h[e.name] = [e.url, e.static_url] }
+    end
+
+    return @emoji_map ||= custom_emojis.each_with_object({}) { |e, h| h[e.shortcode] = [full_asset_url(e.image.url), full_asset_url(e.image.url(:static))] }
   end
 
   def count_tag_nesting(tag)
@@ -85,7 +90,7 @@ class EmojiFormatter
   end
 
   def image_attributes
-    { rel: 'emoji', draggable: false, width: 16, height: 16, class: image_class_names, style: image_style }
+    { rel: 'emoji', draggable: false, height: 16, class: image_class_names, style: image_style }
   end
 
   def image_data_attributes(original_url, static_url)
@@ -97,7 +102,7 @@ class EmojiFormatter
   end
 
   def image_style
-    @options[:style]
+    'min-width:16px;' + (@options[:style] || '')
   end
 
   def animate?
diff --git a/app/validators/poll_validator.rb b/app/validators/poll_validator.rb
index a327277963..bd913188f3 100644
--- a/app/validators/poll_validator.rb
+++ b/app/validators/poll_validator.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 class PollValidator < ActiveModel::Validator
-  MAX_OPTIONS      = 4
+  MAX_OPTIONS      = 8
   MAX_OPTION_CHARS = 50
   MAX_EXPIRATION   = 1.month.freeze
   MIN_EXPIRATION   = 5.minutes.freeze
diff --git a/app/views/statuses/_detailed_status.html.haml b/app/views/statuses/_detailed_status.html.haml
index 70cfbd6b87..735cc1f371 100644
--- a/app/views/statuses/_detailed_status.html.haml
+++ b/app/views/statuses/_detailed_status.html.haml
@@ -1,3 +1,7 @@
+:ruby
+  grouped_emoji_reactions ||= Oj.load(status.status_stat&.emoji_reactions || '', mode: :strict) || []
+  p '=================== DEBUG ' + grouped_emoji_reactions.first&.to_s
+
 .detailed-status.detailed-status--flex{ class: "detailed-status-#{status.visibility}" }
   .p-author.h-card
     = link_to ActivityPub::TagManager.instance.url_for(status.account), class: 'detailed-status__display-name u-url', target: stream_link_target, rel: 'noopener' do
@@ -36,6 +40,13 @@
   - elsif status.preview_card
     = render_card_component(status)
 
+  - if grouped_emoji_reactions.size > 0
+    .status__emoji-reactions-bar
+      - grouped_emoji_reactions.each do |reaction|
+        %button.emoji-reactions-bar__button
+          %span.emojify= prerender_custom_emojis_from_hash(emoji_name_format(reaction, status), reaction)
+          %span.count= reaction['count']
+
   .detailed-status__meta
     %data.dt-published{ value: status.created_at.to_time.iso8601 }
     - if status.edited?
diff --git a/app/views/statuses/_simple_status.html.haml b/app/views/statuses/_simple_status.html.haml
index 32584c92a1..b046b548bd 100644
--- a/app/views/statuses/_simple_status.html.haml
+++ b/app/views/statuses/_simple_status.html.haml
@@ -1,5 +1,6 @@
 :ruby
   hide_show_thread ||= false
+  grouped_emoji_reactions ||= Oj.load(status.status_stat&.emoji_reactions || '', mode: :strict) || []
 
 .status{ class: "status-#{status.visibility}" }
   .status__info
@@ -52,6 +53,13 @@
     = link_to ActivityPub::TagManager.instance.url_for(status), class: 'status__content__read-more-button', target: stream_link_target, rel: 'noopener noreferrer' do
       = t 'statuses.show_thread'
 
+  - if grouped_emoji_reactions.size > 0
+    .status__emoji-reactions-bar
+      - grouped_emoji_reactions.each do |reaction|
+        %button.emoji-reactions-bar__button
+          %span.emojify= prerender_custom_emojis_from_hash(emoji_name_format(reaction, status), reaction)
+          %span.count= reaction['count']
+
   .status__action-bar
     %span.status__action-bar-button.icon-button.icon-button--with-counter
       - if status.in_reply_to_id.nil?