diff --git a/frontend/src/app.js b/frontend/src/app.js
index 87fd80da5a0c4b3c80fe8a415ace3334fd4ae8bd..f9eeab836d8b294dd4b384ef77d8eb13933596b2 100644
--- a/frontend/src/app.js
+++ b/frontend/src/app.js
@@ -14,7 +14,6 @@ import { registerAnalyticsClickListener } from "metabase/lib/analytics";
 var Metabase = angular.module('metabase', [
     'ngRoute',
     'ngCookies',
-    'ui.bootstrap', // bootstrap LIKE widgets via angular directives
     'metabase.auth',
     'metabase.filters',
     'metabase.directives',
diff --git a/frontend/src/card/card.directives.js b/frontend/src/card/card.directives.js
deleted file mode 100644
index daaab51ea0067b3d505732d4cc2e9c833b0f383e..0000000000000000000000000000000000000000
--- a/frontend/src/card/card.directives.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/*global setTimeout */
-
-var CardDirectives = angular.module('metabase.card.directives', []);
-
-CardDirectives.directive('mbCardFavoriteButton', ['Card', function(Card) {
-
-    function link(scope, element, attr) {
-        scope.favorite = false;
-
-        scope.$watch('cardId', function(value) {
-            if (value) {
-                initialize();
-            }
-        });
-
-        var initialize = function() {
-            // initialize the current favorite status
-            Card.isfavorite({
-                'cardId': scope.cardId
-            }, function(result) {
-                if (result && !result.error) {
-                    if (result.favorite === true) {
-                        scope.favorite = true;
-                    }
-                } else {
-                    console.log(result);
-                }
-            });
-        };
-
-        scope.toggleFavorite = function() {
-
-            if (scope.favorite) {
-                // already favorited, lets unfavorite
-                Card.unfavorite({
-                    'cardId': scope.cardId
-                }, function(result) {
-                    if (result && !result.error) {
-                        scope.favorite = false;
-                    }
-                });
-            } else {
-                // currently not favorited, lets favorite
-                Card.favorite({
-                    'cardId': scope.cardId
-                }, function(result) {
-                    if (result && !result.error) {
-                        scope.favorite = true;
-                    }
-                });
-            }
-        };
-    }
-
-    return {
-        restrict: 'E',
-        replace: true,
-        templateUrl: '/app/card/partials/_card_favorite.html',
-        scope: {
-            cardId: '='
-        },
-        link: link
-    };
-}]);
diff --git a/frontend/src/card/card.module.js b/frontend/src/card/card.module.js
index 82ddc6da672aa70d634721e8b9b7abb77c6493db..f012aeac8cab682e592533d4ff91284a5ecbce95 100644
--- a/frontend/src/card/card.module.js
+++ b/frontend/src/card/card.module.js
@@ -5,8 +5,7 @@ var Card = angular.module('metabase.card', [
     'metabase.filters',
     'metabase.directives',
     'metabase.services',
-    'metabase.card.controllers',
-    'metabase.card.directives'
+    'metabase.card.controllers'
 ]);
 
 Card.config(['$routeProvider', function($routeProvider) {
diff --git a/frontend/src/components/icons/icons.js b/frontend/src/components/icons/icons.js
index 07fe0afcc550cbea1d8e5e533e8988ed9e1afe9a..d2f33e5490def215acb7cf179c05d2b4eda60b1d 100644
--- a/frontend/src/components/icons/icons.js
+++ b/frontend/src/components/icons/icons.js
@@ -67,14 +67,4 @@ angular.module('metabase.components')
             };
         });
 
-    angular.module('metabase.components')
-        .directive('mbLoadingIcon', function () {
-            return {
-                restrict: 'E',
-                templateUrl: '/app/components/icons/loading.html',
-                scope: ICON_SCOPE,
-                compile: iconCompile
-            };
-        });
-
 }());
diff --git a/frontend/src/controllers.js b/frontend/src/controllers.js
index 1ccda121efcbd90eb88a775c8a7259696c0366fb..fc29456c09dbae4a08557dc4af9510e49c31007b 100644
--- a/frontend/src/controllers.js
+++ b/frontend/src/controllers.js
@@ -2,7 +2,7 @@ import Navbar from 'metabase/components/Navbar.jsx';
 
 
 // Global Controllers
-var MetabaseControllers = angular.module('metabase.controllers', ['metabase.services', 'metabase.navbar.directives']);
+var MetabaseControllers = angular.module('metabase.controllers', ['metabase.services']);
 
 MetabaseControllers.controller('Metabase', ['$scope', '$location', 'MetabaseCore', 'AppState', function($scope, $location, MetabaseCore, AppState) {
 
diff --git a/frontend/src/directives.js b/frontend/src/directives.js
index b73d9623c7034e7030c5091d2506d83a44fa8a00..e673e00fb53525ab6d76486eff33b05fb792f6e9 100644
--- a/frontend/src/directives.js
+++ b/frontend/src/directives.js
@@ -4,27 +4,9 @@ import ReactDOM from "react-dom";
 import { Provider } from 'react-redux';
 import { DevTools, DebugPanel } from 'redux-devtools/lib/react';
 
-import ProfileLink from './components/ProfileLink.jsx'
-
 /* Directives */
 var MetabaseDirectives = angular.module('metabase.directives', []);
 
-MetabaseDirectives.directive('deleteConfirm', [function() {
-    return {
-        priority: 1,
-        terminal: true,
-        link: function(scope, element, attr) {
-            var msg = attr.ngConfirmClick || "Are you sure?";
-            var clickAction = attr.ngClick;
-            element.bind('click', function(event) {
-                if (window.confirm(msg)) {
-                    scope.$eval(clickAction);
-                }
-            });
-        }
-    };
-}]);
-
 MetabaseDirectives.directive('mbDelayedCall', ['$timeout', function($timeout) {
 
     function link(scope, element, attr) {
@@ -44,95 +26,6 @@ MetabaseDirectives.directive('mbDelayedCall', ['$timeout', function($timeout) {
     };
 }]);
 
-MetabaseDirectives.directive('mbScrollShadow', [function (){
-    return {
-        restrict: 'A',
-        link: function (scope, element, attr) {
-            // grab the raw dom element to check its scroll top
-            var raw = element[0];
-            element.on('scroll', function () {
-                if(raw.scrollTop > 0) {
-                    element.addClass('ScrollShadow');
-                } else {
-                    element.removeClass('ScrollShadow');
-                }
-            });
-        }
-    };
-}]);
-
-MetabaseDirectives.directive('mbActionButton', ['$timeout', '$compile', function ($timeout, $compile) {
-
-    return {
-        restrict: 'A',
-        scope: {
-            actionFunction: '=mbActionButton'
-        },
-        link: function link(scope, element, attr) {
-
-            var defaultText = element.text();
-            var activeText = attr.activeText;
-            var failedText = attr.failedText;
-            var successText = attr.successText;
-
-            var fnArg = attr.fnArg;
-
-            var delayedReset = function() {
-                // do we need to have this timeout be configurable?
-                $timeout(function () {
-                    element.text(defaultText);
-                    element.removeClass('Button--waiting');
-                    element.removeClass('Button--success');
-                    element.removeClass('Button--danger');
-                    element.removeAttr('disabled');
-                }, 5000);
-            };
-
-            element.bind('click', function (event) {
-                element.text(activeText);
-                element.addClass('Button--waiting');
-
-                // activate spinner
-                var loadingIcon = angular.element('<mb-loading-icon width="12px" height="12px"></mb-loading-icon>');
-                element.append(loadingIcon);
-                $compile(loadingIcon)(scope);
-
-                // disable button
-                element.attr('disabled', 'true');
-
-                // NOTE: we are assuming the action function is a promise
-                var promise = (fnArg) ? scope.actionFunction(fnArg) : scope.actionFunction();
-
-                promise.then(function (result) {
-                    element.text(successText);
-                    element.removeClass('Button--waiting');
-                    element.addClass('Button--success');
-                    var checkIcon = angular.element('<mb-icon name="check" width="12px" height="12px"></mb-icon>');
-                    element.prepend(checkIcon);
-                    $compile(checkIcon)(scope);
-
-                    // re-activate button
-                    element.removeAttr('disabled');
-
-                    // timeout, reset to base
-                    delayedReset();
-
-                }, function (error) {
-                    element.text(failedText);
-                    element.removeClass('Button--waiting');
-                    element.addClass('Button--danger');
-
-                    // re-activate button
-                    element.removeAttr('disabled');
-
-                    // timeout, reset to base
-                    delayedReset();
-                });
-            });
-        }
-    };
-}]);
-
 MetabaseDirectives.directive('mbReduxComponent', ['$timeout', function ($timeout) {
     return {
         restrict: 'A',
@@ -219,20 +112,3 @@ MetabaseDirectives.directive('mbReactComponent', ['$timeout', function ($timeout
         }
     };
 }]);
-
-var NavbarDirectives = angular.module('metabase.navbar.directives', []);
-
-NavbarDirectives.directive('mbProfileLink', [function () {
-
-    return {
-        restrict: 'A',
-        template: '<div mb-react-component="ProfileLink"></div>',
-        controller: ['$scope', function ($scope) {
-            $scope.ProfileLink = ProfileLink;
-        }],
-        scope: {
-            context: '=',
-            user: '='
-        },
-    };
-}]);
diff --git a/frontend/test/unit/directives.spec.js b/frontend/test/unit/directives.spec.js
deleted file mode 100644
index ecb3fa0e27c79e4fe832916944dde8ec6a05e743..0000000000000000000000000000000000000000
--- a/frontend/test/unit/directives.spec.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import 'metabase/directives';
-
-describe('metabase.directives', function() {
-    beforeEach(angular.mock.module('metabase.directives'));
-
-    describe('mb-scroll-shadow', function() {
-        var element;
-        beforeEach(angular.mock.inject(function($compile, $rootScope) {
-            element = $compile('<div mb-scroll-shadow style="height: 10px; overflow-y: scroll;"><div style="height: 20px;">x</div></div>')($rootScope);
-            angular.element(document.body).append(element); // must be added to the body to scrolling stuff to work
-        }));
-
-        it('should not add the ScrollShadow class on scroll if scrollTop is 0', function() {
-            element[0].scrollTop = 0;
-            element.triggerHandler('scroll');
-            expect(element.hasClass('ScrollShadow')).toBe(false);
-        });
-
-        it('should add the ScrollShadow class if scrollTop is greater than 0', function() {
-            element[0].scrollTop = 5;
-            element.triggerHandler('scroll');
-            expect(element.hasClass('ScrollShadow')).toBe(true);
-        });
-
-        it('should remove the ScrollShadow class on scroll if scrollTop is 0', function() {
-            element.addClass('ScrollShadow');
-            element[0].scrollTop = 0;
-            element.triggerHandler('scroll');
-            expect(element.hasClass('ScrollShadow')).toBe(false);
-        });
-    })
-});
diff --git a/frontend/vendor.js b/frontend/vendor.js
index 132318bf05518d564a3b4b009258015749075103..c5a0d0ed8b5db74068234d84e158da8efcf9edc1 100644
--- a/frontend/vendor.js
+++ b/frontend/vendor.js
@@ -8,11 +8,9 @@ import 'angular-route';
 
 // angular 3rd-party:
 import 'angular-cookie';
-import 'angular-http-auth'; // currently pulled from unofficial fork: https://github.com/witoldsz/angular-http-auth/pull/100
-import 'angular-ui-bootstrap';
+import 'angular-http-auth';
 
 // ace:
-import 'angular-ui-ace';
 import 'ace/ace';
 import 'ace/ext-language_tools';
 import 'ace/mode-sql';
diff --git a/package.json b/package.json
index a6e31f5dd4563e5fe7212af265373e37ea071efa..4071fbef3b6b00595c9eeab0145ff0370dd7e022 100644
--- a/package.json
+++ b/package.json
@@ -17,8 +17,6 @@
     "angular-http-auth": "1.2.1",
     "angular-resource": "1.2.28",
     "angular-route": "1.2.28",
-    "angular-ui-ace": "0.2.3",
-    "angular-ui-bootstrap": "^0.12.1",
     "classnames": "^2.1.3",
     "crossfilter": "^1.3.12",
     "d3": "^3.5.14",
diff --git a/resources/frontend_client/app/card/partials/_card_favorite.html b/resources/frontend_client/app/card/partials/_card_favorite.html
deleted file mode 100644
index 9365d20151280589f5890244c25162d458759038..0000000000000000000000000000000000000000
--- a/resources/frontend_client/app/card/partials/_card_favorite.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<a href="#" title="Favorite This Question" class="animate-pop" ng-click="toggleFavorite()">
-    <mb-icon
-        name="star"
-        width="18px"
-        height="18px"
-        class="text-grey-1"
-        ng-class="{ 'text-grey-1 text-grey-3-hover' : !favorite,
-                    'text-gold': favorite,
-                    'transition-color': true
-                    }"
-    >
-    </mb-icon>
-</a>
diff --git a/resources/frontend_client/app/components/editor/editor.html b/resources/frontend_client/app/components/editor/editor.html
deleted file mode 100644
index 4119f4a3d5c5581ed322d4b46879b983f7c8f68b..0000000000000000000000000000000000000000
--- a/resources/frontend_client/app/components/editor/editor.html
+++ /dev/null
@@ -1 +0,0 @@
-<div class="my2 border-bottom" ng-model="sql" id="id_sql" rows="10" ui-ace="{ mode: 'sql', onLoad: aceLoaded }"></div>
diff --git a/resources/frontend_client/app/components/icons/loading.html b/resources/frontend_client/app/components/icons/loading.html
deleted file mode 100644
index 6f217985647b10d23b4d69e9e7d9f9a126ba9695..0000000000000000000000000000000000000000
--- a/resources/frontend_client/app/components/icons/loading.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<svg id="loading" viewBox="0 0 32 32" ng-attr-width="{{width}}" ng-attr-height="{height}}" fill="currentcolor">
-    <path opacity=".25" d="M16 0 A16 16 0 0 0 16 32 A16 16 0 0 0 16 0 M16 4 A12 12 0 0 1 16 28 A12 12 0 0 1 16 4"/>
-    <path d="M16 0 A16 16 0 0 1 32 16 L28 16 A12 12 0 0 0 16 4z">
-        <animateTransform attributeName="transform" type="rotate" from="0 16 16" to="360 16 16" dur="0.8s" repeatCount="indefinite" />
-    </path>
-</svg>