diff --git a/ui/package-lock.json b/ui/package-lock.json
index e036337..693c4dc 100644
--- a/ui/package-lock.json
+++ b/ui/package-lock.json
@@ -3262,6 +3262,16 @@
         "babel-runtime": "^6.26.0"
       }
     },
+    "babel-plugin-transform-semantic-ui-react-imports": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/babel-plugin-transform-semantic-ui-react-imports/-/babel-plugin-transform-semantic-ui-react-imports-1.4.1.tgz",
+      "integrity": "sha512-iUt6PVoscvNKzxLqezFpWT0xYcqcyTVOJITTxI35RSavtJNo2vXTilJbIALC+3oeUqknSwrznjgruHmRZA0f2w==",
+      "dev": true,
+      "requires": {
+        "colors": "^1.1.2",
+        "directory-tree": "^2.0.0"
+      }
+    },
     "babel-runtime": {
       "version": "6.26.0",
       "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
@@ -3896,6 +3906,12 @@
         "simple-swizzle": "^0.2.2"
       }
     },
+    "colors": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+      "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
+      "dev": true
+    },
     "combined-stream": {
       "version": "1.0.8",
       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -4566,6 +4582,12 @@
         "randombytes": "^2.0.0"
       }
     },
+    "directory-tree": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/directory-tree/-/directory-tree-2.2.4.tgz",
+      "integrity": "sha512-2N43msQptKbi3WMfIs+U09yi6bfyKL+MWyj5VMj8t1F/Tx04bt1cn/EEIU3o1JBltlJk7NQnzOEuTNa/KQvbWA==",
+      "dev": true
+    },
     "doctrine": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
diff --git a/ui/package.json b/ui/package.json
index f94c4b2..d44c0eb 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -17,7 +17,6 @@
     "downloadjs": "^1.4.7",
     "graphql": "^15.0.0",
     "graphql-tag": "^2.10.3",
-    "lodash": "^4.17.15",
     "parcel-bundler": "^1.12.4",
     "prop-types": "^15.7.2",
     "react": "^16.13.1",
@@ -35,16 +34,14 @@
   },
   "scripts": {
     "start": "parcel start src/index.html",
-    "build": "parcel build src/index.html",
-    "test": "react-scripts test --env=jsdom",
-    "eject": "react-scripts eject",
-    "now-build": "react-scripts build"
+    "build": "parcel build src/index.html --no-source-maps"
   },
   "devDependencies": {
     "@babel/core": "^7.9.0",
     "@babel/plugin-transform-runtime": "^7.9.0",
     "babel-eslint": "^10.1.0",
     "babel-plugin-graphql-tag": "^2.5.0",
+    "babel-plugin-transform-semantic-ui-react-imports": "^1.4.1",
     "eslint": "^6.8.0",
     "eslint-plugin-react": "^7.19.0",
     "eslint-plugin-react-hooks": "^3.0.0",
@@ -79,9 +76,16 @@
       ]
     ],
     "plugins": [
-      "babel-plugin-styled-components",
+      "styled-components",
       "@babel/plugin-transform-runtime",
-      "graphql-tag"
+      "graphql-tag",
+      [
+        "transform-semantic-ui-react-imports",
+        {
+          "convertMemberImports": true,
+          "addCssImports": true
+        }
+      ]
     ]
   },
   "lint-staged": {
diff --git a/ui/src/App.js b/ui/src/App.js
index 8e644ad..73bf322 100644
--- a/ui/src/App.js
+++ b/ui/src/App.js
@@ -11,6 +11,9 @@ const GlobalStyle = createGlobalStyle`
   }
 `
 
+import 'semantic-ui-css/components/reset.css'
+import 'semantic-ui-css/components/site.css'
+
 class App extends Component {
   render() {
     return (
diff --git a/ui/src/components/header/Searchbar.js b/ui/src/components/header/Searchbar.js
index 5f714df..391aaa7 100644
--- a/ui/src/components/header/Searchbar.js
+++ b/ui/src/components/header/Searchbar.js
@@ -1,9 +1,9 @@
-import React, { useState } from 'react'
+import React, { useState, useRef, useEffect } from 'react'
 import PropTypes from 'prop-types'
 import styled from 'styled-components'
 import { useLazyQuery } from '@apollo/react-hooks'
 import gql from 'graphql-tag'
-import debounce from 'lodash/debounce'
+import debounce from '../../debounce'
 import ProtectedImage from '../photoGallery/ProtectedImage'
 import { NavLink } from 'react-router-dom'
 
@@ -82,21 +82,25 @@ const SearchBar = () => {
   const [query, setQuery] = useState('')
   const [fetched, setFetched] = useState(false)
 
-  let debouncedFetch = null
+  let debouncedFetch = useRef(null)
+  useEffect(() => {
+    debouncedFetch.current = debounce(query => {
+      console.log('searching', query)
+      fetchSearches({ variables: { query } })
+      setFetched(true)
+    }, 250)
+
+    return () => {
+      debouncedFetch.current.cancel()
+    }
+  }, [])
+
   const fetchEvent = e => {
     e.persist()
 
-    if (!debouncedFetch) {
-      debouncedFetch = debounce(() => {
-        console.log('searching', e.target.value.trim())
-        fetchSearches({ variables: { query: e.target.value.trim() } })
-        setFetched(true)
-      }, 250)
-    }
-
     setQuery(e.target.value)
     if (e.target.value.trim() != '') {
-      debouncedFetch()
+      debouncedFetch.current(e.target.value.trim())
     } else {
       setFetched(false)
     }
diff --git a/ui/src/components/photoGallery/presentView/PresentNavigationOverlay.js b/ui/src/components/photoGallery/presentView/PresentNavigationOverlay.js
index 3f9e2bd..cc41602 100644
--- a/ui/src/components/photoGallery/presentView/PresentNavigationOverlay.js
+++ b/ui/src/components/photoGallery/presentView/PresentNavigationOverlay.js
@@ -1,7 +1,7 @@
-import React, { useState, useRef } from 'react'
+import React, { useState, useRef, useEffect } from 'react'
 import PropTypes from 'prop-types'
 import styled from 'styled-components'
-import debounce from 'lodash/debounce'
+import debounce from '../../../debounce'
 
 import ExitIcon from './icons/Exit'
 import NextIcon from './icons/Next'
@@ -63,25 +63,35 @@ const NavigationButton = styled(OverlayButton)`
   }
 `
 
-const mouseMoveEvent = ({ setHide }) =>
-  debounce(
-    event => {
-      setHide(hide => !hide)
-    },
-    2000,
-    { leading: true, trailing: true }
-  )
-
 const PresentNavigationOverlay = ({
   nextImage,
   previousImage,
   setPresenting,
 }) => {
   const [hide, setHide] = useState(true)
-  const onMouseMove = useRef(mouseMoveEvent({ hide, setHide }))
+  const onMouseMove = useRef(null)
+
+  useEffect(() => {
+    console.log('Setup mouse move')
+    onMouseMove.current = debounce(
+      () => {
+        setHide(hide => !hide)
+      },
+      2000,
+      true
+    )
+
+    return () => {
+      onMouseMove.current.cancel()
+    }
+  }, [])
 
   return (
-    <StyledOverlayContainer onMouseMove={onMouseMove.current}>
+    <StyledOverlayContainer
+      onMouseMove={() => {
+        onMouseMove.current()
+      }}
+    >
       <NavigationButton
         className={hide && 'hide'}
         float="left"
diff --git a/ui/src/debounce.js b/ui/src/debounce.js
new file mode 100644
index 0000000..03cfd31
--- /dev/null
+++ b/ui/src/debounce.js
@@ -0,0 +1,24 @@
+export default function debounce(func, wait, triggerRising) {
+  let timeout = null
+
+  const debounced = (...args) => {
+    if (timeout) {
+      clearTimeout(timeout)
+      timeout = null
+    } else if (triggerRising) {
+      func(...args)
+    }
+
+    timeout = setTimeout(() => {
+      timeout = null
+      func(...args)
+    }, wait)
+  }
+
+  debounced.cancel = () => {
+    clearTimeout(timeout)
+    timeout = null
+  }
+
+  return debounced
+}
diff --git a/ui/src/index.js b/ui/src/index.js
index 416d7b2..20eae31 100644
--- a/ui/src/index.js
+++ b/ui/src/index.js
@@ -6,8 +6,6 @@ import client from './apolloClient'
 import { ApolloProvider } from 'react-apollo'
 import { BrowserRouter as Router } from 'react-router-dom'
 
-import 'semantic-ui-css/semantic.min.css'
-
 const Main = () => (
   <ApolloProvider client={client}>
     <Router>
