diff --git a/packages/base-model/package.json b/packages/base-model/package.json
index eb34d1d62e5c1b12765771a2d63744dcd55e015d..648c57a8bc3580ec3c5a99b8ed51ac7a37999d83 100644
--- a/packages/base-model/package.json
+++ b/packages/base-model/package.json
@@ -10,6 +10,7 @@
   "license": "MIT",
   "dependencies": {
     "objection": "^1.2.3",
+    "knex": "^0.16.3",
     "pubsweet-server": "^10.1.4"
   },
   "publishConfig": {
diff --git a/packages/base-model/src/index.js b/packages/base-model/src/index.js
index 6b74a9c00859ba47050fd5e5d46ca5dadfb43e4e..0fecd507930d7984545f6be7ff0fb133769ef9eb 100644
--- a/packages/base-model/src/index.js
+++ b/packages/base-model/src/index.js
@@ -1,7 +1,8 @@
 const uuid = require('uuid')
 const { Model, transaction } = require('objection')
 const logger = require('@pubsweet/logger')
-const { db, NotFoundError } = require('pubsweet-server')
+const { NotFoundError } = require('pubsweet-server/src/errors')
+const db = require('@pubsweet/db-manager/src/db')
 const { merge } = require('lodash')
 const config = require('config')
 
diff --git a/packages/cli/cli/migrate.js b/packages/cli/cli/migrate.js
index dfdd31a43f24627923e866f31e43282cb80b1bab..8281368761bf754b4b6cdd537456b8afcd197d94 100644
--- a/packages/cli/cli/migrate.js
+++ b/packages/cli/cli/migrate.js
@@ -1,6 +1,5 @@
 const program = require('commander')
-const { db } = require('pubsweet-server')
-const { migrate } = require('@pubsweet/db-manager')
+const { db, migrate } = require('@pubsweet/db-manager')
 
 module.exports = async (commandArguments = process.argv) => {
   const options = program.parse(commandArguments)
diff --git a/packages/cli/cli/setupdb.js b/packages/cli/cli/setupdb.js
index 46087d5c52c1656c251bd4f7190fb655ba72ffce..fec27577417418f27b4d270f16ffdc0de7557d94 100644
--- a/packages/cli/cli/setupdb.js
+++ b/packages/cli/cli/setupdb.js
@@ -1,7 +1,6 @@
 const program = require('commander')
 const properties = require('../src/schemas').db
-const { setupDb } = require('@pubsweet/db-manager')
-const db = require('pubsweet-server/src/db')
+const { db, setupDb } = require('@pubsweet/db-manager')
 const config = require('config')
 const { some, forEach } = require('lodash')
 const runPrompt = require('../src/run-prompt')
diff --git a/packages/components/model-collection/src/api_collections.js b/packages/components/model-collection/src/api_collections.js
index 5858cf8455d075969eecb45395d5cef9dd41a71a..778d5e3e91ba3b52ba8d2a49258572cc5eea3639 100644
--- a/packages/components/model-collection/src/api_collections.js
+++ b/packages/components/model-collection/src/api_collections.js
@@ -19,8 +19,7 @@ const authBearerAndPublic = passport.authenticate(['bearer', 'anonymous'], {
 })
 
 const CollectionsAPI = app => {
-  const { Collection, Team } = require('pubsweet-server/src/models')
-  const { model: User } = require('@pubsweet/model-user')
+  const { User, Collection, Team } = require('@pubsweet/models')
 
   // List collections
   app.get('/api/collections', authBearerAndPublic, async (req, res, next) => {
diff --git a/packages/components/model-collection/src/collection.js b/packages/components/model-collection/src/collection.js
index ba4cee2f36b7025521b52a3f00064951f37234bc..79917a29a250ccc15e5f6b8328a87f30babfdd63 100644
--- a/packages/components/model-collection/src/collection.js
+++ b/packages/components/model-collection/src/collection.js
@@ -34,7 +34,7 @@ class Collection extends BaseModel {
   }
 
   async delete() {
-    const { model: Team } = require('@pubsweet/model-team')
+    const { Team } = require('@pubsweet/models')
     await Team.deleteAssociated(this.type, this.id)
     return super.delete()
   }
@@ -42,7 +42,8 @@ class Collection extends BaseModel {
   // Gets fragments in a collection, supports filtering by function e.g.
   // collection.getFragments({filter: fragment => {Authorize.can(req.user, 'read', fragment)})
   getFragments(options) {
-    const { Fragment } = require('pubsweet-server/src/models')
+    const { Fragment } = require('@pubsweet/models')
+
     options = options || {}
     options.filter = options.filter || (() => Promise.resolve(true))
 
@@ -63,7 +64,8 @@ class Collection extends BaseModel {
   }
 
   addFragment(fragment) {
-    const { Fragment } = require('pubsweet-server/src/models')
+    const { Fragment } = require('@pubsweet/models')
+
     this.fragments = this.fragments.map(fragment => {
       if (typeof fragment === 'object') {
         return fragment
diff --git a/packages/components/model-fragment/src/api_fragments.js b/packages/components/model-fragment/src/api_fragments.js
index 86e2fd9c52112ee799bf27f19132d3986d0e1212..b228bef4f76196c2369587cc323efd6bacce0d12 100644
--- a/packages/components/model-fragment/src/api_fragments.js
+++ b/packages/components/model-fragment/src/api_fragments.js
@@ -23,11 +23,9 @@ const authBearerAndPublic = passport.authenticate(['bearer', 'anonymous'], {
 const FragmentsAPI = app => {
   const authsome = require('pubsweet-server/src/helpers/authsome')
 
-  const { AuthorizationError } = require('pubsweet-server')
+  const { AuthorizationError } = require('pubsweet-server/src/errors')
 
-  const { model: Team } = require('@pubsweet/model-team')
-  const { model: User } = require('@pubsweet/model-user')
-  const { Fragment, Collection } = require('pubsweet-server/src/models')
+  const { Team, User, Fragment, Collection } = require('@pubsweet/models')
 
   // Create a fragment and update the collection with the fragment
   app.post(
diff --git a/packages/components/model-user/src/api_users.js b/packages/components/model-user/src/api_users.js
index df6f2d3cd6cdf57976601a563076a57d04f8ee64..4a5f3754086b602b14e9e7254e7a21282f7290ca 100644
--- a/packages/components/model-user/src/api_users.js
+++ b/packages/components/model-user/src/api_users.js
@@ -11,7 +11,7 @@ const authentication = require('./authentication')
 
 const UsersAPI = app => {
   const User = require('./user')
-  const { ValidationError } = require('pubsweet-server')
+  const { ValidationError } = require('pubsweet-server/src/errors')
 
   const {
     util: {
diff --git a/packages/components/model-user/src/user.js b/packages/components/model-user/src/user.js
index 169814229b0c81cc787a6007f9c78ef9ba054c71..ea77450423df97e538297caf5e4a36fcc359f770 100644
--- a/packages/components/model-user/src/user.js
+++ b/packages/components/model-user/src/user.js
@@ -1,6 +1,5 @@
 const BaseModel = require('@pubsweet/base-model')
 const bcrypt = require('bcrypt')
-// const omit = require('lodash/omit')
 const pick = require('lodash/pick')
 const config = require('config')
 
@@ -83,7 +82,7 @@ class User extends BaseModel {
   }
 
   static async isUniq(user) {
-    const { ConflictError } = require('pubsweet-server')
+    const { ConflictError } = require('pubsweet-server/src/errors')
 
     let result
 
diff --git a/packages/components/xpub-review-server/src/reviewBackend.js b/packages/components/xpub-review-server/src/reviewBackend.js
index 977cc518eef00464081f710770ba822c90dd2ade..4d5814b9d006154f8d654e3cfd56efbc91e6df9d 100644
--- a/packages/components/xpub-review-server/src/reviewBackend.js
+++ b/packages/components/xpub-review-server/src/reviewBackend.js
@@ -4,11 +4,8 @@ const passport = require('passport')
 const logger = require('@pubsweet/logger')
 const emailer = require('@pubsweet/component-send-email')
 const {
-  User,
-  Team,
-  Fragment,
-  Collection,
-} = require('pubsweet-server/src/models')
+  models: { User, Fragment, Team, Collection },
+} = require('@pubsweet/db-manager')
 const authsome = require('pubsweet-server/src/helpers/authsome')
 const AuthorizationError = require('pubsweet-server/src/errors/AuthorizationError')
 
diff --git a/packages/components/xpub-review-server/src/reviewBackend.test.js b/packages/components/xpub-review-server/src/reviewBackend.test.js
index d5c1b2458da6039947d3cdf1cb568fd9357f08a5..bd0539fa3b1939d05df5f98827c1d01bc24342a3 100644
--- a/packages/components/xpub-review-server/src/reviewBackend.test.js
+++ b/packages/components/xpub-review-server/src/reviewBackend.test.js
@@ -10,47 +10,49 @@ jest.mock('@pubsweet/component-send-email', () => ({
   send: jest.fn().mockImplementation(() => Promise.resolve({})),
 }))
 
-jest.mock('pubsweet-server/src/models', () => ({
-  Team: () => ({
-    find: jest.fn(() => ({
-      id: '9555530a-ca92-4e74-a48c-b21ccc109ca8',
-      teams: ['08888b14-8b64-420d-898f-b2bdd9fbd57c'],
-      email: 'author@example.org',
-    })),
-    save: () => {},
-  }),
-  User: {
-    find: jest.fn(() => ({
-      id: '9555530a-ca92-4e74-a48c-b21ccc109ca8',
-      teams: ['08888b14-8b64-420d-898f-b2bdd9fbd57c'],
-      email: 'author@example.org',
+jest.mock('@pubsweet/db-manager', () => ({
+  models: {
+    Team: () => ({
+      find: jest.fn(() => ({
+        id: '9555530a-ca92-4e74-a48c-b21ccc109ca8',
+        teams: ['08888b14-8b64-420d-898f-b2bdd9fbd57c'],
+        email: 'author@example.org',
+      })),
       save: () => {},
-    })),
-  },
-  Fragment: {
-    find: jest.fn(() => ({
-      version: 1,
-      owners: [{}],
-      metadata: {
-        title: 'title',
-        abstract: 'abstract',
-      },
-      updateProperties(update) {
-        Object.assign(this, update)
-      },
-      save: () => {},
-    })),
-  },
-  Collection: {
-    find: jest.fn(() => ({
-      updateProperties: () => ({}),
-      reviewers: [
-        {
-          user: '9555530a-ca92-4e74-a48c-b21ccc109ca8',
+    }),
+    User: {
+      find: jest.fn(() => ({
+        id: '9555530a-ca92-4e74-a48c-b21ccc109ca8',
+        teams: ['08888b14-8b64-420d-898f-b2bdd9fbd57c'],
+        email: 'author@example.org',
+        save: () => {},
+      })),
+    },
+    Fragment: {
+      find: jest.fn(() => ({
+        version: 1,
+        owners: [{}],
+        metadata: {
+          title: 'title',
+          abstract: 'abstract',
         },
-      ],
-      save: () => {},
-    })),
+        updateProperties(update) {
+          Object.assign(this, update)
+        },
+        save: () => {},
+      })),
+    },
+    Collection: {
+      find: jest.fn(() => ({
+        updateProperties: () => ({}),
+        reviewers: [
+          {
+            user: '9555530a-ca92-4e74-a48c-b21ccc109ca8',
+          },
+        ],
+        save: () => {},
+      })),
+    },
   },
 }))
 
diff --git a/packages/db-manager/package.json b/packages/db-manager/package.json
index acb2b79df510d701da3fcebeb34ea0073eddfd09..f352ff9bcb16c2c4f6c48201720894ac31d2dd69 100644
--- a/packages/db-manager/package.json
+++ b/packages/db-manager/package.json
@@ -32,7 +32,7 @@
     "isomorphic-fetch": "^2.2.1",
     "joi": "^14.3.0",
     "pg": "^7.4.1",
-    "pubsweet-server": "^10.1.4",
+    "objection": "^1.3.0",
     "tmp": "^0.0.33",
     "umzug": "^2.1.0"
   }
diff --git a/packages/db-manager/src/commands/add-collection.js b/packages/db-manager/src/commands/add-collection.js
index 47ad2c7a79e94ffd6545a321f9f05f1e6c1f8d11..a662230253df9efdf50111ae005deee5b58d0eee 100644
--- a/packages/db-manager/src/commands/add-collection.js
+++ b/packages/db-manager/src/commands/add-collection.js
@@ -1,8 +1,7 @@
 const logger = require('@pubsweet/logger')
 
 module.exports = async (collectionData, fragment = null) => {
-  const { model: User } = require('@pubsweet/model-user')
-  const { Collection } = require('pubsweet-server/src/models')
+  const { User, Collection } = require('@pubsweet/models')
 
   logger.info('Creating collection')
 
diff --git a/packages/db-manager/src/commands/add-fragment.js b/packages/db-manager/src/commands/add-fragment.js
index 235997b1c5c4a122d7b4e21086efc79fb4d4d987..c21c7ca4d7edb4b67c88ed75b210278190d3ae62 100644
--- a/packages/db-manager/src/commands/add-fragment.js
+++ b/packages/db-manager/src/commands/add-fragment.js
@@ -1,8 +1,7 @@
 const logger = require('@pubsweet/logger')
 
 module.exports = async fragmentData => {
-  const { Fragment } = require('pubsweet-server/src/models')
-  const { model: User } = require('@pubsweet/model-user')
+  const { Fragment, User } = require('@pubsweet/models')
 
   logger.info('Creating fragment')
 
diff --git a/packages/db-manager/src/commands/add-user.js b/packages/db-manager/src/commands/add-user.js
index 1b4f4c8a9f03d6d1d8fd6ac248d3d71adafee712..cac6aad614ce2fb7cee0107d9a955627da2c1b30 100644
--- a/packages/db-manager/src/commands/add-user.js
+++ b/packages/db-manager/src/commands/add-user.js
@@ -1,5 +1,5 @@
 const logger = require('@pubsweet/logger')
-const { Collection, User } = require('pubsweet-server/src/models')
+const { Collection, User } = require('@pubsweet/models')
 const { validateUser } = require('../validations')
 
 const addAdminOwnerToAllCollections = async user => {
diff --git a/packages/db-manager/src/commands/create-tables.js b/packages/db-manager/src/commands/create-tables.js
index 1747a765d5cb10f86b77bc7cad3c38ff05105590..3f32c7ec445d3425a65d746e435deb6928d1e8ca 100644
--- a/packages/db-manager/src/commands/create-tables.js
+++ b/packages/db-manager/src/commands/create-tables.js
@@ -1,5 +1,5 @@
 const logger = require('@pubsweet/logger')
-const db = require('pubsweet-server/src/db')
+const db = require('../db')
 const migrate = require('./migrate')
 
 const createTables = async clobber => {
diff --git a/packages/server/src/db.js b/packages/db-manager/src/db.js
similarity index 100%
rename from packages/server/src/db.js
rename to packages/db-manager/src/db.js
diff --git a/packages/db-manager/src/helpers/db-exists.js b/packages/db-manager/src/helpers/db-exists.js
index d1eb6dcd1e862376998dc1d3dddef240fa921fe2..ef30f16d67bb7d3c1a12ec557f8ee14a62af16ef 100644
--- a/packages/db-manager/src/helpers/db-exists.js
+++ b/packages/db-manager/src/helpers/db-exists.js
@@ -1,4 +1,4 @@
-const db = require('pubsweet-server/src/db')
+const db = require('../db')
 const logger = require('@pubsweet/logger')
 
 module.exports = async () => {
diff --git a/packages/db-manager/src/helpers/umzug.js b/packages/db-manager/src/helpers/umzug.js
index 55e4463f657b0f59980d56f519936b08f7eea161..26763b4640e2e9ea125de318cefc0aeb134518ed 100644
--- a/packages/db-manager/src/helpers/umzug.js
+++ b/packages/db-manager/src/helpers/umzug.js
@@ -1,5 +1,5 @@
 const logger = require('@pubsweet/logger')
-const db = require('pubsweet-server/src/db')
+const db = require('../db')
 const Umzug = require('umzug')
 const fs = require('fs-extra')
 const path = require('path')
diff --git a/packages/db-manager/src/helpers/umzugStorage.js b/packages/db-manager/src/helpers/umzugStorage.js
index a55355e7619b7c8099a6f162e0e09be6e9e71312..0d745050577ab6798159cabcd2978733f0178633 100644
--- a/packages/db-manager/src/helpers/umzugStorage.js
+++ b/packages/db-manager/src/helpers/umzugStorage.js
@@ -1,4 +1,4 @@
-const db = require('pubsweet-server/src/db')
+const db = require('../db')
 
 // umzug storage adapter
 module.exports = {
diff --git a/packages/db-manager/src/index.js b/packages/db-manager/src/index.js
index 2007b182577959769913f1ecaa2c1605faecf7ef..e817214f6bd755ffd6f585148a67fe26c687207e 100644
--- a/packages/db-manager/src/index.js
+++ b/packages/db-manager/src/index.js
@@ -1,9 +1,8 @@
-module.exports = {
-  createTables: require('./commands/create-tables'),
-  setupDb: require('./commands/setup-db'),
-  migrate: require('./commands/migrate'),
-  addUser: require('./commands/add-user'),
-  addCollection: require('./commands/add-collection'),
-  addFragment: require('./commands/add-fragment'),
-  dbExists: require('./helpers/db-exists'),
-}
+module.exports.db = require('./db')
+module.exports.createTables = require('./commands/create-tables')
+module.exports.setupDb = require('./commands/setup-db')
+module.exports.migrate = require('./commands/migrate')
+module.exports.addUser = require('./commands/add-user')
+module.exports.addCollection = require('./commands/add-collection')
+module.exports.addFragment = require('./commands/add-fragment')
+module.exports.dbExists = require('./helpers/db-exists')
diff --git a/packages/db-manager/test/commands/add-collection.test.js b/packages/db-manager/test/commands/add-collection.test.js
index 0201c77f528671ad70f895d270deeb4ab7b39508..d4ae308e8db868eacf383abe957f691391f598f3 100644
--- a/packages/db-manager/test/commands/add-collection.test.js
+++ b/packages/db-manager/test/commands/add-collection.test.js
@@ -1,6 +1,6 @@
 const { addCollection, createTables } = require('../../src')
-const { Collection, Fragment } = require('pubsweet-server/src/models')
-const { model: User } = require('@pubsweet/model-user')
+
+const { Collection, Fragment, User } = require('@pubsweet/models')
 
 describe('add-collection', () => {
   beforeEach(() => createTables(true))
diff --git a/packages/db-manager/test/commands/add-fragment.test.js b/packages/db-manager/test/commands/add-fragment.test.js
index d0babb4b65d05af1dd7b8c0845166fce1544cb58..eb6298a3234953b2a9816315a4465ddcf2b52b99 100644
--- a/packages/db-manager/test/commands/add-fragment.test.js
+++ b/packages/db-manager/test/commands/add-fragment.test.js
@@ -1,6 +1,6 @@
 const { addFragment, createTables } = require('../../src')
-const { model: Fragment } = require('@pubsweet/model-fragment')
-const { model: User } = require('@pubsweet/model-user')
+
+const { Fragment, User } = require('@pubsweet/models')
 
 describe('add-fragment', () => {
   beforeEach(() => createTables(true))
diff --git a/packages/db-manager/test/commands/add-user.test.js b/packages/db-manager/test/commands/add-user.test.js
index de217ab8e0c6f6087df7c6e98639bdbfde664a0d..6322dee2dbf84cb12e931460d06a2af636440b84 100644
--- a/packages/db-manager/test/commands/add-user.test.js
+++ b/packages/db-manager/test/commands/add-user.test.js
@@ -1,6 +1,7 @@
-const { model: User } = require('@pubsweet/model-user')
 const { addUser, createTables } = require('../../src/')
 
+const { User } = require('@pubsweet/models')
+
 const nonAdminUser = {
   username: 'nonAdminUsername',
   email: 'nonAdmin@example.com',
diff --git a/packages/db-manager/test/commands/setup-db.test.js b/packages/db-manager/test/commands/setup-db.test.js
index 5bef00bf85ab054d9d749f784170d5c43dd9bd93..ab8f5c64efacf74c0733a34aa293bbab3dbda759 100644
--- a/packages/db-manager/test/commands/setup-db.test.js
+++ b/packages/db-manager/test/commands/setup-db.test.js
@@ -1,5 +1,5 @@
-const { model: User } = require('@pubsweet/model-user')
 const { setupDb } = require('../../src')
+const { User } = require('@pubsweet/models')
 
 describe('setup-db', () => {
   it('creates the database and an admin user', async () => {
diff --git a/packages/models/README.md b/packages/models/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..ec5eb1c3d3a15a95c044815a25fc4a9e4c8b903e
--- /dev/null
+++ b/packages/models/README.md
@@ -0,0 +1,7 @@
+# Models
+
+A package that connects all model components together, so that you can use them elsewhere with e.g.
+
+```
+const { User } = require('@pubsweet/models')
+```
diff --git a/packages/models/config/test.js b/packages/models/config/test.js
new file mode 100644
index 0000000000000000000000000000000000000000..57ffa063ae7d068506e3c5cfc3f91578d2571a7c
--- /dev/null
+++ b/packages/models/config/test.js
@@ -0,0 +1,31 @@
+const path = require('path')
+
+module.exports = {
+  'pubsweet-server': {
+    db: {
+      // temporary database name set by jest-environment-db
+      database: global.__testDbName || 'test',
+    },
+    pool: { min: 0, max: 10, idleTimeoutMillis: 1000 },
+    enableExperimentalGraphql: true,
+    port: 4000,
+    secret: 'test',
+    sse: false,
+    uploads: 'uploads',
+  },
+  authsome: {
+    mode: path.resolve(__dirname, '..', 'test', 'helpers', 'authsome_mode'),
+    teams: {
+      teamTest: {
+        name: 'Contributors',
+      },
+    },
+  },
+  schema: {
+    Manuscript: {
+      properties: {
+        configField: { type: 'string' },
+      },
+    },
+  },
+}
diff --git a/packages/models/package.json b/packages/models/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..62dbf46ec5ac38bf0ec459c288721f44c2f6a6e3
--- /dev/null
+++ b/packages/models/package.json
@@ -0,0 +1,18 @@
+{
+  "name": "@pubsweet/models",
+  "version": "0.0.1",
+  "description": "A simple package that brings models together",
+  "main": "src/index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "author": "Adam Hyde",
+  "license": "MIT",
+  "dependencies": {
+    "objection": "^1.2.3",
+    "pubsweet-server": "^10.1.4"
+  },
+  "publishConfig": {
+    "access": "public"
+  }
+}
diff --git a/packages/server/src/models/index.js b/packages/models/src/index.js
similarity index 100%
rename from packages/server/src/models/index.js
rename to packages/models/src/index.js
diff --git a/packages/server/package.json b/packages/server/package.json
index cdbdf9527a7245bb6b63cdb614b7aa46d9149997..aab51870017e2d86b1561b8ec7b5e3723a967b0c 100644
--- a/packages/server/package.json
+++ b/packages/server/package.json
@@ -31,7 +31,6 @@
     "http-status-codes": "^1.0.6",
     "joi": "^14.3.0",
     "jsonwebtoken": "^8.4.0",
-    "knex": "^0.15.2",
     "lodash": "^4.0.0",
     "minimist": "^1.2.0",
     "morgan": "^1.8.2",
diff --git a/packages/server/src/app.js b/packages/server/src/app.js
index 7b4cb34ee3cd1c0ccab48ab118cd86d249195503..a232d442dba5af69cbe61049ff9bef9f6b9ca069 100644
--- a/packages/server/src/app.js
+++ b/packages/server/src/app.js
@@ -13,8 +13,6 @@ const passport = require('passport')
 const graphqlApi = require('./graphql/routes')
 const index = require('./routes/index')
 const api = require('./routes/api')
-const models = require('./models')
-const authsome = require('./helpers/authsome')
 const logger = require('@pubsweet/logger')
 const sse = require('pubsweet-sse')
 
@@ -25,6 +23,9 @@ const registerComponents = require('./register-components')
 const configureApp = app => {
   global.versions = {}
 
+  const models = require('@pubsweet/models')
+  const authsome = require('./helpers/authsome')
+
   app.locals.models = models
 
   app.use(bodyParser.json({ limit: '50mb' }))
diff --git a/packages/server/src/connectors/index.js b/packages/server/src/connectors/index.js
index f19a2d830a0e5d59397637f99d432f15189ac9c2..89b41739ec37afff221bae9eca35f5c54e5fea14 100644
--- a/packages/server/src/connectors/index.js
+++ b/packages/server/src/connectors/index.js
@@ -1,17 +1,11 @@
 const config = require('config')
 
 const connector = require('./connector')
-const models = require('../models')
 
 const requireRelative = m =>
   require(require.resolve(m, { paths: [process.cwd()] }))
 
-const connectors = {
-  Collection: connector('Collection', models.Collection),
-  Fragment: connector('Fragment', models.Fragment),
-  Team: connector('Team', models.Team),
-  User: connector('User', models.User),
-}
+const connectors = {}
 
 // merge in component connectors, recursively
 function getConnectorsRecursively(componentName) {
diff --git a/packages/server/src/errors/index.js b/packages/server/src/errors/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..c7d9cea6b7938e34de200f21b11fdc9300f73426
--- /dev/null
+++ b/packages/server/src/errors/index.js
@@ -0,0 +1,4 @@
+module.exports.NotFoundError = require('./NotFoundError')
+module.exports.ConflictError = require('./ConflictError')
+module.exports.ValidationError = require('./ValidationError')
+module.exports.AuthorizationError = require('./AuthorizationError')
diff --git a/packages/server/src/helpers/authsome.js b/packages/server/src/helpers/authsome.js
index 5495f74b8312424cd9766d71f75c71999b324bfe..f5f23abef5e2ae21a70cc1adb7819ed7b1113e9d 100644
--- a/packages/server/src/helpers/authsome.js
+++ b/packages/server/src/helpers/authsome.js
@@ -3,7 +3,7 @@ const Authsome = require('authsome')
 
 const mode = require(config.get('authsome.mode'))
 
-const models = require('../models')
+const models = require('@pubsweet/models')
 
 // be lenient with custom/extended data models based on BaseModel
 // and allow them through to authsome in their entirety. If you use this
diff --git a/packages/server/src/index.js b/packages/server/src/index.js
index 0fb3d68afd28b8e3ba4a08911c3496395225b3d2..b83c94ac93dd576cd98a281ff8dc9e1d52899b04 100644
--- a/packages/server/src/index.js
+++ b/packages/server/src/index.js
@@ -1,10 +1,4 @@
-module.exports.db = require('./db')
-
 module.exports.pubsubManager = require('./graphql/pubsub')
-module.exports.NotFoundError = require('./errors/NotFoundError')
-module.exports.ConflictError = require('./errors/ConflictError')
-module.exports.ValidationError = require('./errors/ValidationError')
-module.exports.AuthorizationError = require('./errors/AuthorizationError')
 
 module.exports.startServer = require('./start-server')
 
diff --git a/packages/server/src/jobs/index.js b/packages/server/src/jobs/index.js
index 76bb1a0585c896e83e60d868cfa0601423297dbe..5246b78fa6e8a12d71d05a00885f1c8dab7f2c87 100644
--- a/packages/server/src/jobs/index.js
+++ b/packages/server/src/jobs/index.js
@@ -2,7 +2,7 @@
 const PgBoss = require('pg-boss')
 const logger = require('@pubsweet/logger')
 
-const db = require('../db')
+const db = require('@pubsweet/db-manager/src/db')
 
 const dbAdapter = {
   executeSql: (sql, parameters = []) => {
diff --git a/packages/server/src/setup-base.js b/packages/server/src/setup-base.js
index 731939d38c5bd5a6a8cba4df3939caabac169128..d18b3297c26037473936579438c848f7a1631e8b 100644
--- a/packages/server/src/setup-base.js
+++ b/packages/server/src/setup-base.js
@@ -2,7 +2,7 @@ const logger = require('@pubsweet/logger')
 
 class Setup {
   static async setup(user, collection) {
-    const { Collection, User } = require('pubsweet-server/src/models')
+    const { Collection, User } = require('@pubsweet/models')
 
     logger.info('Starting setup')
 
diff --git a/packages/server/test/api_admin_test.js b/packages/server/test/api_admin_test.js
index 4713014247db6d6e31668ddbbd60eb969db230f4..b47727d07b08de3b304a5b206f4380e253f07a40 100644
--- a/packages/server/test/api_admin_test.js
+++ b/packages/server/test/api_admin_test.js
@@ -4,7 +4,7 @@ const createBasicCollection = require('./helpers/basic_collection')
 const cleanDB = require('./helpers/db_cleaner')
 const fixtures = require('./fixtures/fixtures')
 
-const { User, Fragment } = require('../src/models')
+const { Fragment, User } = require('@pubsweet/models')
 
 const api = require('./helpers/api')
 
diff --git a/packages/server/test/api_authenticated_test.js b/packages/server/test/api_authenticated_test.js
index c23630454e3839f1f0c47e9dea67d24a764ee2c7..0bc84dbeffdecdac5c0e2fec69a5ba095182a307 100644
--- a/packages/server/test/api_authenticated_test.js
+++ b/packages/server/test/api_authenticated_test.js
@@ -6,7 +6,7 @@ const api = require('./helpers/api')
 const setTeamForCollection = require('./helpers/set_team')
 const fixtures = require('./fixtures/fixtures')
 
-const { Fragment, User } = require('../src/models')
+const { Fragment, User } = require('@pubsweet/models')
 
 describe('authenticated api', () => {
   let otherUser
diff --git a/packages/server/test/api_teams_test.js b/packages/server/test/api_teams_test.js
index 0b8b6f7a7df2f14eda2e16a62da8933dff79f08a..e5f341a96fe334102e474a281a2b796b4a3d4322 100644
--- a/packages/server/test/api_teams_test.js
+++ b/packages/server/test/api_teams_test.js
@@ -1,7 +1,8 @@
 const STATUS = require('http-status-codes')
 const cloneDeep = require('lodash/cloneDeep')
 
-const { Collection, User, Team } = require('../src/models')
+const { Collection, User, Team } = require('@pubsweet/models')
+
 const cleanDB = require('./helpers/db_cleaner')
 const fixtures = require('./fixtures/fixtures')
 
diff --git a/packages/server/test/api_unauthenticated_test.js b/packages/server/test/api_unauthenticated_test.js
index dc425656b3ed97407fc27e65c539f944f24de919..6d230000572e806cfc95324d14ea14b75dd613e4 100644
--- a/packages/server/test/api_unauthenticated_test.js
+++ b/packages/server/test/api_unauthenticated_test.js
@@ -4,7 +4,7 @@ const api = require('./helpers/api')
 const createBasicCollection = require('./helpers/basic_collection')
 const createFragment = require('./helpers/fragment')
 const cleanDB = require('./helpers/db_cleaner')
-const { Collection } = require('../src/models')
+const { Collection } = require('@pubsweet/models')
 
 describe('unauthenticated/public api', () => {
   let fragment
diff --git a/packages/server/test/helpers/db_cleaner.js b/packages/server/test/helpers/db_cleaner.js
index d029ceab1b1d302ef3b12da8c7e2c39f85857091..455d631f2e7c5ecd89b8d59ca0a70a8fa160c946 100644
--- a/packages/server/test/helpers/db_cleaner.js
+++ b/packages/server/test/helpers/db_cleaner.js
@@ -1,6 +1,5 @@
-const db = require('../../src/db')
+const { db, migrate } = require('@pubsweet/db-manager')
 const logger = require('@pubsweet/logger')
-const { migrate } = require('@pubsweet/db-manager')
 
 const dbCleaner = async () => {
   await db.raw('DROP SCHEMA public CASCADE;')
diff --git a/packages/server/test/helpers/fragment.js b/packages/server/test/helpers/fragment.js
index 96f05e7989ddb1bc69f86aa39e67b69a98eed279..0c73f806fb478eea63a9ee972fca11f9d7d3e02e 100644
--- a/packages/server/test/helpers/fragment.js
+++ b/packages/server/test/helpers/fragment.js
@@ -1,5 +1,5 @@
 const fixtures = require('../fixtures/fixtures')
-const { Fragment } = require('../../src/models')
+const { Fragment } = require('@pubsweet/models')
 const assign = require('lodash/assign')
 
 module.exports = (opts, collection) => {
diff --git a/packages/server/test/model_test.js b/packages/server/test/model_test.js
index 06902854aa502b57c0d0611c794a4048aa0303f6..e082fb061001f33fe83108a4ec9523a11b0833aa 100644
--- a/packages/server/test/model_test.js
+++ b/packages/server/test/model_test.js
@@ -1,5 +1,5 @@
 const STATUS = require('http-status-codes')
-const { Fragment, Collection } = require('../src/models')
+const { Fragment, Collection } = require('@pubsweet/models')
 const { model: User } = require('@pubsweet/model-user')
 const dbCleaner = require('./helpers/db_cleaner')
 const fixtures = require('./fixtures/fixtures')
diff --git a/packages/server/test/teams_test.js b/packages/server/test/teams_test.js
index ca2e4bc1864fa9a5227d676e1e8b5030e2802913..77113a07d1106a53c0c16cc55053ce3bf77bc058 100644
--- a/packages/server/test/teams_test.js
+++ b/packages/server/test/teams_test.js
@@ -1,4 +1,4 @@
-const { Fragment, User, Collection, Team } = require('../src/models')
+const { Fragment, User, Collection, Team } = require('@pubsweet/models')
 const dbCleaner = require('./helpers/db_cleaner')
 const fixtures = require('./fixtures/fixtures')
 
diff --git a/packages/ui/package.json b/packages/ui/package.json
index ae0a659b5f275866eb9f379f480b289d31352139..e6c1940027c663e0c24854535e01d9a035bde6e9 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -36,7 +36,6 @@
     "styled-components": "^4.1.1"
   },
   "devDependencies": {
-    "@pubsweet/styleguide": "^4.0.3",
     "babel-core": "^6.26.0",
     "babel-loader": "^7.1.2",
     "babel-preset-env": "^1.6.0",
diff --git a/yarn.lock b/yarn.lock
index c4715881cca894dbd26afebaf92f771c61457b1e..9cbe468418ed0d41c29e28148d729f6ab7a600a2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -135,6 +135,14 @@
   resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.6.tgz#16e97aca1ec1062324a01c5a6a7d0df8dd189854"
   integrity sha512-dWP6LJm9nKT6ALaa+bnL247GHHMWir3vSlZ2+IHgHgktZQx0L3Uvq2uAWcuzIe+fujRsYWBW2q622C5UvGK9iQ==
 
+"@babel/polyfill@^7.0.0":
+  version "7.2.3"
+  resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.2.3.tgz#277fe900281d6874ab82332c90482621cbea2575"
+  integrity sha512-XG854errfwBkrnWV9dDmSSa8ueTciFUMcC47Mn9obkfLipRKaQL4o33YRsNk0IEep1WXMvr1hGz8DQbSQC2tPQ==
+  dependencies:
+    core-js "^2.5.7"
+    regenerator-runtime "^0.12.0"
+
 "@babel/runtime-corejs2@^7.0.0":
   version "7.1.5"
   resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.1.5.tgz#ec8341c9aec71d1139c985327314739d66b204a0"
@@ -1012,6 +1020,11 @@
   resolved "https://registry.yarnpkg.com/@types/async/-/async-2.0.50.tgz#117540e026d64e1846093abbd5adc7e27fda7bcb"
   integrity sha512-VMhZMMQgV1zsR+lX/0IBfAk+8Eb7dPVMWiQGFAt3qjo5x7Ml6b77jUo0e1C3ToD+XRDXqtrfw+6AB0uUsPEr3Q==
 
+"@types/bluebird@^3.5.25":
+  version "3.5.25"
+  resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.25.tgz#59188b871208092e37767e4b3d80c3b3eaae43bd"
+  integrity sha512-yfhIBix+AIFTmYGtkC0Bi+XGjSkOINykqKvO/Wqdz/DuXlAKK7HmhLAXdPIGsV4xzKcL3ev/zYc4yLNo+OvGaw==
+
 "@types/node@*":
   version "10.12.10"
   resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.10.tgz#4fa76e6598b7de3f0cb6ec3abacc4f59e5b3a2ce"
@@ -3466,15 +3479,6 @@ chalk@2.3.1:
     escape-string-regexp "^1.0.5"
     supports-color "^5.2.0"
 
-chalk@2.3.2:
-  version "2.3.2"
-  resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.2.tgz#250dc96b07491bfd601e648d66ddf5f60c7a5c65"
-  integrity sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==
-  dependencies:
-    ansi-styles "^3.2.1"
-    escape-string-regexp "^1.0.5"
-    supports-color "^5.3.0"
-
 chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.1:
   version "2.4.1"
   resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
@@ -3913,7 +3917,7 @@ combined-stream@^1.0.5, combined-stream@^1.0.6, combined-stream@~1.0.6:
   dependencies:
     delayed-stream "~1.0.0"
 
-commander@^2.11.0, commander@^2.16.0, commander@^2.19.0, commander@^2.9.0:
+commander@^2.11.0, commander@^2.19.0, commander@^2.9.0:
   version "2.19.0"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
   integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
@@ -4679,6 +4683,13 @@ debug@3.1.0, debug@=3.1.0:
   dependencies:
     ms "2.0.0"
 
+debug@4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87"
+  integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==
+  dependencies:
+    ms "^2.1.1"
+
 debug@^3.0.0, debug@^3.1.0, debug@^3.2.5:
   version "3.2.6"
   resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
@@ -6439,9 +6450,9 @@ findup@^0.1.5:
     commander "~2.1.0"
 
 fined@^1.0.1:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/fined/-/fined-1.1.0.tgz#b37dc844b76a2f5e7081e884f7c0ae344f153476"
-  integrity sha1-s33IRLdqL15wgeiE98CuNE8VNHY=
+  version "1.1.1"
+  resolved "https://registry.yarnpkg.com/fined/-/fined-1.1.1.tgz#95d88ff329123dd1a6950fdfcd321f746271e01f"
+  integrity sha512-jQp949ZmEbiYHk3gkbdtpJ0G1+kgtLQBNdP5edFP7Fh+WAYceLQz6yO1SBj72Xkg8GVyTB3bBzAYrHJVh5Xd5g==
   dependencies:
     expand-tilde "^2.0.2"
     is-plain-object "^2.0.3"
@@ -6450,9 +6461,9 @@ fined@^1.0.1:
     parse-filepath "^1.0.1"
 
 flagged-respawn@^1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.0.tgz#4e79ae9b2eb38bf86b3bb56bf3e0a56aa5fcabd7"
-  integrity sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-1.0.1.tgz#e7de6f1279ddd9ca9aac8a5971d618606b3aab41"
+  integrity sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==
 
 flat-cache@^1.2.1:
   version "1.3.4"
@@ -9107,20 +9118,21 @@ kleur@^2.0.1:
   resolved "https://registry.yarnpkg.com/kleur/-/kleur-2.0.2.tgz#b704f4944d95e255d038f0cb05fb8a602c55a300"
   integrity sha512-77XF9iTllATmG9lSlIv0qdQ2BQ/h9t0bJllHlbvsQ0zUWfU7Yi0S8L5JXzPZgkefIiajLmBJJ4BsMJmqcf7oxQ==
 
-knex@^0.15.2:
-  version "0.15.2"
-  resolved "https://registry.yarnpkg.com/knex/-/knex-0.15.2.tgz#6059b87489605f4cc87599a6d2a9d265709e9340"
-  integrity sha1-YFm4dIlgX0zIdZmm0qnSZXCek0A=
+knex@^0.16.3:
+  version "0.16.3"
+  resolved "https://registry.yarnpkg.com/knex/-/knex-0.16.3.tgz#ca9effd4973655f42b42132b9019b0bc6bd20644"
+  integrity sha512-jGTOBW8b7exaBPfCKJSlv5q320IvWw9hEdtnURtbb0k3HusfZrR4UYiEewem8Nl7VqJILoCj99SjCK3W54UNPg==
   dependencies:
-    babel-runtime "^6.26.0"
-    bluebird "^3.5.1"
-    chalk "2.3.2"
-    commander "^2.16.0"
-    debug "3.1.0"
+    "@babel/polyfill" "^7.0.0"
+    "@types/bluebird" "^3.5.25"
+    bluebird "^3.5.3"
+    chalk "2.4.1"
+    commander "^2.19.0"
+    debug "4.1.0"
     inherits "~2.0.3"
     interpret "^1.1.0"
     liftoff "2.5.0"
-    lodash "^4.17.10"
+    lodash "^4.17.11"
     minimist "1.2.0"
     mkdirp "^0.5.1"
     pg-connection-string "2.0.0"
@@ -11348,7 +11360,7 @@ path-key@^2.0.0, path-key@^2.0.1:
   resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
   integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
 
-path-parse@^1.0.5:
+path-parse@^1.0.5, path-parse@^1.0.6:
   version "1.0.6"
   resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
   integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
@@ -13510,13 +13522,20 @@ resolve@1.1.7:
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
   integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=
 
-resolve@^1.1.6, resolve@^1.1.7, resolve@^1.3.3, resolve@^1.5.0, resolve@^1.6.0:
+resolve@^1.1.6, resolve@^1.3.3, resolve@^1.5.0, resolve@^1.6.0:
   version "1.8.1"
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26"
   integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==
   dependencies:
     path-parse "^1.0.5"
 
+resolve@^1.1.7:
+  version "1.9.0"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.9.0.tgz#a14c6fdfa8f92a7df1d996cb7105fa744658ea06"
+  integrity sha512-TZNye00tI67lwYvzxCxHGjwTNlUV70io54/Ed4j6PscB8xVfuBJpRenI/o6dVk0cY0PYTY27AgCoGGxRnYuItQ==
+  dependencies:
+    path-parse "^1.0.6"
+
 restore-cursor@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
@@ -14254,11 +14273,6 @@ stack-utils@^1.0.1:
   resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8"
   integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==
 
-stackback@0.0.2:
-  version "0.0.2"
-  resolved "https://registry.yarnpkg.com/stackback/-/stackback-0.0.2.tgz#1ac8a0d9483848d1695e418b6d031a3c3ce68e3b"
-  integrity sha1-Gsig2Ug4SNFpXkGLbQMaPDzmjjs=
-
 staged-git-files@1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.0.0.tgz#cdb847837c1fcc52c08a872d4883cc0877668a80"
@@ -15561,9 +15575,9 @@ v8flags@^2.1.1:
     user-home "^1.1.1"
 
 v8flags@^3.1.1:
-  version "3.1.1"
-  resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.1.1.tgz#42259a1461c08397e37fe1d4f1cfb59cad85a053"
-  integrity sha512-iw/1ViSEaff8NJ3HLyEjawk/8hjJib3E7pvG4pddVXfUg1983s3VGsiClDjhK64MQVDGqc1Q8r18S4VKQZS9EQ==
+  version "3.1.2"
+  resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.1.2.tgz#fc5cd0c227428181e6c29b2992e4f8f1da5e0c9f"
+  integrity sha512-MtivA7GF24yMPte9Rp/BWGCYQNaUj86zeYxV/x2RRJMKagImbbv3u8iJC57lNhWLPcGLJmHcHmFWkNsplbbLWw==
   dependencies:
     homedir-polyfill "^1.0.1"
 
@@ -15973,13 +15987,6 @@ which@1, which@^1.2.10, which@^1.2.12, which@^1.2.14, which@^1.2.9, which@^1.3.0
   dependencies:
     isexe "^2.0.0"
 
-why-is-node-running@^2.0.3:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/why-is-node-running/-/why-is-node-running-2.0.3.tgz#86619c2861405d3509f55268684fc85e7f4ce145"
-  integrity sha512-XmzbFN2T859avcs5qAsiiK1iu0nUpSUXRgiGsoHPcNijxhIlp1bPQWQk6ANUljDWqBtAbIR2jF1HxR0y2l2kCA==
-  dependencies:
-    stackback "0.0.2"
-
 wide-align@^1.1.0:
   version "1.1.3"
   resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"