diff --git a/client/components/AudioPlayer.vue b/client/components/AudioPlayer.vue
index 4bb39c7dc..54bb1ec14 100644
--- a/client/components/AudioPlayer.vue
+++ b/client/components/AudioPlayer.vue
@@ -153,9 +153,6 @@ export default {
     },
     currentChapterName() {
       return this.currentChapter ? this.currentChapter.title : ''
-    },
-    showExperimentalFeatures() {
-      return this.$store.state.showExperimentalFeatures
     }
   },
   methods: {
diff --git a/client/components/app/SideRail.vue b/client/components/app/SideRail.vue
index 46e1c4cd5..c6b54c5a1 100644
--- a/client/components/app/SideRail.vue
+++ b/client/components/app/SideRail.vue
@@ -89,9 +89,6 @@ export default {
     offsetTop() {
       return 64
     },
-    showExperimentalFeatures() {
-      return this.$store.state.showExperimentalFeatures
-    },
     userIsAdminOrUp() {
       return this.$store.getters['user/getIsAdminOrUp']
     },
diff --git a/client/components/app/StreamContainer.vue b/client/components/app/StreamContainer.vue
index ea140a780..880490030 100644
--- a/client/components/app/StreamContainer.vue
+++ b/client/components/app/StreamContainer.vue
@@ -74,9 +74,6 @@ export default {
     }
   },
   computed: {
-    showExperimentalFeatures() {
-      return this.$store.state.showExperimentalFeatures
-    },
     coverAspectRatio() {
       return this.$store.getters['getServerSetting']('coverAspectRatio')
     },
diff --git a/client/components/cards/GroupCard.vue b/client/components/cards/GroupCard.vue
index 5b31ed0e6..ff12c5616 100644
--- a/client/components/cards/GroupCard.vue
+++ b/client/components/cards/GroupCard.vue
@@ -109,19 +109,14 @@ export default {
     hasValidCovers() {
       var validCovers = this.bookItems.map((bookItem) => bookItem.media.coverPath)
       return !!validCovers.length
-    },
-    showExperimentalFeatures() {
-      return this.$store.state.showExperimentalFeatures
     }
   },
   methods: {
     mouseoverCard() {
       this.isHovering = true
-      // if (this.$refs.groupcover) this.$refs.groupcover.setHover(true)
     },
     mouseleaveCard() {
       this.isHovering = false
-      // if (this.$refs.groupcover) this.$refs.groupcover.setHover(false)
     },
     clickCard() {
       this.$emit('click', this.group)
diff --git a/client/components/cards/LazyBookCard.vue b/client/components/cards/LazyBookCard.vue
index dda734740..34b0be60c 100644
--- a/client/components/cards/LazyBookCard.vue
+++ b/client/components/cards/LazyBookCard.vue
@@ -147,6 +147,9 @@ export default {
     showExperimentalFeatures() {
       return this.store.state.showExperimentalFeatures
     },
+    enableEReader() {
+      return this.store.getters['getServerSetting']('enableEReader')
+    },
     _libraryItem() {
       return this.libraryItem || {}
     },
@@ -287,13 +290,13 @@ export default {
       return this.store.getters['getlibraryItemIdStreaming'] === this.libraryItemId
     },
     showReadButton() {
-      return !this.isSelectionMode && this.showExperimentalFeatures && !this.showPlayButton && this.hasEbook
+      return !this.isSelectionMode && !this.showPlayButton && this.hasEbook && (this.showExperimentalFeatures || this.enableEReader)
     },
     showPlayButton() {
       return !this.isSelectionMode && !this.isMissing && !this.isInvalid && !this.isStreaming && (this.numTracks || this.recentEpisode)
     },
     showSmallEBookIcon() {
-      return !this.isSelectionMode && this.showExperimentalFeatures && this.hasEbook
+      return !this.isSelectionMode && this.hasEbook && (this.showExperimentalFeatures || this.enableEReader)
     },
     isMissing() {
       return this._libraryItem.isMissing
diff --git a/client/components/covers/GroupCover.vue b/client/components/covers/GroupCover.vue
index 015e539fe..671616f44 100644
--- a/client/components/covers/GroupCover.vue
+++ b/client/components/covers/GroupCover.vue
@@ -59,9 +59,6 @@ export default {
       if (this.bookCoverAspectRatio === 1) return this.width / (120 * 1.6 * 2)
       return this.width / 240
     },
-    showExperimentalFeatures() {
-      return this.store.state.showExperimentalFeatures
-    },
     store() {
       return this.$store || this.$nuxt.$store
     },
diff --git a/client/components/modals/item/EditModal.vue b/client/components/modals/item/EditModal.vue
index f4b33b9f6..548ddf4e7 100644
--- a/client/components/modals/item/EditModal.vue
+++ b/client/components/modals/item/EditModal.vue
@@ -64,8 +64,7 @@ export default {
         {
           id: 'manage',
           title: 'Manage',
-          component: 'modals-item-tabs-manage',
-          experimental: true
+          component: 'modals-item-tabs-manage'
         }
       ]
     }
diff --git a/client/components/modals/item/tabs/Manage.vue b/client/components/modals/item/tabs/Manage.vue
index de97ec495..644d3f44e 100644
--- a/client/components/modals/item/tabs/Manage.vue
+++ b/client/components/modals/item/tabs/Manage.vue
@@ -26,7 +26,7 @@
     
 
     
-    
+    
       
         
           Split M4B to MP3's
@@ -51,7 +51,7 @@
     
 
 
     
-    
+    
       
         
           Embed Metadata
@@ -113,6 +113,9 @@ export default {
     }
   },
   computed: {
+    showExperimentalFeatures() {
+      return this.$store.state.showExperimentalFeatures
+    },
     libraryItemId() {
       return this.libraryItem ? this.libraryItem.id : null
     },
diff --git a/client/pages/audiobook/_id/edit.vue b/client/pages/audiobook/_id/edit.vue
index d63e4eb8c..887391d8f 100644
--- a/client/pages/audiobook/_id/edit.vue
+++ b/client/pages/audiobook/_id/edit.vue
@@ -126,9 +126,6 @@ export default {
     }
   },
   computed: {
-    showExperimentalFeatures() {
-      return this.$store.state.showExperimentalFeatures
-    },
     media() {
       return this.libraryItem.media || {}
     },
diff --git a/client/pages/config/index.vue b/client/pages/config/index.vue
index b7e57ca65..87a5d9693 100644
--- a/client/pages/config/index.vue
+++ b/client/pages/config/index.vue
@@ -122,6 +122,20 @@
           
         
       
 
+
+      
+        
Experimental Feature Settings
+      
+
+      
+        
 updateSettingsKey('enableEReader', val)" />
+        
+          
+            Enable e-reader for all users
+            info_outlined
+          
+        
+       
      
 
     
@@ -169,10 +183,12 @@
         
           
@@ -207,6 +223,7 @@ export default {
       isPurgingCache: false,
       newServerSettings: {},
       tooltips: {
+        experimentalFeatures: 'Features in development that could use your feedback and help testing. Click to open github discussion.',
         scannerDisableWatcher: 'Disables the automatic adding/updating of items when file changes are detected. *Requires server restart',
         scannerPreferOpfMetadata: 'OPF file metadata will be used for book details over folder names',
         scannerPreferAudioMetadata: 'Audio file ID3 meta tags will be used for book details over folder names',
@@ -216,7 +233,8 @@ export default {
         bookshelfView: 'Alternative view without wooden bookshelf',
         storeCoverWithItem: 'By default covers are stored in /metadata/items, enabling this setting will store covers in your library item folder. Only one file named "cover" will be kept',
         storeMetadataWithItem: 'By default metadata files are stored in /metadata/items, enabling this setting will store metadata files in your library item folders. Uses .abs file extension',
-        coverAspectRatio: 'Prefer to use square covers over standard 1.6:1 book covers'
+        coverAspectRatio: 'Prefer to use square covers over standard 1.6:1 book covers',
+        enableEReader: 'E-reader is still a work in progress, but use this setting to open it up to all your users (or use the "Experimental Features" toggle below just for you)'
       },
       showConfirmPurgeCache: false
     }
@@ -229,9 +247,6 @@ export default {
     }
   },
   computed: {
-    experimentalFeaturesTooltip() {
-      return 'Features in development that could use your feedback and help testing.'
-    },
     serverSettings() {
       return this.$store.state.serverSettings
     },
diff --git a/client/pages/config/users/_id.vue b/client/pages/config/users/_id.vue
index 5b953ff00..b44bd9003 100644
--- a/client/pages/config/users/_id.vue
+++ b/client/pages/config/users/_id.vue
@@ -104,9 +104,6 @@ export default {
     bookCoverAspectRatio() {
       return this.coverAspectRatio === this.$constants.BookCoverAspectRatio.SQUARE ? 1 : 1.6
     },
-    showExperimentalFeatures() {
-      return this.$store.state.showExperimentalFeatures
-    },
     username() {
       return this.user.username
     },
diff --git a/client/pages/item/_id/index.vue b/client/pages/item/_id/index.vue
index 2b25d0a1c..c41087dcc 100644
--- a/client/pages/item/_id/index.vue
+++ b/client/pages/item/_id/index.vue
@@ -92,7 +92,8 @@
           
           
             warning_amber
-            
Book has no audio tracks but has valid ebook files. The e-reader is experimental and can be turned on in config.
+            
Book has no audio tracks but has an ebook. The experimental e-reader can be enabled in config.
+            
Book has no audio tracks but has an ebook. The experimental e-reader must be enabled by a server admin.
            
 
           
@@ -135,7 +136,7 @@
               {{ isMissing ? 'Missing' : 'Incomplete' }}
             
 
-            
+            
               auto_stories
               Read
             
@@ -223,6 +224,12 @@ export default {
     }
   },
   computed: {
+    showExperimentalFeatures() {
+      return this.$store.state.showExperimentalFeatures
+    },
+    enableEReader() {
+      return this.$store.getters['getServerSetting']('enableEReader')
+    },
     userIsAdminOrUp() {
       return this.$store.getters['user/getIsAdminOrUp']
     },
@@ -241,9 +248,6 @@ export default {
     isDeveloperMode() {
       return this.$store.state.developerMode
     },
-    showExperimentalFeatures() {
-      return this.$store.state.showExperimentalFeatures
-    },
     isPodcast() {
       return this.libraryItem.mediaType === 'podcast'
     },
@@ -262,6 +266,9 @@ export default {
       if (this.isPodcast) return this.podcastEpisodes.length
       return this.tracks.length
     },
+    showReadButton() {
+      return this.ebookFile && (this.showExperimentalFeatures || this.enableEReader)
+    },
     libraryId() {
       return this.libraryItem.libraryId
     },
@@ -342,7 +349,7 @@ export default {
       return this.media.ebookFile
     },
     showExperimentalReadAlert() {
-      return !this.tracks.length && this.ebookFile && !this.showExperimentalFeatures
+      return !this.tracks.length && this.ebookFile && !this.showExperimentalFeatures && !this.enableEReader
     },
     description() {
       return this.mediaMetadata.description || ''
diff --git a/package.json b/package.json
index acc1532a2..c1ddcffcf 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,11 @@
   "version": "2.0.15",
   "description": "Self-hosted audiobook and podcast server",
   "main": "index.js",
+  "watch": {
+    "dev": "server/{*,*/*}/*.js"
+  },
   "scripts": {
+    "watch": "npm-watch",
     "dev": "node index.js",
     "start": "node index.js",
     "client": "cd client && npm install && npm run generate",
@@ -53,5 +57,7 @@
     "watcher": "^1.2.0",
     "xml2js": "^0.4.23"
   },
-  "devDependencies": {}
-}
\ No newline at end of file
+  "devDependencies": {
+    "npm-watch": "^0.11.0"
+  }
+}
diff --git a/server/objects/settings/ServerSettings.js b/server/objects/settings/ServerSettings.js
index e1e20e12f..bea7b6edf 100644
--- a/server/objects/settings/ServerSettings.js
+++ b/server/objects/settings/ServerSettings.js
@@ -5,10 +5,6 @@ class ServerSettings {
   constructor(settings) {
     this.id = 'server-settings'
 
-    // Misc/Unused
-    this.autoTagNew = false
-    this.newTagExpireDays = 15
-
     // Scanner
     this.scannerParseSubtitle = false
     this.scannerFindCovers = false
@@ -43,11 +39,16 @@ class ServerSettings {
     // Podcasts
     this.podcastEpisodeSchedule = '0 * * * *' // Every hour
 
+    // Sorting
     this.sortingIgnorePrefix = false
     this.sortingPrefixes = ['the', 'a']
 
+    // Misc Flags
     this.chromecastEnabled = false
+    this.enableEReader = false
+
     this.logLevel = Logger.logLevel
+
     this.version = null
 
     if (settings) {
@@ -56,8 +57,6 @@ class ServerSettings {
   }
 
   construct(settings) {
-    this.autoTagNew = settings.autoTagNew
-    this.newTagExpireDays = settings.newTagExpireDays
     this.scannerFindCovers = !!settings.scannerFindCovers
     this.scannerCoverProvider = settings.scannerCoverProvider || 'google'
     this.scannerParseSubtitle = settings.scannerParseSubtitle
@@ -91,6 +90,7 @@ class ServerSettings {
     this.sortingIgnorePrefix = !!settings.sortingIgnorePrefix
     this.sortingPrefixes = settings.sortingPrefixes || ['the', 'a']
     this.chromecastEnabled = !!settings.chromecastEnabled
+    this.enableEReader = !!settings.enableEReader
     this.logLevel = settings.logLevel || Logger.logLevel
     this.version = settings.version || null
 
@@ -102,8 +102,6 @@ class ServerSettings {
   toJSON() {
     return {
       id: this.id,
-      autoTagNew: this.autoTagNew,
-      newTagExpireDays: this.newTagExpireDays,
       scannerFindCovers: this.scannerFindCovers,
       scannerCoverProvider: this.scannerCoverProvider,
       scannerParseSubtitle: this.scannerParseSubtitle,
@@ -125,6 +123,7 @@ class ServerSettings {
       sortingIgnorePrefix: this.sortingIgnorePrefix,
       sortingPrefixes: [...this.sortingPrefixes],
       chromecastEnabled: this.chromecastEnabled,
+      enableEReader: this.enableEReader,
       logLevel: this.logLevel,
       version: this.version
     }
diff --git a/server/utils/libraryHelpers.js b/server/utils/libraryHelpers.js
index 459e28e44..46ea9d1f9 100644
--- a/server/utils/libraryHelpers.js
+++ b/server/utils/libraryHelpers.js
@@ -418,7 +418,7 @@ module.exports = {
                   books: [libraryItemJson],
                   inProgress: bookInProgress,
                   bookInProgressLastUpdate: bookInProgress ? mediaProgress.lastUpdate : null,
-                  firstBookUnread: bookInProgress ? libraryItemJson : null
+                  firstBookUnread: bookInProgress ? null : libraryItemJson
                 }
                 seriesMap[librarySeries.id] = series