diff --git a/.babelrc b/.babelrc
index 081c4f963c24a4fd6a688af21b7396a4dd8695f2..292d52e2775924f4ca1b6816ae3d74f0cf9cdef9 100644
--- a/.babelrc
+++ b/.babelrc
@@ -15,6 +15,7 @@
   "plugins": [
     "syntax-dynamic-import",
     ["transform-object-rest-spread", { "useBuiltIns": true }],
+    "transform-decorators-legacy",
     "transform-class-properties",
     [
       "react-intl",
diff --git a/app/javascript/mastodon/components/account.js b/app/javascript/mastodon/components/account.js
index 960d136d3347ceb1c72bf061b6039b958a0692d9..b6ca0661fb154a6ba03bda268e11e8db7c887ac7 100644
--- a/app/javascript/mastodon/components/account.js
+++ b/app/javascript/mastodon/components/account.js
@@ -16,7 +16,8 @@ const messages = defineMessages({
   unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
 });
 
-class Account extends ImmutablePureComponent {
+@injectIntl
+export default class Account extends ImmutablePureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map.isRequired,
@@ -82,5 +83,3 @@ class Account extends ImmutablePureComponent {
   }
 
 }
-
-export default injectIntl(Account);
diff --git a/app/javascript/mastodon/components/attachment_list.js b/app/javascript/mastodon/components/attachment_list.js
index a57c25ad0be5d39e59629ada91ba503eb194b156..b3d00b335730e69b663afc1f0f769461f273ec7d 100644
--- a/app/javascript/mastodon/components/attachment_list.js
+++ b/app/javascript/mastodon/components/attachment_list.js
@@ -4,7 +4,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
 
 const filename = url => url.split('/').pop().split('#')[0].split('?')[0];
 
-class AttachmentList extends ImmutablePureComponent {
+export default class AttachmentList extends ImmutablePureComponent {
 
   static propTypes = {
     media: ImmutablePropTypes.list.isRequired,
@@ -31,5 +31,3 @@ class AttachmentList extends ImmutablePureComponent {
   }
 
 }
-
-export default AttachmentList;
diff --git a/app/javascript/mastodon/components/autosuggest_textarea.js b/app/javascript/mastodon/components/autosuggest_textarea.js
index 9a5760a2cfb44f6680dd118375c8605e7a676be2..fa41e59e1fce922d968b365baa41eb8e8cc1c504 100644
--- a/app/javascript/mastodon/components/autosuggest_textarea.js
+++ b/app/javascript/mastodon/components/autosuggest_textarea.js
@@ -31,7 +31,7 @@ const textAtCursorMatchesToken = (str, caretPosition) => {
   }
 };
 
-class AutosuggestTextarea extends ImmutablePureComponent {
+export default class AutosuggestTextarea extends ImmutablePureComponent {
 
   static propTypes = {
     value: PropTypes.string,
@@ -196,5 +196,3 @@ class AutosuggestTextarea extends ImmutablePureComponent {
   }
 
 }
-
-export default AutosuggestTextarea;
diff --git a/app/javascript/mastodon/components/avatar.js b/app/javascript/mastodon/components/avatar.js
index 3531a42b56a649a5b6eb000f0302d0044f80219c..4f8170657610afc81ec04ad73f9a9401e8817514 100644
--- a/app/javascript/mastodon/components/avatar.js
+++ b/app/javascript/mastodon/components/avatar.js
@@ -1,7 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 
-class Avatar extends React.PureComponent {
+export default class Avatar extends React.PureComponent {
 
   static propTypes = {
     src: PropTypes.string.isRequired,
@@ -66,5 +66,3 @@ class Avatar extends React.PureComponent {
   }
 
 }
-
-export default Avatar;
diff --git a/app/javascript/mastodon/components/avatar_overlay.js b/app/javascript/mastodon/components/avatar_overlay.js
index c82c8963720feb54b2a898f0afe91ce193ed3f13..de43e0ef5150a234ee0fd232d6dc5051034116c9 100644
--- a/app/javascript/mastodon/components/avatar_overlay.js
+++ b/app/javascript/mastodon/components/avatar_overlay.js
@@ -1,7 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 
-class AvatarOverlay extends React.PureComponent {
+export default class AvatarOverlay extends React.PureComponent {
 
   static propTypes = {
     staticSrc: PropTypes.string.isRequired,
@@ -28,5 +28,3 @@ class AvatarOverlay extends React.PureComponent {
   }
 
 }
-
-export default AvatarOverlay;
diff --git a/app/javascript/mastodon/components/button.js b/app/javascript/mastodon/components/button.js
index 52af193e7914d6fbac6dae4ea9c9217cb36957b7..51e2e6a7a80c83e5cfd0da880af2b863672890f0 100644
--- a/app/javascript/mastodon/components/button.js
+++ b/app/javascript/mastodon/components/button.js
@@ -2,7 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import classNames from 'classnames';
 
-class Button extends React.PureComponent {
+export default class Button extends React.PureComponent {
 
   static propTypes = {
     text: PropTypes.node,
@@ -61,5 +61,3 @@ class Button extends React.PureComponent {
   }
 
 }
-
-export default Button;
diff --git a/app/javascript/mastodon/components/column.js b/app/javascript/mastodon/components/column.js
index 157a89c0e261377ef932edcdbb3aa545f8a7049c..3cbb745c5aac693ec0df808e79516b175d869db2 100644
--- a/app/javascript/mastodon/components/column.js
+++ b/app/javascript/mastodon/components/column.js
@@ -2,7 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import scrollTop from '../scroll';
 
-class Column extends React.PureComponent {
+export default class Column extends React.PureComponent {
 
   static propTypes = {
     children: PropTypes.node,
@@ -41,5 +41,3 @@ class Column extends React.PureComponent {
   }
 
 }
-
-export default Column;
diff --git a/app/javascript/mastodon/components/column_back_button.js b/app/javascript/mastodon/components/column_back_button.js
index 191c0f597ef425a35136903a68bdd7dee95cb5ce..ba2736d7a07fb8cb8739d68ca04b340865952fd6 100644
--- a/app/javascript/mastodon/components/column_back_button.js
+++ b/app/javascript/mastodon/components/column_back_button.js
@@ -2,7 +2,7 @@ import React from 'react';
 import { FormattedMessage } from 'react-intl';
 import PropTypes from 'prop-types';
 
-class ColumnBackButton extends React.PureComponent {
+export default class ColumnBackButton extends React.PureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -23,5 +23,3 @@ class ColumnBackButton extends React.PureComponent {
   }
 
 }
-
-export default ColumnBackButton;
diff --git a/app/javascript/mastodon/components/column_back_button_slim.js b/app/javascript/mastodon/components/column_back_button_slim.js
index ffb05fa027d64070baac4b32aa87a2eb48ee676d..3b4f46d99f44de240f9cff00674c3f1550c720a9 100644
--- a/app/javascript/mastodon/components/column_back_button_slim.js
+++ b/app/javascript/mastodon/components/column_back_button_slim.js
@@ -2,7 +2,7 @@ import React from 'react';
 import { FormattedMessage } from 'react-intl';
 import PropTypes from 'prop-types';
 
-class ColumnBackButtonSlim extends React.PureComponent {
+export default class ColumnBackButtonSlim extends React.PureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -25,5 +25,3 @@ class ColumnBackButtonSlim extends React.PureComponent {
   }
 
 }
-
-export default ColumnBackButtonSlim;
diff --git a/app/javascript/mastodon/components/column_collapsable.js b/app/javascript/mastodon/components/column_collapsable.js
index c7c953acdfa9da55c313416712853a0937c6a537..d6b4edb9fefa3906e688a50409efa054bd6e95c9 100644
--- a/app/javascript/mastodon/components/column_collapsable.js
+++ b/app/javascript/mastodon/components/column_collapsable.js
@@ -1,7 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 
-class ColumnCollapsable extends React.PureComponent {
+export default class ColumnCollapsable extends React.PureComponent {
 
   static propTypes = {
     icon: PropTypes.string.isRequired,
@@ -48,5 +48,3 @@ class ColumnCollapsable extends React.PureComponent {
   }
 
 }
-
-export default ColumnCollapsable;
diff --git a/app/javascript/mastodon/components/column_header.js b/app/javascript/mastodon/components/column_header.js
index 076f1cdaddc57a4482c6238a4769676d552700d7..a309f74e8a7e906005031a6e4493e033132d248b 100644
--- a/app/javascript/mastodon/components/column_header.js
+++ b/app/javascript/mastodon/components/column_header.js
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
 import classNames from 'classnames';
 import { FormattedMessage } from 'react-intl';
 
-class ColumnHeader extends React.PureComponent {
+export default class ColumnHeader extends React.PureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -141,5 +141,3 @@ class ColumnHeader extends React.PureComponent {
   }
 
 }
-
-export default ColumnHeader;
diff --git a/app/javascript/mastodon/components/display_name.js b/app/javascript/mastodon/components/display_name.js
index 6fbc1dfc0ba37d57f92766dfea1fe371581e4292..dc3665a2b05da7123bf0d4af645eef701dcde4c6 100644
--- a/app/javascript/mastodon/components/display_name.js
+++ b/app/javascript/mastodon/components/display_name.js
@@ -3,7 +3,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
 import escapeTextContentForBrowser from 'escape-html';
 import emojify from '../emoji';
 
-class DisplayName extends React.PureComponent {
+export default class DisplayName extends React.PureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map.isRequired,
@@ -21,5 +21,3 @@ class DisplayName extends React.PureComponent {
   }
 
 }
-
-export default DisplayName;
diff --git a/app/javascript/mastodon/components/dropdown_menu.js b/app/javascript/mastodon/components/dropdown_menu.js
index deaab938e4dc45c33bc86e2d49aee1a6e5bd3ca0..12e1b44fa2225d5da2e80e8833aa550086913fe0 100644
--- a/app/javascript/mastodon/components/dropdown_menu.js
+++ b/app/javascript/mastodon/components/dropdown_menu.js
@@ -2,7 +2,7 @@ import React from 'react';
 import Dropdown, { DropdownTrigger, DropdownContent } from 'react-simple-dropdown';
 import PropTypes from 'prop-types';
 
-class DropdownMenu extends React.PureComponent {
+export default class DropdownMenu extends React.PureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -92,5 +92,3 @@ class DropdownMenu extends React.PureComponent {
   }
 
 }
-
-export default DropdownMenu;
diff --git a/app/javascript/mastodon/components/extended_video_player.js b/app/javascript/mastodon/components/extended_video_player.js
index 4d92bd779b3a31c25359cd2c316784ee0f453173..4c62fa7b3dfe36b0b6bcc24d087b82610765a550 100644
--- a/app/javascript/mastodon/components/extended_video_player.js
+++ b/app/javascript/mastodon/components/extended_video_player.js
@@ -1,7 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 
-class ExtendedVideoPlayer extends React.PureComponent {
+export default class ExtendedVideoPlayer extends React.PureComponent {
 
   static propTypes = {
     src: PropTypes.string.isRequired,
@@ -44,5 +44,3 @@ class ExtendedVideoPlayer extends React.PureComponent {
   }
 
 }
-
-export default ExtendedVideoPlayer;
diff --git a/app/javascript/mastodon/components/icon_button.js b/app/javascript/mastodon/components/icon_button.js
index 302e63df5c9942752874cc6e041cb26e812de295..ac734f5ad4e1e9f9b5811bdb537a2902c9e18031 100644
--- a/app/javascript/mastodon/components/icon_button.js
+++ b/app/javascript/mastodon/components/icon_button.js
@@ -3,7 +3,7 @@ import Motion from 'react-motion/lib/Motion';
 import spring from 'react-motion/lib/spring';
 import PropTypes from 'prop-types';
 
-class IconButton extends React.PureComponent {
+export default class IconButton extends React.PureComponent {
 
   static propTypes = {
     className: PropTypes.string,
@@ -86,5 +86,3 @@ class IconButton extends React.PureComponent {
   }
 
 }
-
-export default IconButton;
diff --git a/app/javascript/mastodon/components/load_more.js b/app/javascript/mastodon/components/load_more.js
index fa0caaae99be3e7e04294917f295f3758abc0ad7..2996d4dc8d8d8176c3c2b45d3bf6e525602ad1ba 100644
--- a/app/javascript/mastodon/components/load_more.js
+++ b/app/javascript/mastodon/components/load_more.js
@@ -2,7 +2,7 @@ import React from 'react';
 import { FormattedMessage } from 'react-intl';
 import PropTypes from 'prop-types';
 
-class LoadMore extends React.PureComponent {
+export default class LoadMore extends React.PureComponent {
 
   static propTypes = {
     onClick: PropTypes.func,
@@ -17,5 +17,3 @@ class LoadMore extends React.PureComponent {
   }
 
 }
-
-export default LoadMore;
diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js
index cbed90f82b23417d3b41476ca56417eab50b71d9..78ff351308ce8e91794dc54dab588fe8dd31fd3c 100644
--- a/app/javascript/mastodon/components/media_gallery.js
+++ b/app/javascript/mastodon/components/media_gallery.js
@@ -123,7 +123,8 @@ class Item extends React.PureComponent {
 
 }
 
-class MediaGallery extends React.PureComponent {
+@injectIntl
+export default class MediaGallery extends React.PureComponent {
 
   static propTypes = {
     sensitive: PropTypes.bool,
@@ -183,5 +184,3 @@ class MediaGallery extends React.PureComponent {
   }
 
 }
-
-export default injectIntl(MediaGallery);
diff --git a/app/javascript/mastodon/components/permalink.js b/app/javascript/mastodon/components/permalink.js
index 7149e83801923c58f8e80c832bfc2deb930f758f..5d3e4738d04ba48c00c35a4adfd31b2d7367ed13 100644
--- a/app/javascript/mastodon/components/permalink.js
+++ b/app/javascript/mastodon/components/permalink.js
@@ -1,7 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 
-class Permalink extends React.PureComponent {
+export default class Permalink extends React.PureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -32,5 +32,3 @@ class Permalink extends React.PureComponent {
   }
 
 }
-
-export default Permalink;
diff --git a/app/javascript/mastodon/components/relative_timestamp.js b/app/javascript/mastodon/components/relative_timestamp.js
index 3eed88df80cc32383d2ee279d879e78f03e43232..2717d2326d7ce294be2653190a003462795c2bfd 100644
--- a/app/javascript/mastodon/components/relative_timestamp.js
+++ b/app/javascript/mastodon/components/relative_timestamp.js
@@ -11,7 +11,8 @@ const dateFormatOptions = {
   minute: '2-digit',
 };
 
-class RelativeTimestamp extends React.Component {
+@injectIntl
+export default class RelativeTimestamp extends React.Component {
 
   static propTypes = {
     intl: PropTypes.object.isRequired,
@@ -37,5 +38,3 @@ class RelativeTimestamp extends React.Component {
   }
 
 }
-
-export default injectIntl(RelativeTimestamp);
diff --git a/app/javascript/mastodon/components/setting_text.js b/app/javascript/mastodon/components/setting_text.js
index d4f177f8abb2ca718487edb1d51f8699214f9ca9..dd975bc991be04db7091e29cc11481cb351822d2 100644
--- a/app/javascript/mastodon/components/setting_text.js
+++ b/app/javascript/mastodon/components/setting_text.js
@@ -2,7 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 
-class SettingText extends React.PureComponent {
+export default class SettingText extends React.PureComponent {
 
   static propTypes = {
     settings: ImmutablePropTypes.map.isRequired,
@@ -29,5 +29,3 @@ class SettingText extends React.PureComponent {
   }
 
 }
-
-export default SettingText;
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js
index 3be3685ece295a2f3e41a84f1e9f04f195c9aab5..81196c82a4b0790aaa5d319607f1da56c5d1a6f3 100644
--- a/app/javascript/mastodon/components/status.js
+++ b/app/javascript/mastodon/components/status.js
@@ -15,7 +15,7 @@ import escapeTextContentForBrowser from 'escape-html';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import scheduleIdleTask from '../features/ui/util/schedule_idle_task';
 
-class Status extends ImmutablePureComponent {
+export default class Status extends ImmutablePureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -233,5 +233,3 @@ class Status extends ImmutablePureComponent {
   }
 
 }
-
-export default Status;
diff --git a/app/javascript/mastodon/components/status_action_bar.js b/app/javascript/mastodon/components/status_action_bar.js
index 800f0d0fbfc3b3001f79cb3fe6b91f80d6ded1d6..edb2d6eb0a4c5607b5b4735aa6cc13c3bd01deaf 100644
--- a/app/javascript/mastodon/components/status_action_bar.js
+++ b/app/javascript/mastodon/components/status_action_bar.js
@@ -22,7 +22,8 @@ const messages = defineMessages({
   unmuteConversation: { id: 'status.unmute_conversation', defaultMessage: 'Unmute conversation' },
 });
 
-class StatusActionBar extends ImmutablePureComponent {
+@injectIntl
+export default class StatusActionBar extends ImmutablePureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -149,5 +150,3 @@ class StatusActionBar extends ImmutablePureComponent {
   }
 
 }
-
-export default injectIntl(StatusActionBar);
diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js
index 605d42138c4a328f50f959189fd7b7e8754981e1..0acea033c5a292d3c740362b20a5297edd3ad765 100644
--- a/app/javascript/mastodon/components/status_content.js
+++ b/app/javascript/mastodon/components/status_content.js
@@ -7,7 +7,7 @@ import { isRtl } from '../rtl';
 import { FormattedMessage } from 'react-intl';
 import Permalink from './permalink';
 
-class StatusContent extends React.PureComponent {
+export default class StatusContent extends React.PureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -171,5 +171,3 @@ class StatusContent extends React.PureComponent {
   }
 
 }
-
-export default StatusContent;
diff --git a/app/javascript/mastodon/components/status_list.js b/app/javascript/mastodon/components/status_list.js
index 40e9d38c1b3d336a78ddaf6b9e20fdc272d8ce7b..5bc46e8eeb4e9974b3458cf95bbcbec0d4b896f6 100644
--- a/app/javascript/mastodon/components/status_list.js
+++ b/app/javascript/mastodon/components/status_list.js
@@ -8,7 +8,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
 import IntersectionObserverWrapper from '../features/ui/util/intersection_observer_wrapper';
 import { debounce } from 'lodash';
 
-class StatusList extends ImmutablePureComponent {
+export default class StatusList extends ImmutablePureComponent {
 
   static propTypes = {
     scrollKey: PropTypes.string.isRequired,
@@ -142,5 +142,3 @@ class StatusList extends ImmutablePureComponent {
   }
 
 }
-
-export default StatusList;
diff --git a/app/javascript/mastodon/components/video_player.js b/app/javascript/mastodon/components/video_player.js
index 66c3a64bc684f5426375d534c24ef5efa02c2ee8..452a843196e300bdda839d73db60fcf83cd36f6b 100644
--- a/app/javascript/mastodon/components/video_player.js
+++ b/app/javascript/mastodon/components/video_player.js
@@ -11,7 +11,8 @@ const messages = defineMessages({
   expand_video: { id: 'video_player.expand', defaultMessage: 'Expand video' },
 });
 
-class VideoPlayer extends React.PureComponent {
+@injectIntl
+export default class VideoPlayer extends React.PureComponent {
 
   static propTypes = {
     media: ImmutablePropTypes.map.isRequired,
@@ -193,5 +194,3 @@ class VideoPlayer extends React.PureComponent {
   }
 
 }
-
-export default injectIntl(VideoPlayer);
diff --git a/app/javascript/mastodon/containers/mastodon.js b/app/javascript/mastodon/containers/mastodon.js
index e3cb815c9d3730b4576e42662bcd60c0de3e8876..3bd89902f67acdf93aee16c8fc1d23f8ec49b99f 100644
--- a/app/javascript/mastodon/containers/mastodon.js
+++ b/app/javascript/mastodon/containers/mastodon.js
@@ -26,7 +26,11 @@ const store = configureStore();
 const initialState = JSON.parse(document.getElementById('initial-state').textContent);
 store.dispatch(hydrateStore(initialState));
 
-class Mastodon extends React.PureComponent {
+export default class Mastodon extends React.PureComponent {
+
+  static propTypes = {
+    locale: PropTypes.string.isRequired,
+  };
 
   componentDidMount() {
     const { locale }  = this.props;
@@ -117,9 +121,3 @@ class Mastodon extends React.PureComponent {
   }
 
 }
-
-Mastodon.propTypes = {
-  locale: PropTypes.string.isRequired,
-};
-
-export default Mastodon;
diff --git a/app/javascript/mastodon/features/account/components/action_bar.js b/app/javascript/mastodon/features/account/components/action_bar.js
index 0ea8ad34782b4a754d0d073d82371b75c5634690..374da103eabf6344918e7783d0da49b970eebfd3 100644
--- a/app/javascript/mastodon/features/account/components/action_bar.js
+++ b/app/javascript/mastodon/features/account/components/action_bar.js
@@ -21,7 +21,8 @@ const messages = defineMessages({
   unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unhide {domain}' },
 });
 
-class ActionBar extends React.PureComponent {
+@injectIntl
+export default class ActionBar extends React.PureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map.isRequired,
@@ -105,5 +106,3 @@ class ActionBar extends React.PureComponent {
   }
 
 }
-
-export default injectIntl(ActionBar);
diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js
index 80a671a01bbe5b813a26d09eecee3351c932d29c..3239b1085cb8ade1f81bf1067a0ca4701a478228 100644
--- a/app/javascript/mastodon/features/account/components/header.js
+++ b/app/javascript/mastodon/features/account/components/header.js
@@ -70,7 +70,9 @@ class Avatar extends ImmutablePureComponent {
 
 }
 
-class Header extends ImmutablePureComponent {
+@connect(makeMapStateToProps)
+@injectIntl
+export default class Header extends ImmutablePureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map,
@@ -140,5 +142,3 @@ class Header extends ImmutablePureComponent {
   }
 
 }
-
-export default connect(makeMapStateToProps)(injectIntl(Header));
diff --git a/app/javascript/mastodon/features/account_gallery/components/media_item.js b/app/javascript/mastodon/features/account_gallery/components/media_item.js
index 31c05c8669eb5c52577d5d928110c2665875699f..dda3d4e37baaf3090e98760fc179d3bce5112106 100644
--- a/app/javascript/mastodon/features/account_gallery/components/media_item.js
+++ b/app/javascript/mastodon/features/account_gallery/components/media_item.js
@@ -3,7 +3,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import Permalink from '../../../components/permalink';
 
-class MediaItem extends ImmutablePureComponent {
+export default class MediaItem extends ImmutablePureComponent {
 
   static propTypes = {
     media: ImmutablePropTypes.map.isRequired,
@@ -37,5 +37,3 @@ class MediaItem extends ImmutablePureComponent {
   }
 
 }
-
-export default MediaItem;
diff --git a/app/javascript/mastodon/features/account_gallery/index.js b/app/javascript/mastodon/features/account_gallery/index.js
index 1e4af30a4c57a22d1069ad2e969848c1f8f3a490..0cfd98f23157aa60c81be064ce57be5363055902 100644
--- a/app/javascript/mastodon/features/account_gallery/index.js
+++ b/app/javascript/mastodon/features/account_gallery/index.js
@@ -22,7 +22,8 @@ const mapStateToProps = (state, props) => ({
   autoPlayGif: state.getIn(['meta', 'auto_play_gif']),
 });
 
-class AccountGallery extends ImmutablePureComponent {
+@connect(mapStateToProps)
+export default class AccountGallery extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
@@ -111,5 +112,3 @@ class AccountGallery extends ImmutablePureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(AccountGallery);
diff --git a/app/javascript/mastodon/features/account_timeline/components/header.js b/app/javascript/mastodon/features/account_timeline/components/header.js
index 55fdc4167538fce8be0fa9d2b088863a33361c4b..7f80e39e8d72d16ce5511f17a15c0711bcbab032 100644
--- a/app/javascript/mastodon/features/account_timeline/components/header.js
+++ b/app/javascript/mastodon/features/account_timeline/components/header.js
@@ -6,7 +6,7 @@ import ActionBar from '../../account/components/action_bar';
 import MissingIndicator from '../../../components/missing_indicator';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 
-class Header extends ImmutablePureComponent {
+export default class Header extends ImmutablePureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map,
@@ -91,5 +91,3 @@ class Header extends ImmutablePureComponent {
   }
 
 }
-
-export default Header;
diff --git a/app/javascript/mastodon/features/account_timeline/index.js b/app/javascript/mastodon/features/account_timeline/index.js
index 1aab8f130debfafc847922dbdecfa9a0425d5a1b..955d0000e7a4e40545b71df63a9e8114051ab8ae 100644
--- a/app/javascript/mastodon/features/account_timeline/index.js
+++ b/app/javascript/mastodon/features/account_timeline/index.js
@@ -19,7 +19,8 @@ const mapStateToProps = (state, props) => ({
   me: state.getIn(['meta', 'me']),
 });
 
-class AccountTimeline extends ImmutablePureComponent {
+@connect(mapStateToProps)
+export default class AccountTimeline extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
@@ -77,5 +78,3 @@ class AccountTimeline extends ImmutablePureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(AccountTimeline);
diff --git a/app/javascript/mastodon/features/blocks/index.js b/app/javascript/mastodon/features/blocks/index.js
index de02e53cc36901ec73cea19836996736540a53fe..b16af4b287950b298093586961b1c655f69d92e7 100644
--- a/app/javascript/mastodon/features/blocks/index.js
+++ b/app/javascript/mastodon/features/blocks/index.js
@@ -19,7 +19,9 @@ const mapStateToProps = state => ({
   accountIds: state.getIn(['user_lists', 'blocks', 'items']),
 });
 
-class Blocks extends ImmutablePureComponent {
+@connect(mapStateToProps)
+@injectIntl
+export default class Blocks extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
@@ -66,5 +68,3 @@ class Blocks extends ImmutablePureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(injectIntl(Blocks));
diff --git a/app/javascript/mastodon/features/community_timeline/components/column_settings.js b/app/javascript/mastodon/features/community_timeline/components/column_settings.js
index aa487e34ee044bf8365bb690325b1504b6433f7d..a992b27bbdb458007d9b66e8653adce6dcf04985 100644
--- a/app/javascript/mastodon/features/community_timeline/components/column_settings.js
+++ b/app/javascript/mastodon/features/community_timeline/components/column_settings.js
@@ -9,7 +9,8 @@ const messages = defineMessages({
   settings: { id: 'home.settings', defaultMessage: 'Column settings' },
 });
 
-class ColumnSettings extends React.PureComponent {
+@injectIntl
+export default class ColumnSettings extends React.PureComponent {
 
   static propTypes = {
     settings: ImmutablePropTypes.map.isRequired,
@@ -32,5 +33,3 @@ class ColumnSettings extends React.PureComponent {
   }
 
 }
-
-export default injectIntl(ColumnSettings);
diff --git a/app/javascript/mastodon/features/community_timeline/index.js b/app/javascript/mastodon/features/community_timeline/index.js
index 6c4b5dacf268d59358d331a9afdda7ef119b46cb..0e2300f8ce17cc6aa9d4d0d329dbf7d6374f0813 100644
--- a/app/javascript/mastodon/features/community_timeline/index.js
+++ b/app/javascript/mastodon/features/community_timeline/index.js
@@ -27,7 +27,9 @@ const mapStateToProps = state => ({
   accessToken: state.getIn(['meta', 'access_token']),
 });
 
-class CommunityTimeline extends React.PureComponent {
+@connect(mapStateToProps)
+@injectIntl
+export default class CommunityTimeline extends React.PureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
@@ -141,5 +143,3 @@ class CommunityTimeline extends React.PureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(injectIntl(CommunityTimeline));
diff --git a/app/javascript/mastodon/features/compose/components/autosuggest_account.js b/app/javascript/mastodon/features/compose/components/autosuggest_account.js
index 23665811e8e076f563c51ffe175ab8ae999e79f6..ebfa3c247bd2ce4879b5335c0d861f6b068f45ee 100644
--- a/app/javascript/mastodon/features/compose/components/autosuggest_account.js
+++ b/app/javascript/mastodon/features/compose/components/autosuggest_account.js
@@ -4,7 +4,7 @@ import DisplayName from '../../../components/display_name';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 
-class AutosuggestAccount extends ImmutablePureComponent {
+export default class AutosuggestAccount extends ImmutablePureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map.isRequired,
@@ -22,5 +22,3 @@ class AutosuggestAccount extends ImmutablePureComponent {
   }
 
 }
-
-export default AutosuggestAccount;
diff --git a/app/javascript/mastodon/features/compose/components/character_counter.js b/app/javascript/mastodon/features/compose/components/character_counter.js
index e35f2b879cf2bba774261f7c082544b195746d04..6c488b661da3968723da74b02155953a6425291a 100644
--- a/app/javascript/mastodon/features/compose/components/character_counter.js
+++ b/app/javascript/mastodon/features/compose/components/character_counter.js
@@ -2,7 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { length } from 'stringz';
 
-class CharacterCounter extends React.PureComponent {
+export default class CharacterCounter extends React.PureComponent {
 
   static propTypes = {
     text: PropTypes.string.isRequired,
@@ -23,5 +23,3 @@ class CharacterCounter extends React.PureComponent {
   }
 
 }
-
-export default CharacterCounter;
diff --git a/app/javascript/mastodon/features/compose/components/compose_form.js b/app/javascript/mastodon/features/compose/components/compose_form.js
index d75bbdf9cbc69f0af8431a9ba28b9604d541c928..c379c1855a4e2e886010c90687d405b3845a4970 100644
--- a/app/javascript/mastodon/features/compose/components/compose_form.js
+++ b/app/javascript/mastodon/features/compose/components/compose_form.js
@@ -25,7 +25,8 @@ const messages = defineMessages({
   publishLoud: { id: 'compose_form.publish_loud', defaultMessage: '{publish}!' },
 });
 
-class ComposeForm extends ImmutablePureComponent {
+@injectIntl
+export default class ComposeForm extends ImmutablePureComponent {
 
   static propTypes = {
     intl: PropTypes.object.isRequired,
@@ -199,5 +200,3 @@ class ComposeForm extends ImmutablePureComponent {
   }
 
 }
-
-export default injectIntl(ComposeForm);
diff --git a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js
index afaff1be12675c4f4c9ccb3d6f33192af3856209..c83dbb63ece1ddc3017f03d2265050950c040ce0 100644
--- a/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js
+++ b/app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js
@@ -24,7 +24,8 @@ const settings = {
 
 let EmojiPicker; // load asynchronously
 
-class EmojiPickerDropdown extends React.PureComponent {
+@injectIntl
+export default class EmojiPickerDropdown extends React.PureComponent {
 
   static propTypes = {
     intl: PropTypes.object.isRequired,
@@ -123,5 +124,3 @@ class EmojiPickerDropdown extends React.PureComponent {
   }
 
 }
-
-export default injectIntl(EmojiPickerDropdown);
diff --git a/app/javascript/mastodon/features/compose/components/navigation_bar.js b/app/javascript/mastodon/features/compose/components/navigation_bar.js
index 00f27dea1ba44f559fb7348b50eccecc384fc389..fa4f560f3976afc77253be468e797ae491cdbce5 100644
--- a/app/javascript/mastodon/features/compose/components/navigation_bar.js
+++ b/app/javascript/mastodon/features/compose/components/navigation_bar.js
@@ -5,7 +5,7 @@ import Permalink from '../../../components/permalink';
 import { FormattedMessage } from 'react-intl';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 
-class NavigationBar extends ImmutablePureComponent {
+export default class NavigationBar extends ImmutablePureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map.isRequired,
@@ -30,5 +30,3 @@ class NavigationBar extends ImmutablePureComponent {
   }
 
 }
-
-export default NavigationBar;
diff --git a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
index f368186a5768ace0b0d12804f9442460793196ae..9524f7501ab1c743f9cea33f4cff5df1a847ae9d 100644
--- a/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
+++ b/app/javascript/mastodon/features/compose/components/privacy_dropdown.js
@@ -20,7 +20,8 @@ const iconStyle = {
   lineHeight: '27px',
 };
 
-class PrivacyDropdown extends React.PureComponent {
+@injectIntl
+export default class PrivacyDropdown extends React.PureComponent {
 
   static propTypes = {
     value: PropTypes.string.isRequired,
@@ -95,5 +96,3 @@ class PrivacyDropdown extends React.PureComponent {
   }
 
 }
-
-export default injectIntl(PrivacyDropdown);
diff --git a/app/javascript/mastodon/features/compose/components/reply_indicator.js b/app/javascript/mastodon/features/compose/components/reply_indicator.js
index 474549a5fbe6bc893d1ecee0689f5033fe2d425b..da00e46c51e7026184b43d99f36d70abedb40bc9 100644
--- a/app/javascript/mastodon/features/compose/components/reply_indicator.js
+++ b/app/javascript/mastodon/features/compose/components/reply_indicator.js
@@ -12,7 +12,8 @@ const messages = defineMessages({
   cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' },
 });
 
-class ReplyIndicator extends ImmutablePureComponent {
+@injectIntl
+export default class ReplyIndicator extends ImmutablePureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -61,5 +62,3 @@ class ReplyIndicator extends ImmutablePureComponent {
   }
 
 }
-
-export default injectIntl(ReplyIndicator);
diff --git a/app/javascript/mastodon/features/compose/components/search.js b/app/javascript/mastodon/features/compose/components/search.js
index 21b3cf34b259fede2361c4b333307158e0fa3b0b..cdc7952c0236a4f3f149a87c5fc7754eab86160d 100644
--- a/app/javascript/mastodon/features/compose/components/search.js
+++ b/app/javascript/mastodon/features/compose/components/search.js
@@ -6,7 +6,8 @@ const messages = defineMessages({
   placeholder: { id: 'search.placeholder', defaultMessage: 'Search' },
 });
 
-class Search extends React.PureComponent {
+@injectIntl
+export default class Search extends React.PureComponent {
 
   static propTypes = {
     value: PropTypes.string.isRequired,
@@ -70,5 +71,3 @@ class Search extends React.PureComponent {
   }
 
 }
-
-export default injectIntl(Search);
diff --git a/app/javascript/mastodon/features/compose/components/search_results.js b/app/javascript/mastodon/features/compose/components/search_results.js
index 1a2605c159b7cd41856bd46d517fa7b719bb656d..ae4d1e86ae1089d55aac8852e070506c803be571 100644
--- a/app/javascript/mastodon/features/compose/components/search_results.js
+++ b/app/javascript/mastodon/features/compose/components/search_results.js
@@ -6,7 +6,7 @@ import StatusContainer from '../../../containers/status_container';
 import Link from 'react-router-dom/Link';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 
-class SearchResults extends ImmutablePureComponent {
+export default class SearchResults extends ImmutablePureComponent {
 
   static propTypes = {
     results: ImmutablePropTypes.map.isRequired,
@@ -63,5 +63,3 @@ class SearchResults extends ImmutablePureComponent {
   }
 
 }
-
-export default SearchResults;
diff --git a/app/javascript/mastodon/features/compose/components/text_icon_button.js b/app/javascript/mastodon/features/compose/components/text_icon_button.js
index cc0fbd11a811cc2bd3be29657d9ff4b81a03ec0e..9c8ffab1f93d84fc947d3321e40e4e94c0ce7311 100644
--- a/app/javascript/mastodon/features/compose/components/text_icon_button.js
+++ b/app/javascript/mastodon/features/compose/components/text_icon_button.js
@@ -1,7 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 
-class TextIconButton extends React.PureComponent {
+export default class TextIconButton extends React.PureComponent {
 
   static propTypes = {
     label: PropTypes.string.isRequired,
@@ -27,5 +27,3 @@ class TextIconButton extends React.PureComponent {
   }
 
 }
-
-export default TextIconButton;
diff --git a/app/javascript/mastodon/features/compose/components/upload_button.js b/app/javascript/mastodon/features/compose/components/upload_button.js
index 0f11b9e8b6d6752c43cc42622341af9c6c68b092..badd6cfc5caf1e249f4a39218de0b508a2b63e8d 100644
--- a/app/javascript/mastodon/features/compose/components/upload_button.js
+++ b/app/javascript/mastodon/features/compose/components/upload_button.js
@@ -23,7 +23,9 @@ const iconStyle = {
   lineHeight: '27px',
 };
 
-class UploadButton extends ImmutablePureComponent {
+@connect(makeMapStateToProps)
+@injectIntl
+export default class UploadButton extends ImmutablePureComponent {
 
   static propTypes = {
     disabled: PropTypes.bool,
@@ -70,5 +72,3 @@ class UploadButton extends ImmutablePureComponent {
   }
 
 }
-
-export default connect(makeMapStateToProps)(injectIntl(UploadButton));
diff --git a/app/javascript/mastodon/features/compose/components/upload_form.js b/app/javascript/mastodon/features/compose/components/upload_form.js
index 7e665683a50291e600038368bea0b5e63ae10e44..78473dab40e0616eb28fb66b9e7449c5a4756c3d 100644
--- a/app/javascript/mastodon/features/compose/components/upload_form.js
+++ b/app/javascript/mastodon/features/compose/components/upload_form.js
@@ -11,7 +11,8 @@ const messages = defineMessages({
   undo: { id: 'upload_form.undo', defaultMessage: 'Undo' },
 });
 
-class UploadForm extends React.PureComponent {
+@injectIntl
+export default class UploadForm extends React.PureComponent {
 
   static propTypes = {
     media: ImmutablePropTypes.list.isRequired,
@@ -48,5 +49,3 @@ class UploadForm extends React.PureComponent {
   }
 
 }
-
-export default injectIntl(UploadForm);
diff --git a/app/javascript/mastodon/features/compose/components/upload_progress.js b/app/javascript/mastodon/features/compose/components/upload_progress.js
index 8c8ce3835196d0a61676378f37c4e1306f3488f2..3e49098c72cca94bc189c19a3beb0c0f8f6c370a 100644
--- a/app/javascript/mastodon/features/compose/components/upload_progress.js
+++ b/app/javascript/mastodon/features/compose/components/upload_progress.js
@@ -4,7 +4,7 @@ import Motion from 'react-motion/lib/Motion';
 import spring from 'react-motion/lib/spring';
 import { FormattedMessage } from 'react-intl';
 
-class UploadProgress extends React.PureComponent {
+export default class UploadProgress extends React.PureComponent {
 
   static propTypes = {
     active: PropTypes.bool,
@@ -40,5 +40,3 @@ class UploadProgress extends React.PureComponent {
   }
 
 }
-
-export default UploadProgress;
diff --git a/app/javascript/mastodon/features/compose/components/warning.js b/app/javascript/mastodon/features/compose/components/warning.js
index d0e75a5c3fb503855fcc8f7e727baa41392ecfb3..75f36b840479021f851159fc0da5ed43ee2f70d8 100644
--- a/app/javascript/mastodon/features/compose/components/warning.js
+++ b/app/javascript/mastodon/features/compose/components/warning.js
@@ -1,7 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 
-class Warning extends React.PureComponent {
+export default class Warning extends React.PureComponent {
 
   static propTypes = {
     message: PropTypes.node.isRequired,
@@ -18,5 +18,3 @@ class Warning extends React.PureComponent {
   }
 
 }
-
-export default Warning;
diff --git a/app/javascript/mastodon/features/compose/index.js b/app/javascript/mastodon/features/compose/index.js
index 0452de856606693b412b9a51908a9f1acb7dfc07..747fe421641118cb8624a417849452c9bc1d4832 100644
--- a/app/javascript/mastodon/features/compose/index.js
+++ b/app/javascript/mastodon/features/compose/index.js
@@ -23,7 +23,9 @@ const mapStateToProps = state => ({
   showSearch: state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']),
 });
 
-class Compose extends React.PureComponent {
+@connect(mapStateToProps)
+@injectIntl
+export default class Compose extends React.PureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
@@ -82,5 +84,3 @@ class Compose extends React.PureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(injectIntl(Compose));
diff --git a/app/javascript/mastodon/features/favourited_statuses/index.js b/app/javascript/mastodon/features/favourited_statuses/index.js
index caf0d2ca2bb1d7fa13d3ceac5029ce31ef451917..137e55089a8c536d126f7c1c6ea5c12f01748051 100644
--- a/app/javascript/mastodon/features/favourited_statuses/index.js
+++ b/app/javascript/mastodon/features/favourited_statuses/index.js
@@ -17,7 +17,9 @@ const mapStateToProps = state => ({
   loaded: state.getIn(['status_lists', 'favourites', 'loaded']),
 });
 
-class Favourites extends ImmutablePureComponent {
+@connect(mapStateToProps)
+@injectIntl
+export default class Favourites extends ImmutablePureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
@@ -53,5 +55,3 @@ class Favourites extends ImmutablePureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(injectIntl(Favourites));
diff --git a/app/javascript/mastodon/features/favourites/index.js b/app/javascript/mastodon/features/favourites/index.js
index 94f9f268b3879b32d2fb6e936b6447a04a9360e8..dc8109d16e3a1c1af8cd2b9b0e9dcc1a498a75dc 100644
--- a/app/javascript/mastodon/features/favourites/index.js
+++ b/app/javascript/mastodon/features/favourites/index.js
@@ -14,7 +14,8 @@ const mapStateToProps = (state, props) => ({
   accountIds: state.getIn(['user_lists', 'favourited_by', Number(props.params.statusId)]),
 });
 
-class Favourites extends ImmutablePureComponent {
+@connect(mapStateToProps)
+export default class Favourites extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
@@ -57,5 +58,3 @@ class Favourites extends ImmutablePureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(Favourites);
diff --git a/app/javascript/mastodon/features/follow_requests/components/account_authorize.js b/app/javascript/mastodon/features/follow_requests/components/account_authorize.js
index e41597c17ef9f3a6cc8cab9ab11e6613cc6914b4..566953ddd604354305aed80440239bd8c4d72c46 100644
--- a/app/javascript/mastodon/features/follow_requests/components/account_authorize.js
+++ b/app/javascript/mastodon/features/follow_requests/components/account_authorize.js
@@ -14,7 +14,8 @@ const messages = defineMessages({
   reject: { id: 'follow_request.reject', defaultMessage: 'Reject' },
 });
 
-class AccountAuthorize extends ImmutablePureComponent {
+@injectIntl
+export default class AccountAuthorize extends ImmutablePureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map.isRequired,
@@ -47,5 +48,3 @@ class AccountAuthorize extends ImmutablePureComponent {
   }
 
 }
-
-export default injectIntl(AccountAuthorize);
diff --git a/app/javascript/mastodon/features/follow_requests/index.js b/app/javascript/mastodon/features/follow_requests/index.js
index 286f128f450d6f5db73cd09d194559a0e6d8d0dc..4c9e514cb50e17571cba85fce280426ebd36663d 100644
--- a/app/javascript/mastodon/features/follow_requests/index.js
+++ b/app/javascript/mastodon/features/follow_requests/index.js
@@ -19,7 +19,9 @@ const mapStateToProps = state => ({
   accountIds: state.getIn(['user_lists', 'follow_requests', 'items']),
 });
 
-class FollowRequests extends ImmutablePureComponent {
+@connect(mapStateToProps)
+@injectIntl
+export default class FollowRequests extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
@@ -67,5 +69,3 @@ class FollowRequests extends ImmutablePureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(injectIntl(FollowRequests));
diff --git a/app/javascript/mastodon/features/followers/index.js b/app/javascript/mastodon/features/followers/index.js
index e9910dce48d8b4f3f8c024d0221fbd5a5d896345..2d85b9cc0b980b06665489a7242a696026dd02a4 100644
--- a/app/javascript/mastodon/features/followers/index.js
+++ b/app/javascript/mastodon/features/followers/index.js
@@ -21,7 +21,8 @@ const mapStateToProps = (state, props) => ({
   hasMore: !!state.getIn(['user_lists', 'followers', Number(props.params.accountId), 'next']),
 });
 
-class Followers extends ImmutablePureComponent {
+@connect(mapStateToProps)
+export default class Followers extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
@@ -90,5 +91,3 @@ class Followers extends ImmutablePureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(Followers);
diff --git a/app/javascript/mastodon/features/following/index.js b/app/javascript/mastodon/features/following/index.js
index 764f702fff9cc46f0cebbb8d3a69cbcd9c7d39a8..e4e2a4811eb2bd0004d674855bba2e2583e4c232 100644
--- a/app/javascript/mastodon/features/following/index.js
+++ b/app/javascript/mastodon/features/following/index.js
@@ -21,7 +21,8 @@ const mapStateToProps = (state, props) => ({
   hasMore: !!state.getIn(['user_lists', 'following', Number(props.params.accountId), 'next']),
 });
 
-class Following extends ImmutablePureComponent {
+@connect(mapStateToProps)
+export default class Following extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
@@ -90,5 +91,3 @@ class Following extends ImmutablePureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(Following);
diff --git a/app/javascript/mastodon/features/getting_started/index.js b/app/javascript/mastodon/features/getting_started/index.js
index c1eb06fcbb54c58547670c9602b8e72460ef093a..f8ea0102471d5105b11081f39c439a4d13108ebd 100644
--- a/app/javascript/mastodon/features/getting_started/index.js
+++ b/app/javascript/mastodon/features/getting_started/index.js
@@ -30,7 +30,9 @@ const mapStateToProps = state => ({
   columns: state.getIn(['settings', 'columns']),
 });
 
-class GettingStarted extends ImmutablePureComponent {
+@connect(mapStateToProps)
+@injectIntl
+export default class GettingStarted extends ImmutablePureComponent {
 
   static propTypes = {
     intl: PropTypes.object.isRequired,
@@ -105,5 +107,3 @@ class GettingStarted extends ImmutablePureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(injectIntl(GettingStarted));
diff --git a/app/javascript/mastodon/features/hashtag_timeline/index.js b/app/javascript/mastodon/features/hashtag_timeline/index.js
index 853434d4b71e69d8cd79910350f162f6437f5ab1..b17e8e1a5b5ad8e342602f700a1108709da8603d 100644
--- a/app/javascript/mastodon/features/hashtag_timeline/index.js
+++ b/app/javascript/mastodon/features/hashtag_timeline/index.js
@@ -20,7 +20,8 @@ const mapStateToProps = state => ({
   accessToken: state.getIn(['meta', 'access_token']),
 });
 
-class HashtagTimeline extends React.PureComponent {
+@connect(mapStateToProps)
+export default class HashtagTimeline extends React.PureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
@@ -136,5 +137,3 @@ class HashtagTimeline extends React.PureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(HashtagTimeline);
diff --git a/app/javascript/mastodon/features/home_timeline/components/column_settings.js b/app/javascript/mastodon/features/home_timeline/components/column_settings.js
index 47cd340afbb5f891380430d5153c28017ef55e3b..43172bd25b462143658693f2c8d9e7ec380feaaa 100644
--- a/app/javascript/mastodon/features/home_timeline/components/column_settings.js
+++ b/app/javascript/mastodon/features/home_timeline/components/column_settings.js
@@ -10,7 +10,8 @@ const messages = defineMessages({
   settings: { id: 'home.settings', defaultMessage: 'Column settings' },
 });
 
-class ColumnSettings extends React.PureComponent {
+@injectIntl
+export default class ColumnSettings extends React.PureComponent {
 
   static propTypes = {
     settings: ImmutablePropTypes.map.isRequired,
@@ -43,5 +44,3 @@ class ColumnSettings extends React.PureComponent {
   }
 
 }
-
-export default injectIntl(ColumnSettings);
diff --git a/app/javascript/mastodon/features/home_timeline/index.js b/app/javascript/mastodon/features/home_timeline/index.js
index ddebf23793128dc117812ef7e55ff240e9f0cffd..6021299d64a6044cffea9ccbe405c73c9601bec9 100644
--- a/app/javascript/mastodon/features/home_timeline/index.js
+++ b/app/javascript/mastodon/features/home_timeline/index.js
@@ -19,7 +19,9 @@ const mapStateToProps = state => ({
   hasFollows: state.getIn(['accounts_counters', state.getIn(['meta', 'me']), 'following_count']) > 0,
 });
 
-class HomeTimeline extends React.PureComponent {
+@connect(mapStateToProps)
+@injectIntl
+export default class HomeTimeline extends React.PureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
@@ -96,5 +98,3 @@ class HomeTimeline extends React.PureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(injectIntl(HomeTimeline));
diff --git a/app/javascript/mastodon/features/mutes/index.js b/app/javascript/mastodon/features/mutes/index.js
index f0d8856beba69eecfdc4cc6064ea96abdef3710e..25ca921ae832ea8fb95686e224e12f5222541ffc 100644
--- a/app/javascript/mastodon/features/mutes/index.js
+++ b/app/javascript/mastodon/features/mutes/index.js
@@ -19,7 +19,16 @@ const mapStateToProps = state => ({
   accountIds: state.getIn(['user_lists', 'mutes', 'items']),
 });
 
-class Mutes extends ImmutablePureComponent {
+@connect(mapStateToProps)
+@injectIntl
+export default class Mutes extends ImmutablePureComponent {
+
+  static propTypes = {
+    params: PropTypes.object.isRequired,
+    dispatch: PropTypes.func.isRequired,
+    accountIds: ImmutablePropTypes.list,
+    intl: PropTypes.object.isRequired,
+  };
 
   componentWillMount () {
     this.props.dispatch(fetchMutes());
@@ -59,12 +68,3 @@ class Mutes extends ImmutablePureComponent {
   }
 
 }
-
-Mutes.propTypes = {
-  params: PropTypes.object.isRequired,
-  dispatch: PropTypes.func.isRequired,
-  accountIds: ImmutablePropTypes.list,
-  intl: PropTypes.object.isRequired,
-};
-
-export default connect(mapStateToProps)(injectIntl(Mutes));
diff --git a/app/javascript/mastodon/features/notifications/components/clear_column_button.js b/app/javascript/mastodon/features/notifications/components/clear_column_button.js
index 54beb1c4d676dadf08e0c87a326b35f7f5ddf6fc..22a10753f555a5193a0879d100a676c053c4250c 100644
--- a/app/javascript/mastodon/features/notifications/components/clear_column_button.js
+++ b/app/javascript/mastodon/features/notifications/components/clear_column_button.js
@@ -2,7 +2,7 @@ import React from 'react';
 import PropTypes from 'prop-types';
 import { FormattedMessage } from 'react-intl';
 
-class ClearColumnButton extends React.Component {
+export default class ClearColumnButton extends React.Component {
 
   static propTypes = {
     onClick: PropTypes.func.isRequired,
@@ -15,5 +15,3 @@ class ClearColumnButton extends React.Component {
   }
 
 }
-
-export default ClearColumnButton;
diff --git a/app/javascript/mastodon/features/notifications/components/column_settings.js b/app/javascript/mastodon/features/notifications/components/column_settings.js
index 2051e0c8635dfaa2d9615d074ffc606a0d6dad37..26059489477f8f19fa44920e0e1aa06a87417386 100644
--- a/app/javascript/mastodon/features/notifications/components/column_settings.js
+++ b/app/javascript/mastodon/features/notifications/components/column_settings.js
@@ -5,7 +5,7 @@ import { FormattedMessage } from 'react-intl';
 import ClearColumnButton from './clear_column_button';
 import SettingToggle from './setting_toggle';
 
-class ColumnSettings extends React.PureComponent {
+export default class ColumnSettings extends React.PureComponent {
 
   static propTypes = {
     settings: ImmutablePropTypes.map.isRequired,
@@ -63,5 +63,3 @@ class ColumnSettings extends React.PureComponent {
   }
 
 }
-
-export default ColumnSettings;
diff --git a/app/javascript/mastodon/features/notifications/components/notification.js b/app/javascript/mastodon/features/notifications/components/notification.js
index ede37f66a3c67c3c445e6ea5e8b2ca63f81b7766..9d631644a02417000c3a34c08d46c84981f59500 100644
--- a/app/javascript/mastodon/features/notifications/components/notification.js
+++ b/app/javascript/mastodon/features/notifications/components/notification.js
@@ -8,7 +8,7 @@ import emojify from '../../../emoji';
 import escapeTextContentForBrowser from 'escape-html';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 
-class Notification extends ImmutablePureComponent {
+export default class Notification extends ImmutablePureComponent {
 
   static propTypes = {
     notification: ImmutablePropTypes.map.isRequired,
@@ -86,5 +86,3 @@ class Notification extends ImmutablePureComponent {
   }
 
 }
-
-export default Notification;
diff --git a/app/javascript/mastodon/features/notifications/components/setting_toggle.js b/app/javascript/mastodon/features/notifications/components/setting_toggle.js
index 8707a993e9e974a80427c1db1bd8e8ac3a70045b..5108203587f3303dc8a6ae7299813d710be34055 100644
--- a/app/javascript/mastodon/features/notifications/components/setting_toggle.js
+++ b/app/javascript/mastodon/features/notifications/components/setting_toggle.js
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import Toggle from 'react-toggle';
 
-class SettingToggle extends React.PureComponent {
+export default class SettingToggle extends React.PureComponent {
 
   static propTypes = {
     prefix: PropTypes.string,
@@ -30,5 +30,3 @@ class SettingToggle extends React.PureComponent {
   }
 
 }
-
-export default SettingToggle;
diff --git a/app/javascript/mastodon/features/notifications/index.js b/app/javascript/mastodon/features/notifications/index.js
index b85d6d692fa5239acdd75a2711575c110b469419..1dd1b9a71a77cd3975ed1da5f0d041f127832c07 100644
--- a/app/javascript/mastodon/features/notifications/index.js
+++ b/app/javascript/mastodon/features/notifications/index.js
@@ -30,7 +30,9 @@ const mapStateToProps = state => ({
   hasMore: !!state.getIn(['notifications', 'next']),
 });
 
-class Notifications extends React.PureComponent {
+@connect(mapStateToProps)
+@injectIntl
+export default class Notifications extends React.PureComponent {
 
   static propTypes = {
     columnId: PropTypes.string,
@@ -173,5 +175,3 @@ class Notifications extends React.PureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(injectIntl(Notifications));
diff --git a/app/javascript/mastodon/features/public_timeline/index.js b/app/javascript/mastodon/features/public_timeline/index.js
index 3de54ef8bc4b821c7c73d288b77fbbd2f70f3f26..c6cad02d6deb5e8a46e3d61d03bc45e4b418619a 100644
--- a/app/javascript/mastodon/features/public_timeline/index.js
+++ b/app/javascript/mastodon/features/public_timeline/index.js
@@ -27,7 +27,9 @@ const mapStateToProps = state => ({
   accessToken: state.getIn(['meta', 'access_token']),
 });
 
-class PublicTimeline extends React.PureComponent {
+@connect(mapStateToProps)
+@injectIntl
+export default class PublicTimeline extends React.PureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
@@ -141,5 +143,3 @@ class PublicTimeline extends React.PureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(injectIntl(PublicTimeline));
diff --git a/app/javascript/mastodon/features/reblogs/index.js b/app/javascript/mastodon/features/reblogs/index.js
index 13fd1b20e8b15dab301c47138fe024bc17a5b9da..dc940ae01a620ae71d3168d61529408743232562 100644
--- a/app/javascript/mastodon/features/reblogs/index.js
+++ b/app/javascript/mastodon/features/reblogs/index.js
@@ -14,7 +14,8 @@ const mapStateToProps = (state, props) => ({
   accountIds: state.getIn(['user_lists', 'reblogged_by', Number(props.params.statusId)]),
 });
 
-class Reblogs extends ImmutablePureComponent {
+@connect(mapStateToProps)
+export default class Reblogs extends ImmutablePureComponent {
 
   static propTypes = {
     params: PropTypes.object.isRequired,
@@ -57,5 +58,3 @@ class Reblogs extends ImmutablePureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(Reblogs);
diff --git a/app/javascript/mastodon/features/report/components/status_check_box.js b/app/javascript/mastodon/features/report/components/status_check_box.js
index a31eabc21a385008abbf14da933b26a7b19f84f4..6a1a84c28c0237f7c55f2604010b58a1446c14db 100644
--- a/app/javascript/mastodon/features/report/components/status_check_box.js
+++ b/app/javascript/mastodon/features/report/components/status_check_box.js
@@ -4,7 +4,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
 import emojify from '../../../emoji';
 import Toggle from 'react-toggle';
 
-class StatusCheckBox extends React.PureComponent {
+export default class StatusCheckBox extends React.PureComponent {
 
   static propTypes = {
     status: ImmutablePropTypes.map.isRequired,
@@ -36,5 +36,3 @@ class StatusCheckBox extends React.PureComponent {
   }
 
 }
-
-export default StatusCheckBox;
diff --git a/app/javascript/mastodon/features/report/index.js b/app/javascript/mastodon/features/report/index.js
index 0a52684303c40151699a3f7c6338dd5aa28e5654..bfb09e193dce59bbcf2ce72f49f4c7dd260a00b5 100644
--- a/app/javascript/mastodon/features/report/index.js
+++ b/app/javascript/mastodon/features/report/index.js
@@ -35,7 +35,9 @@ const makeMapStateToProps = () => {
   return mapStateToProps;
 };
 
-class Report extends React.PureComponent {
+@connect(makeMapStateToProps)
+@injectIntl
+export default class Report extends React.PureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -121,5 +123,3 @@ class Report extends React.PureComponent {
   }
 
 }
-
-export default connect(makeMapStateToProps)(injectIntl(Report));
diff --git a/app/javascript/mastodon/features/status/components/action_bar.js b/app/javascript/mastodon/features/status/components/action_bar.js
index 21c2fd68226bc4b1067a9242a553a3ccee75e5f9..29080529df39daaa8e69affa0134fe012bd814b5 100644
--- a/app/javascript/mastodon/features/status/components/action_bar.js
+++ b/app/javascript/mastodon/features/status/components/action_bar.js
@@ -15,7 +15,8 @@ const messages = defineMessages({
   report: { id: 'status.report', defaultMessage: 'Report @{name}' },
 });
 
-class ActionBar extends React.PureComponent {
+@injectIntl
+export default class ActionBar extends React.PureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -91,5 +92,3 @@ class ActionBar extends React.PureComponent {
   }
 
 }
-
-export default injectIntl(ActionBar);
diff --git a/app/javascript/mastodon/features/status/components/card.js b/app/javascript/mastodon/features/status/components/card.js
index 415587d6e1abe7b59518de2d197bd46ad95d75ba..bfb40468bd7bf3a417d2d1328947ff2712c88749 100644
--- a/app/javascript/mastodon/features/status/components/card.js
+++ b/app/javascript/mastodon/features/status/components/card.js
@@ -17,7 +17,7 @@ const getHostname = url => {
   return parser.hostname;
 };
 
-class Card extends React.PureComponent {
+export default class Card extends React.PureComponent {
 
   static propTypes = {
     card: ImmutablePropTypes.map,
@@ -97,5 +97,3 @@ class Card extends React.PureComponent {
   }
 
 }
-
-export default Card;
diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js
index a77c4f0bbf87350cee540f9a34d8a654d8f3ef5d..619957dbe7d2a4821c8b30f0a2baffffb2197a7a 100644
--- a/app/javascript/mastodon/features/status/components/detailed_status.js
+++ b/app/javascript/mastodon/features/status/components/detailed_status.js
@@ -12,7 +12,7 @@ import { FormattedDate, FormattedNumber } from 'react-intl';
 import CardContainer from '../containers/card_container';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 
-class DetailedStatus extends ImmutablePureComponent {
+export default class DetailedStatus extends ImmutablePureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -87,5 +87,3 @@ class DetailedStatus extends ImmutablePureComponent {
   }
 
 }
-
-export default DetailedStatus;
diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js
index afd8a781189494489c73b9ce40e397532919083f..cbabdd5bc7d74a1c7a01360d86239106b531b574 100644
--- a/app/javascript/mastodon/features/status/index.js
+++ b/app/javascript/mastodon/features/status/index.js
@@ -48,7 +48,9 @@ const makeMapStateToProps = () => {
   return mapStateToProps;
 };
 
-class Status extends ImmutablePureComponent {
+@injectIntl
+@connect(makeMapStateToProps)
+export default class Status extends ImmutablePureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -195,5 +197,3 @@ class Status extends ImmutablePureComponent {
   }
 
 }
-
-export default injectIntl(connect(makeMapStateToProps)(Status));
diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.js b/app/javascript/mastodon/features/ui/components/boost_modal.js
index 9a8b96333d84e885d51fd2238649902c2f34adca..6c80a10844a7e105cf77a48813d31c64b7558abd 100644
--- a/app/javascript/mastodon/features/ui/components/boost_modal.js
+++ b/app/javascript/mastodon/features/ui/components/boost_modal.js
@@ -13,7 +13,8 @@ const messages = defineMessages({
   reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
 });
 
-class BoostModal extends ImmutablePureComponent {
+@injectIntl
+export default class BoostModal extends ImmutablePureComponent {
 
   static contextTypes = {
     router: PropTypes.object,
@@ -81,5 +82,3 @@ class BoostModal extends ImmutablePureComponent {
   }
 
 }
-
-export default injectIntl(BoostModal);
diff --git a/app/javascript/mastodon/features/ui/components/column.js b/app/javascript/mastodon/features/ui/components/column.js
index 970d625b099a55de80888c7f6efbc803ce633693..ce1dca171ef9043a021eabffa6d170d92b42a0f4 100644
--- a/app/javascript/mastodon/features/ui/components/column.js
+++ b/app/javascript/mastodon/features/ui/components/column.js
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
 import { debounce } from 'lodash';
 import scrollTop from '../../../scroll';
 
-class Column extends React.PureComponent {
+export default class Column extends React.PureComponent {
 
   static propTypes = {
     heading: PropTypes.string,
@@ -59,5 +59,3 @@ class Column extends React.PureComponent {
   }
 
 }
-
-export default Column;
diff --git a/app/javascript/mastodon/features/ui/components/column_header.js b/app/javascript/mastodon/features/ui/components/column_header.js
index 578432fec497bb99a47b54106a50a5144eaf9be6..dc601d6e1c097c0c2e398d0d70a177d67d2edce1 100644
--- a/app/javascript/mastodon/features/ui/components/column_header.js
+++ b/app/javascript/mastodon/features/ui/components/column_header.js
@@ -1,7 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 
-class ColumnHeader extends React.PureComponent {
+export default class ColumnHeader extends React.PureComponent {
 
   static propTypes = {
     icon: PropTypes.string,
@@ -34,5 +34,3 @@ class ColumnHeader extends React.PureComponent {
   }
 
 }
-
-export default ColumnHeader;
diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.js
index 43be3484083f02cd40ad745015c5d3c3f9177a4d..3c3e9425d36b5a7a387d5cb571820dd575b8809b 100644
--- a/app/javascript/mastodon/features/ui/components/columns_area.js
+++ b/app/javascript/mastodon/features/ui/components/columns_area.js
@@ -20,7 +20,7 @@ const componentMap = {
   'HASHTAG': HashtagTimeline,
 };
 
-class ColumnsArea extends ImmutablePureComponent {
+export default class ColumnsArea extends ImmutablePureComponent {
 
   static contextTypes = {
     router: PropTypes.object.isRequired,
@@ -73,5 +73,3 @@ class ColumnsArea extends ImmutablePureComponent {
   }
 
 }
-
-export default ColumnsArea;
diff --git a/app/javascript/mastodon/features/ui/components/confirmation_modal.js b/app/javascript/mastodon/features/ui/components/confirmation_modal.js
index a45c220faf20d7d7535f56e9896ce09ae4000bfd..86588c46a23ed869f425d1bb02ba76b1251864ca 100644
--- a/app/javascript/mastodon/features/ui/components/confirmation_modal.js
+++ b/app/javascript/mastodon/features/ui/components/confirmation_modal.js
@@ -3,7 +3,8 @@ import PropTypes from 'prop-types';
 import { injectIntl, FormattedMessage } from 'react-intl';
 import Button from '../../../components/button';
 
-class ConfirmationModal extends React.PureComponent {
+@injectIntl
+export default class ConfirmationModal extends React.PureComponent {
 
   static propTypes = {
     message: PropTypes.node.isRequired,
@@ -50,5 +51,3 @@ class ConfirmationModal extends React.PureComponent {
   }
 
 }
-
-export default injectIntl(ConfirmationModal);
diff --git a/app/javascript/mastodon/features/ui/components/image_loader.js b/app/javascript/mastodon/features/ui/components/image_loader.js
index 94bf55badbbb316d5e489fdace8dbaf665d062c4..5c3879970eb6d84c7ea6a67c678acca0c82fb772 100644
--- a/app/javascript/mastodon/features/ui/components/image_loader.js
+++ b/app/javascript/mastodon/features/ui/components/image_loader.js
@@ -1,7 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 
-class ImageLoader extends React.PureComponent {
+export default class ImageLoader extends React.PureComponent {
 
   static propTypes = {
     alt: PropTypes.string,
@@ -65,5 +65,3 @@ class ImageLoader extends React.PureComponent {
   }
 
 }
-
-export default ImageLoader;
diff --git a/app/javascript/mastodon/features/ui/components/media_modal.js b/app/javascript/mastodon/features/ui/components/media_modal.js
index 0209bc99b231f288ee39d1ccbde4bb44345f4377..8bb81ca01d15da14ecb18d5483222c29b8d819f5 100644
--- a/app/javascript/mastodon/features/ui/components/media_modal.js
+++ b/app/javascript/mastodon/features/ui/components/media_modal.js
@@ -12,7 +12,8 @@ const messages = defineMessages({
   close: { id: 'lightbox.close', defaultMessage: 'Close' },
 });
 
-class MediaModal extends ImmutablePureComponent {
+@injectIntl
+export default class MediaModal extends ImmutablePureComponent {
 
   static propTypes = {
     media: ImmutablePropTypes.list.isRequired,
@@ -95,5 +96,3 @@ class MediaModal extends ImmutablePureComponent {
   }
 
 }
-
-export default injectIntl(MediaModal);
diff --git a/app/javascript/mastodon/features/ui/components/modal_root.js b/app/javascript/mastodon/features/ui/components/modal_root.js
index 0f68cfbdf77de06c053238d1297a293999c19cce..2e4f9876d9d3ba71a30322d43624492065c3ec2d 100644
--- a/app/javascript/mastodon/features/ui/components/modal_root.js
+++ b/app/javascript/mastodon/features/ui/components/modal_root.js
@@ -16,7 +16,7 @@ const MODAL_COMPONENTS = {
   'CONFIRM': ConfirmationModal,
 };
 
-class ModalRoot extends React.PureComponent {
+export default class ModalRoot extends React.PureComponent {
 
   static propTypes = {
     type: PropTypes.string,
@@ -87,5 +87,3 @@ class ModalRoot extends React.PureComponent {
   }
 
 }
-
-export default ModalRoot;
diff --git a/app/javascript/mastodon/features/ui/components/onboarding_modal.js b/app/javascript/mastodon/features/ui/components/onboarding_modal.js
index 27959916999e7659e7928ff5f94e38595fe9872c..d2e02d63b417e7007cae5b7c20d09a48339ed30c 100644
--- a/app/javascript/mastodon/features/ui/components/onboarding_modal.js
+++ b/app/javascript/mastodon/features/ui/components/onboarding_modal.js
@@ -167,7 +167,9 @@ const mapStateToProps = state => ({
   domain: state.getIn(['meta', 'domain']),
 });
 
-class OnboardingModal extends React.PureComponent {
+@connect(mapStateToProps)
+@injectIntl
+export default class OnboardingModal extends React.PureComponent {
 
   static propTypes = {
     onClose: PropTypes.func.isRequired,
@@ -322,5 +324,3 @@ class OnboardingModal extends React.PureComponent {
   }
 
 }
-
-export default connect(mapStateToProps)(injectIntl(OnboardingModal));
diff --git a/app/javascript/mastodon/features/ui/components/tabs_bar.js b/app/javascript/mastodon/features/ui/components/tabs_bar.js
index 09acee0670c449364b1ff91c1875c3f70f3edeeb..c2e6c88b5167cce7040fc845d655965ae760d57e 100644
--- a/app/javascript/mastodon/features/ui/components/tabs_bar.js
+++ b/app/javascript/mastodon/features/ui/components/tabs_bar.js
@@ -33,7 +33,7 @@ export function getNextLink (path) {
   return null;
 };
 
-class TabsBar extends React.Component {
+export default class TabsBar extends React.Component {
 
   render () {
     return (
@@ -44,5 +44,3 @@ class TabsBar extends React.Component {
   }
 
 }
-
-export default TabsBar;
diff --git a/app/javascript/mastodon/features/ui/components/upload_area.js b/app/javascript/mastodon/features/ui/components/upload_area.js
index c40fe1fb92283643a35dc0662af38e57b621c293..030c3db2efe0dbe9171404791eb499578b58a746 100644
--- a/app/javascript/mastodon/features/ui/components/upload_area.js
+++ b/app/javascript/mastodon/features/ui/components/upload_area.js
@@ -4,7 +4,7 @@ import Motion from 'react-motion/lib/Motion';
 import spring from 'react-motion/lib/spring';
 import { FormattedMessage } from 'react-intl';
 
-class UploadArea extends React.PureComponent {
+export default class UploadArea extends React.PureComponent {
 
   static propTypes = {
     active: PropTypes.bool,
@@ -51,5 +51,3 @@ class UploadArea extends React.PureComponent {
   }
 
 }
-
-export default UploadArea;
diff --git a/app/javascript/mastodon/features/ui/components/video_modal.js b/app/javascript/mastodon/features/ui/components/video_modal.js
index 3599ab775acebf226452d93632d3837612a7cdc2..9a9a49dfb91d3f39a101baeaa7f45fe41aede52b 100644
--- a/app/javascript/mastodon/features/ui/components/video_modal.js
+++ b/app/javascript/mastodon/features/ui/components/video_modal.js
@@ -10,7 +10,8 @@ const messages = defineMessages({
   close: { id: 'lightbox.close', defaultMessage: 'Close' },
 });
 
-class VideoModal extends ImmutablePureComponent {
+@injectIntl
+export default class VideoModal extends ImmutablePureComponent {
 
   static propTypes = {
     media: ImmutablePropTypes.map.isRequired,
@@ -35,5 +36,3 @@ class VideoModal extends ImmutablePureComponent {
   }
 
 }
-
-export default injectIntl(VideoModal);
diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js
index e48e9dbe995c4dbe5bffe3996c72a786817ee714..8453679b050c901e027c0ebf32e1416f22534f09 100644
--- a/app/javascript/mastodon/features/ui/index.js
+++ b/app/javascript/mastodon/features/ui/index.js
@@ -74,7 +74,8 @@ class WrappedRoute extends React.Component {
 
 }
 
-class UI extends React.PureComponent {
+@connect()
+export default class UI extends React.PureComponent {
 
   static propTypes = {
     dispatch: PropTypes.func.isRequired,
@@ -219,5 +220,3 @@ class UI extends React.PureComponent {
   }
 
 }
-
-export default connect()(UI);
diff --git a/package.json b/package.json
index dc08fc10677c6d099bffe043456755ad36ae6292..2e89b5c0a2c8c4fe8f0a1543f083b9ef8242d02a 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
     "babel-plugin-react-transform": "^2.0.2",
     "babel-plugin-syntax-dynamic-import": "^6.18.0",
     "babel-plugin-transform-class-properties": "^6.24.1",
+    "babel-plugin-transform-decorators-legacy": "^1.3.4",
     "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
     "babel-plugin-transform-object-rest-spread": "^6.23.0",
     "babel-plugin-transform-react-jsx-self": "^6.22.0",
diff --git a/yarn.lock b/yarn.lock
index 85de4b546bc20701fc22d582a78ff080acd32081..00dff65c83089e6f9a4ccc34637ddf6c2e3b1756 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -717,7 +717,7 @@ babel-plugin-syntax-class-properties@^6.8.0:
   version "6.13.0"
   resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de"
 
-babel-plugin-syntax-decorators@^6.13.0:
+babel-plugin-syntax-decorators@^6.1.18, babel-plugin-syntax-decorators@^6.13.0:
   version "6.13.0"
   resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b"
 
@@ -790,6 +790,14 @@ babel-plugin-transform-class-properties@6.24.1, babel-plugin-transform-class-pro
     babel-runtime "^6.22.0"
     babel-template "^6.24.1"
 
+babel-plugin-transform-decorators-legacy@^1.3.4:
+  version "1.3.4"
+  resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators-legacy/-/babel-plugin-transform-decorators-legacy-1.3.4.tgz#741b58f6c5bce9e6027e0882d9c994f04f366925"
+  dependencies:
+    babel-plugin-syntax-decorators "^6.1.18"
+    babel-runtime "^6.2.0"
+    babel-template "^6.3.0"
+
 babel-plugin-transform-decorators@^6.24.1:
   version "6.24.1"
   resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d"
@@ -1270,7 +1278,7 @@ babel-runtime@6.x.x, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime
     core-js "^2.4.0"
     regenerator-runtime "^0.10.0"
 
-babel-template@^6.24.1, babel-template@^6.25.0:
+babel-template@^6.24.1, babel-template@^6.25.0, babel-template@^6.3.0:
   version "6.25.0"
   resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071"
   dependencies: