diff --git a/server.js b/server.js
index 7d06288..74bff78 100644
--- a/server.js
+++ b/server.js
@@ -1,12 +1,16 @@
-const path = require('path')
 const throng = require('throng')
-const { startServer } = require('./server/index')
+const createServer = require('./server/createServer')
 
 const port = parseInt(process.env.PORT, 10) || 5000
-const publicDir = path.resolve(__dirname, 'build')
 
 throng({
   workers: process.env.WEB_CONCURRENCY || 1,
-  start: (id) => startServer({ id, port, publicDir }),
-  lifetime: Infinity
+  lifetime: Infinity,
+  start: function (id) {
+    const server = createServer()
+
+    server.listen(port, function () {
+      console.log('Server #%s listening on port %s, Ctrl+C to stop', id, port)
+    })
+  }
 })
diff --git a/server/index.js b/server/createServer.js
similarity index 62%
rename from server/index.js
rename to server/createServer.js
index 9960b44..0bd98a5 100644
--- a/server/index.js
+++ b/server/createServer.js
@@ -1,23 +1,34 @@
-/*eslint-disable no-console*/
+const fs = require('fs')
+const path = require('path')
 const http = require('http')
 const express = require('express')
 const cors = require('cors')
 const morgan = require('morgan')
-const middleware = require('./middleware')
+
 const { fetchStats } = require('./cloudflare')
+const parseURL = require('./middleware/parseURL')
+const checkBlacklist = require('./middleware/checkBlacklist')
+const fetchPackage = require('./middleware/fetchPackage')
+const findFile = require('./middleware/findFile')
+const serveFile = require('./middleware/serveFile')
 
-const fs = require('fs')
-const path = require('path')
+morgan.token('fwd', function (req) {
+  return req.get('x-forwarded-for').replace(/\s/g, '')
+})
 
-const sendHomePage = (publicDir) => {
+function sendHomePage(publicDir) {
   const html = fs.readFileSync(path.join(publicDir, 'index.html'), 'utf8')
 
-  return (req, res, next) => {
-    fetchStats((error, stats) => {
+  return function (req, res, next) {
+    fetchStats(function (error, stats) {
       if (error) {
         next(error)
       } else {
-        res.set('Cache-Control', 'public, max-age=60')
+        res.set({
+          'Cache-Control': 'public, max-age=60',
+          'Cache-Tag': 'home'
+        })
+
         res.send(
           // Replace the __SERVER_DATA__ token that was added to the
           // HTML file in the build process (see scripts/build.js).
@@ -30,15 +41,13 @@ const sendHomePage = (publicDir) => {
   }
 }
 
-const errorHandler = (err, req, res, next) => {
-  res.status(500).send('<p>Internal Server Error</p>')
+function errorHandler(err, req, res, next) {
+  res.status(500).type('text').send('Internal Server Error')
   console.error(err.stack)
   next(err)
 }
 
-morgan.token('fwd', (req) => req.get('x-forwarded-for').replace(/\s/g, ''))
-
-const createServer = (config) => {
+function createServer() {
   const app = express()
 
   app.disable('x-powered-by')
@@ -53,20 +62,24 @@ const createServer = (config) => {
   app.use(errorHandler)
   app.use(cors())
 
-  app.get('/', sendHomePage(config.publicDir))
+  app.get('/', sendHomePage('build'))
 
-  app.use(express.static(config.publicDir, {
+  app.use(express.static('build', {
     maxAge: '365d'
   }))
 
-  app.use(middleware())
+  app.use(parseURL)
+  app.use(checkBlacklist)
+  app.use(fetchPackage)
+  app.use(findFile)
+  app.use(serveFile)
 
   const server = http.createServer(app)
 
   // Heroku dynos automatically timeout after 30s. Set our
   // own timeout here to force sockets to close before that.
   // https://devcenter.heroku.com/articles/request-timeout
-  server.setTimeout(25000, (socket) => {
+  server.setTimeout(25000, function (socket) {
     const message = `Timeout of 25 seconds exceeded`
 
     socket.end([
@@ -83,22 +96,4 @@ const createServer = (config) => {
   return server
 }
 
-const defaultServerConfig = {
-  id: 1,
-  port: parseInt(process.env.PORT, 10) || 5000,
-  publicDir: 'public'
-}
-
-const startServer = (serverConfig = {}) => {
-  const config = Object.assign({}, defaultServerConfig, serverConfig)
-  const server = createServer(config)
-
-  server.listen(config.port, () => {
-    console.log('Server #%s listening on port %s, Ctrl+C to stop', config.id, config.port)
-  })
-}
-
-module.exports = {
-  createServer,
-  startServer
-}
+module.exports = createServer
diff --git a/server/middleware/checkBlacklist.js b/server/middleware/checkBlacklist.js
index 892de53..bb90103 100644
--- a/server/middleware/checkBlacklist.js
+++ b/server/middleware/checkBlacklist.js
@@ -5,7 +5,7 @@ const blacklist = require('../PackageBlacklist').blacklist
  */
 function checkBlacklist(req, res, next) {
   if (blacklist.includes(req.packageName)) {
-    res.status(403).send(`Package ${req.packageName} is blacklisted`)
+    res.status(403).type('text').send(`Package ${req.packageName} is blacklisted`)
   } else {
     next()
   }
diff --git a/server/middleware/fetchPackage.js b/server/middleware/fetchPackage.js
index ab2732c..5afbf77 100644
--- a/server/middleware/fetchPackage.js
+++ b/server/middleware/fetchPackage.js
@@ -11,11 +11,11 @@ function fetchPackage(req, res, next) {
   PackageInfo.get(req.packageName, function (error, packageInfo) {
     if (error) {
       console.error(error)
-      return res.status(500).send(`Cannot get info for package "${req.packageName}"`)
+      return res.status(500).type('text').send(`Cannot get info for package "${req.packageName}"`)
     }
 
     if (packageInfo == null || packageInfo.versions == null)
-      return res.status(404).send(`Cannot find package "${req.packageName}"`)
+      return res.status(404).type('text').send(`Cannot find package "${req.packageName}"`)
 
     req.packageInfo = packageInfo
 
@@ -28,7 +28,7 @@ function fetchPackage(req, res, next) {
       PackageCache.get(req.packageConfig, function (error, outputDir) {
         if (error) {
           console.error(error)
-          res.status(500).send(`Cannot fetch package ${req.packageSpec}`)
+          res.status(500).type('text').send(`Cannot fetch package ${req.packageSpec}`)
         } else {
           req.packageDir = outputDir
           next()
@@ -42,7 +42,7 @@ function fetchPackage(req, res, next) {
       if (maxVersion) {
         res.redirect(PackageURL.create(req.packageName, maxVersion, req.filename, req.search))
       } else {
-        res.status(404).send(`Cannot find package ${req.packageSpec}`)
+        res.status(404).type('text').send(`Cannot find package ${req.packageSpec}`)
       }
     }
   })
diff --git a/server/middleware/findFile.js b/server/middleware/findFile.js
index 86318bc..a281311 100644
--- a/server/middleware/findFile.js
+++ b/server/middleware/findFile.js
@@ -51,7 +51,7 @@ function findFile(req, res, next) {
         console.error(error)
 
       if (file == null) {
-        res.status(404).send(`Cannot find file "${req.filename}" in package ${req.packageSpec}`)
+        res.status(404).type('text').send(`Cannot find file "${req.filename}" in package ${req.packageSpec}`)
       } else if (stats.isDirectory() && req.pathname[req.pathname.length - 1] !== '/') {
         // Append / to directory URLs.
         res.redirect(`${req.pathname}/${req.search}`)
@@ -71,7 +71,7 @@ function findFile(req, res, next) {
 
     if (queryMain) {
       if (!(queryMain in packageConfig))
-        return res.status(404).send(`Cannot find field "${queryMain}" in ${req.packageSpec} package config`)
+        return res.status(404).type('text').send(`Cannot find field "${queryMain}" in ${req.packageSpec} package config`)
 
       mainFilename = packageConfig[queryMain]
     } else {
@@ -93,7 +93,7 @@ function findFile(req, res, next) {
         console.error(error)
 
       if (file == null) {
-        res.status(404).send(`Cannot find main file "${mainFilename}" in package ${req.packageSpec}`)
+        res.status(404).type('text').send(`Cannot find main file "${mainFilename}" in package ${req.packageSpec}`)
       } else {
         req.file = file.replace(req.packageDir, '')
         req.stats = stats
diff --git a/server/middleware/index.js b/server/middleware/index.js
deleted file mode 100644
index 085e4f5..0000000
--- a/server/middleware/index.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const express = require('express')
-const parseURL = require('./parseURL')
-const checkBlacklist = require('./checkBlacklist')
-const fetchPackage = require('./fetchPackage')
-const findFile = require('./findFile')
-const serveFile = require('./serveFile')
-
-/**
- * Creates and returns a function that can be used in the "request"
- * event of a standard node HTTP server. Supported URL schemes are:
- *
- * /history@1.12.5/umd/History.min.js (recommended)
- * /history@1.12.5 (package.json's main is implied)
- *
- * Additionally, the following URLs are supported but will return a
- * temporary (302) redirect:
- *
- * /history (redirects to version, latest is implied)
- * /history/umd/History.min.js (redirects to version, latest is implied)
- * /history@latest/umd/History.min.js (redirects to version)
- * /history@^1/umd/History.min.js (redirects to max satisfying version)
- */
-function createRequestHandler() {
-  const app = express.Router()
-
-  app.use(
-    parseURL,
-    checkBlacklist,
-    fetchPackage,
-    findFile,
-    serveFile
-  )
-
-  return app
-}
-
-module.exports = createRequestHandler
diff --git a/server/middleware/parseURL.js b/server/middleware/parseURL.js
index 07bebae..a5d054e 100644
--- a/server/middleware/parseURL.js
+++ b/server/middleware/parseURL.js
@@ -19,12 +19,12 @@ function parseURL(req, res, next) {
   const url = PackageURL.parse(req.url)
 
   if (url == null)
-    return res.status(403).send(`Invalid URL: ${req.url}`)
+    return res.status(403).type('text').send(`Invalid URL: ${req.url}`)
 
   // Do not allow unrecognized query parameters because
   // some people use them to bust the cache.
   if (!queryIsValid(url.query))
-    return res.status(403).send(`Invalid query: ${JSON.stringify(url.query)}`)
+    return res.status(403).type('text').send(`Invalid query: ${JSON.stringify(url.query)}`)
 
   req.packageName = url.packageName
   req.packageVersion = url.packageVersion
diff --git a/server/middleware/serveFile.js b/server/middleware/serveFile.js
index 7afd7ea..b483c5f 100644
--- a/server/middleware/serveFile.js
+++ b/server/middleware/serveFile.js
@@ -31,7 +31,7 @@ function sendFile(res, file, stats) {
 
   stream.on('error', (error) => {
     console.error(error)
-    res.status(500).send('There was an error serving this file')
+    res.status(500).type('text').send('There was an error serving this file')
   })
 
   stream.pipe(res)
@@ -46,15 +46,21 @@ function serveFile(req, res, next) {
     Metadata.get(req.packageDir, req.file, req.stats, MaximumDepth, function (error, metadata) {
       if (error) {
         console.error(error)
-        res.status(500).send(`Cannot generate JSON metadata for ${req.packageSpec}${req.filename}`)
+        res.status(500).type('text').send(`Cannot generate JSON metadata for ${req.packageSpec}${req.filename}`)
       } else {
         // Cache metadata for 1 year.
-        res.set('Cache-Control', 'public, max-age=31536000').send(metadata)
+        res.set({
+          'Cache-Control': 'public, max-age=31536000',
+          'Cache-Tag': 'meta'
+        }).send(metadata)
       }
     })
   } else if (req.stats.isFile()) {
     // Cache files for 1 year.
-    res.set('Cache-Control', 'public, max-age=31536000')
+    res.set({
+      'Cache-Control': 'public, max-age=31536000',
+      'Cache-Tag': 'file'
+    })
 
     // TODO: use res.sendFile instead of our own sendFile?
     sendFile(res, path.join(req.packageDir, req.file), req.stats)
@@ -62,14 +68,17 @@ function serveFile(req, res, next) {
     generateDirectoryIndexHTML(req.packageInfo, req.packageVersion, req.packageDir, req.file, function (error, html) {
       if (error) {
         console.error(error)
-        res.status(500).send(`Cannot generate index page for ${req.packageSpec}${req.filename}`)
+        res.status(500).type('text').send(`Cannot generate index page for ${req.packageSpec}${req.filename}`)
       } else {
         // Cache HTML directory listings for 1 minute.
-        res.set('Cache-Control', 'public, max-age=60').send(html)
+        res.set({
+          'Cache-Control': 'public, max-age=60',
+          'Cache-Tag': 'index'
+        }).send(html)
       }
     })
   } else {
-    res.status(403).send(`Cannot serve ${req.packageSpec}${req.filename}; it's not a file`)
+    res.status(403).type('text').send(`Cannot serve ${req.packageSpec}${req.filename}; it's not a file`)
   }
 }