diff --git a/src/components/mute_card/mute_card.js b/src/components/mute_card/mute_card.js
new file mode 100644
index 00000000..5dd0a9e5
--- /dev/null
+++ b/src/components/mute_card/mute_card.js
@@ -0,0 +1,37 @@
+import BasicUserCard from '../basic_user_card/basic_user_card.vue'
+
+const MuteCard = {
+  props: ['userId'],
+  data () {
+    return {
+      progress: false
+    }
+  },
+  computed: {
+    user () {
+      return this.$store.getters.userById(this.userId)
+    },
+    muted () {
+      return this.user.muted
+    }
+  },
+  components: {
+    BasicUserCard
+  },
+  methods: {
+    unmuteUser () {
+      this.progress = true
+      this.$store.dispatch('unmuteUser', this.user.id).then(() => {
+        this.progress = false
+      })
+    },
+    muteUser () {
+      this.progress = true
+      this.$store.dispatch('muteUser', this.user.id).then(() => {
+        this.progress = false
+      })
+    }
+  }
+}
+
+export default MuteCard
diff --git a/src/components/mute_card/mute_card.vue b/src/components/mute_card/mute_card.vue
new file mode 100644
index 00000000..e1bfe20b
--- /dev/null
+++ b/src/components/mute_card/mute_card.vue
@@ -0,0 +1,24 @@
+<template>
+  <basic-user-card :user="user">
+    <template slot="secondary-area">
+      <button class="btn btn-default" @click="unmuteUser" :disabled="progress" v-if="muted">
+        <template v-if="progress">
+          {{ $t('user_card.unmute_progress') }}
+        </template>
+        <template v-else>
+          {{ $t('user_card.unmute') }}
+        </template>
+      </button>
+      <button class="btn btn-default" @click="muteUser" :disabled="progress" v-else>
+        <template v-if="progress">
+          {{ $t('user_card.mute_progress') }}
+        </template>
+        <template v-else>
+          {{ $t('user_card.mute') }}
+        </template>
+      </button>
+    </template>
+  </basic-user-card>
+</template>
+
+<script src="./mute_card.js"></script>
\ No newline at end of file
diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js
index 8eade382..8114d5e2 100644
--- a/src/components/user_settings/user_settings.js
+++ b/src/components/user_settings/user_settings.js
@@ -6,7 +6,7 @@ import ImageCropper from '../image_cropper/image_cropper.vue'
 import StyleSwitcher from '../style_switcher/style_switcher.vue'
 import fileSizeFormatService from '../../services/file_size_format/file_size_format.js'
 import BlockCard from '../block_card/block_card.vue'
-import withLoadMore from '../../hocs/with_load_more/with_load_more'
+import MuteCard from '../mute_card/mute_card.vue'
 import withSubscription from '../../hocs/with_subscription/with_subscription'
 import withList from '../../hocs/with_list/with_list'
 
@@ -18,6 +18,14 @@ const BlockListWithSubscription = withSubscription(
   'entries'
 )
 
+const MuteList = withList(MuteCard, userId => ({ userId }))
+const MuteListWithSubscription = withSubscription(
+  MuteList,
+  (props, $store) => $store.dispatch('fetchMutes'),
+  (props, $store) => get($store.state.users.currentUser, 'muteIds', []),
+  'entries'
+)
+
 const UserSettings = {
   data () {
     return {
@@ -55,7 +63,8 @@ const UserSettings = {
     StyleSwitcher,
     TabSwitcher,
     ImageCropper,
-    'block-list': BlockListWithSubscription
+    'block-list': BlockListWithSubscription,
+    'mute-list': MuteListWithSubscription
   },
   computed: {
     user () {
diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue
index 5bae583c..27f3e7cb 100644
--- a/src/components/user_settings/user_settings.vue
+++ b/src/components/user_settings/user_settings.vue
@@ -166,6 +166,10 @@
         <div :label="$t('settings.blocks_tab')">
           <block-list :refresh="true" />
         </div>
+
+        <div :label="$t('settings.mutes_tab')">
+          <mute-list :refresh="true" />
+        </div>
       </tab-switcher>
     </div>
   </div>
diff --git a/src/i18n/en.json b/src/i18n/en.json
index eeb95f9c..b41b6db9 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -165,6 +165,7 @@
     "lock_account_description": "Restrict your account to approved followers only",
     "loop_video": "Loop videos",
     "loop_video_silent_only": "Loop only videos without sound (i.e. Mastodon's \"gifs\")",
+    "mutes_tab": "Mutes",
     "play_videos_in_modal": "Play videos directly in the media viewer",
     "use_contain_fit": "Don't crop the attachment in thumbnails",
     "name": "Name",
diff --git a/src/modules/users.js b/src/modules/users.js
index 1f03b47e..71201a77 100644
--- a/src/modules/users.js
+++ b/src/modules/users.js
@@ -89,6 +89,10 @@ export const mutations = {
     const user = state.currentUser
     user.blockIds = union(user.blockIds, blockIds)
   },
+  saveMutes (state, ids) {
+    const user = state.currentUser
+    user.muteIds = union(user.muteIds, ids)
+  },
   setUserForStatus (state, status) {
     status.user = state.usersObject[status.user.id]
   },
@@ -157,6 +161,22 @@ const users = {
       return store.rootState.api.backendInteractor.unblockUser(id)
         .then((user) => store.commit('addNewUsers', [user]))
     },
+    fetchMutes (store) {
+      return store.rootState.api.backendInteractor.fetchMutes()
+        .then((mutedUsers) => {
+          each(mutedUsers, (user) => { user.muted = true })
+          store.commit('addNewUsers', mutedUsers)
+          store.commit('saveMutes', map(mutedUsers, 'id'))
+        })
+    },
+    muteUser (store, id) {
+      return store.state.api.backendInteractor.setUserMute({ id, muted: true })
+        .then((user) => store.commit('addNewUsers', [user]))
+    },
+    unmuteUser (store, id) {
+      return store.state.api.backendInteractor.setUserMute({ id, muted: false })
+        .then((user) => store.commit('addNewUsers', [user]))
+    },
     addFriends ({ rootState, commit }, fetchBy) {
       return new Promise((resolve, reject) => {
         const user = rootState.users.usersObject[fetchBy]
@@ -300,10 +320,7 @@ const users = {
               store.dispatch('startFetching', { timeline: 'friends' })
 
               // Get user mutes and follower info
-              store.rootState.api.backendInteractor.fetchMutes().then((mutedUsers) => {
-                each(mutedUsers, (user) => { user.muted = true })
-                store.commit('addNewUsers', mutedUsers)
-              })
+              store.dispatch('fetchMutes')
 
               // Fetch our friends
               store.rootState.api.backendInteractor.fetchFriends({ id: user.id })
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index 0e1be61e..49c83811 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -121,6 +121,7 @@ export const parseUser = (data) => {
     output.follow_request_count = data.pleroma.follow_request_count
   }
   output.blockIds = []
+  output.muteIds = []
 
   return output
 }