diff --git a/packages/xpub-faraday/README.md b/packages/xpub-faraday/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..64c7aaf4b917b690da5d454a12b74fc37f5e6e2c
--- /dev/null
+++ b/packages/xpub-faraday/README.md
@@ -0,0 +1,3 @@
+## xPub-faraday  
+
+An MVP implementation of the first design sessions which allows a user to go through the process of creating a submission, assigning editors and reviewers, submitting reviews and submitting a decision.  
\ No newline at end of file
diff --git a/packages/xpub-faraday/app.js b/packages/xpub-faraday/app.js
new file mode 100644
index 0000000000000000000000000000000000000000..084fe15f5699b0ddf8c4e648680b47bf3e1e5abb
--- /dev/null
+++ b/packages/xpub-faraday/app.js
@@ -0,0 +1,7 @@
+const logger = require('@pubsweet/logger')
+const startServer = require('pubsweet-server')
+
+startServer().catch(err => {
+    logger.error('FATAL ERROR, SHUTTING DOWN:', err)
+    process.exit(1)
+})
diff --git a/packages/xpub-faraday/app/DummyPage.js b/packages/xpub-faraday/app/DummyPage.js
new file mode 100644
index 0000000000000000000000000000000000000000..17dd3ef96b6e330eea6a092af5776a047eb2d151
--- /dev/null
+++ b/packages/xpub-faraday/app/DummyPage.js
@@ -0,0 +1,11 @@
+import React, { Component } from 'react'
+import { withJournal } from 'xpub-journal'
+
+class DummyComp extends Component {
+    render() {
+        console.log(this)
+        return <div>Dummy page </div>
+    }
+}
+
+export default withJournal(DummyComp)
diff --git a/packages/xpub-faraday/app/app.js b/packages/xpub-faraday/app/app.js
new file mode 100644
index 0000000000000000000000000000000000000000..3283086e0b8b052405120779ea1ca3758750ebf1
--- /dev/null
+++ b/packages/xpub-faraday/app/app.js
@@ -0,0 +1,39 @@
+import React from 'react'
+import ReactDOM from 'react-dom'
+import { AppContainer } from 'react-hot-loader'
+import createHistory from 'history/createBrowserHistory'
+
+import { configureStore, Root } from 'pubsweet-client'
+import { JournalProvider } from 'xpub-journal'
+import 'xpub-theme'
+
+import * as journal from './config/journal'
+import Routes from './routes'
+
+const history = createHistory()
+const store = configureStore(history, {})
+const theme = {}
+
+const render = () => {
+    ReactDOM.render(
+        <AppContainer>
+            <JournalProvider journal={journal}>
+                <Root
+                    history={history}
+                    routes={<Routes />}
+                    store={store}
+                    theme={theme}
+                />
+            </JournalProvider>
+        </AppContainer>,
+        document.getElementById('root'),
+    )
+}
+
+render()
+
+if (module.hot) {
+    module.hot.accept('./routes', () => {
+        render()
+    })
+}
diff --git a/packages/xpub-faraday/app/config/journal/article-sections.js b/packages/xpub-faraday/app/config/journal/article-sections.js
new file mode 100644
index 0000000000000000000000000000000000000000..72c45c40fae37485ab5c36606e7de001dd96c415
--- /dev/null
+++ b/packages/xpub-faraday/app/config/journal/article-sections.js
@@ -0,0 +1,30 @@
+export default [
+    {
+        label: 'Cognitive Psychology',
+        value: 'cognitive-psychology',
+    },
+    {
+        label: 'Social Psychology',
+        value: 'social-psychology',
+    },
+    {
+        label: 'Personality Psychology',
+        value: 'personality-psychology',
+    },
+    {
+        label: 'Developmental Psychology',
+        value: 'developmental-psychology',
+    },
+    {
+        label: 'Clinical Psychology',
+        value: 'clinical-psychology',
+    },
+    {
+        label: 'Organizational Behavior',
+        value: 'organizational-behavior',
+    },
+    {
+        label: 'Methodology and Research Practice',
+        value: 'methodology',
+    },
+]
diff --git a/packages/xpub-faraday/app/config/journal/article-types.js b/packages/xpub-faraday/app/config/journal/article-types.js
new file mode 100644
index 0000000000000000000000000000000000000000..409bf85ce2d020119c63ea6fe22f0433a94ae287
--- /dev/null
+++ b/packages/xpub-faraday/app/config/journal/article-types.js
@@ -0,0 +1,18 @@
+export default [
+    {
+        label: 'Original Research Report',
+        value: 'original-research',
+    },
+    {
+        label: 'Review',
+        value: 'review',
+    },
+    {
+        label: 'Opinion/Commentary',
+        value: 'opinion',
+    },
+    {
+        label: 'Registered Report',
+        value: 'registered-report',
+    },
+]
diff --git a/packages/xpub-faraday/app/config/journal/decisions.js b/packages/xpub-faraday/app/config/journal/decisions.js
new file mode 100644
index 0000000000000000000000000000000000000000..cf4c46bb9394859c31e7934fd197bd47f70a3a2f
--- /dev/null
+++ b/packages/xpub-faraday/app/config/journal/decisions.js
@@ -0,0 +1,24 @@
+export default {
+    accept: {
+        color: 'green',
+        label: 'Accept',
+        message: 'The submission has been accepted for publication',
+    },
+    major: {
+        color: 'yellow',
+        label: 'Major revisions',
+        message:
+            'The requested changes must be made before submission for review',
+    },
+    minor: {
+        color: 'orange',
+        label: 'Minor revisions',
+        message:
+            'The submission will be accepted for publication after minor changes',
+    },
+    reject: {
+        color: 'red',
+        label: 'Reject',
+        message: 'The submission is not acceptable for publication',
+    },
+}
diff --git a/packages/xpub-faraday/app/config/journal/declarations.js b/packages/xpub-faraday/app/config/journal/declarations.js
new file mode 100644
index 0000000000000000000000000000000000000000..da1aa76c30eb41e8a33321000c923ed2080a0a25
--- /dev/null
+++ b/packages/xpub-faraday/app/config/journal/declarations.js
@@ -0,0 +1,28 @@
+export default {
+    questions: [
+        {
+            id: 'openData',
+            legend: 'Data is open',
+        },
+        {
+            id: 'previouslySubmitted',
+            legend: 'Previously submitted',
+        },
+        {
+            id: 'openPeerReview',
+            legend: 'Open peer review',
+        },
+        {
+            id: 'streamlinedReview',
+            legend: 'Streamlined review',
+        },
+        {
+            id: 'researchNexus',
+            legend: 'Submitted as part of the research nexus?',
+        },
+        {
+            id: 'preregistered',
+            legend: 'Pre-registered?',
+        },
+    ],
+}
diff --git a/packages/xpub-faraday/app/config/journal/editors.js b/packages/xpub-faraday/app/config/journal/editors.js
new file mode 100644
index 0000000000000000000000000000000000000000..3132c2a78542328700fd0b25027ead94f5d17374
--- /dev/null
+++ b/packages/xpub-faraday/app/config/journal/editors.js
@@ -0,0 +1,32 @@
+export default {
+    handlingEditor: [
+        {
+            name: 'Handling Editor One',
+            user: 5,
+        },
+        {
+            name: 'Handling Editor Two',
+            user: 6,
+        },
+    ],
+    managingEditor: [
+        {
+            name: 'Managing Editor One',
+            user: 1,
+        },
+        {
+            name: 'Managing Editor Two',
+            user: 2,
+        },
+    ],
+    seniorEditor: [
+        {
+            name: 'Senior Editor One',
+            user: 3,
+        },
+        {
+            name: 'Senior Editor Two',
+            user: 4,
+        },
+    ],
+}
diff --git a/packages/xpub-faraday/app/config/journal/index.js b/packages/xpub-faraday/app/config/journal/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..30bc3a405632a2e2ff3972ac0c490a26666ce330
--- /dev/null
+++ b/packages/xpub-faraday/app/config/journal/index.js
@@ -0,0 +1,9 @@
+export { default as metadata } from './metadata'
+export { default as declarations } from './declarations'
+export { default as decisions } from './decisions'
+export { default as recommendations } from './recommendations'
+export { default as sections } from './sections'
+export { default as articleSections } from './article-sections'
+export { default as articleTypes } from './article-types'
+export { default as editors } from './editors'
+export { default as roles } from './roles'
diff --git a/packages/xpub-faraday/app/config/journal/metadata.js b/packages/xpub-faraday/app/config/journal/metadata.js
new file mode 100644
index 0000000000000000000000000000000000000000..5a9fb6318ec6d7ab9519951dad1830b02663a3d1
--- /dev/null
+++ b/packages/xpub-faraday/app/config/journal/metadata.js
@@ -0,0 +1,4 @@
+export default {
+    issn: '2474-7394',
+    name: 'Collabra: Psychology',
+}
diff --git a/packages/xpub-faraday/app/config/journal/recommendations.js b/packages/xpub-faraday/app/config/journal/recommendations.js
new file mode 100644
index 0000000000000000000000000000000000000000..0138243fddacb1a54411edae22ccfa99b84af5ec
--- /dev/null
+++ b/packages/xpub-faraday/app/config/journal/recommendations.js
@@ -0,0 +1,17 @@
+export default [
+    {
+        color: 'green',
+        label: 'Accept',
+        value: 'accept',
+    },
+    {
+        color: 'orange',
+        label: 'Revise',
+        value: 'revise',
+    },
+    {
+        color: 'red',
+        label: 'Reject',
+        value: 'reject',
+    },
+]
diff --git a/packages/xpub-faraday/app/config/journal/roles.js b/packages/xpub-faraday/app/config/journal/roles.js
new file mode 100644
index 0000000000000000000000000000000000000000..4021e6ecc12457a7f737fc8380bd47edd7587cec
--- /dev/null
+++ b/packages/xpub-faraday/app/config/journal/roles.js
@@ -0,0 +1,6 @@
+export default {
+    author: 'Author',
+    handlingEditor: 'Handling Editor',
+    managingEditor: 'Managing Editor',
+    seniorEditor: 'Senior Editor',
+}
diff --git a/packages/xpub-faraday/app/config/journal/sections.js b/packages/xpub-faraday/app/config/journal/sections.js
new file mode 100644
index 0000000000000000000000000000000000000000..a3b483e908254d0aac1668408b96eeaded1238f0
--- /dev/null
+++ b/packages/xpub-faraday/app/config/journal/sections.js
@@ -0,0 +1,6 @@
+export default [
+    {
+        id: 'submissions',
+        label: 'My Submissions',
+    },
+]
diff --git a/packages/xpub-faraday/app/index-production.html b/packages/xpub-faraday/app/index-production.html
new file mode 100644
index 0000000000000000000000000000000000000000..c4113cccda13c34cb919c145ec37c1af99334208
--- /dev/null
+++ b/packages/xpub-faraday/app/index-production.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <meta charset=utf-8>
+    <title><%= htmlWebpackPlugin.options.title %></title>
+</head>
+<body>
+<div id="root"></div>
+</body>
+</html>
diff --git a/packages/xpub-faraday/app/index.html b/packages/xpub-faraday/app/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..4210e6fed4fc2a8b610b816d684fc47fb77b3421
--- /dev/null
+++ b/packages/xpub-faraday/app/index.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+</head>
+<body>
+  <div id="root"></div>
+  <script src="/assets/app.js"></script>
+</body>
+</html>
diff --git a/packages/xpub-faraday/app/routes.js b/packages/xpub-faraday/app/routes.js
new file mode 100644
index 0000000000000000000000000000000000000000..3dafc287bac30494aa0d4ea01c604f7dddc55992
--- /dev/null
+++ b/packages/xpub-faraday/app/routes.js
@@ -0,0 +1,25 @@
+import React from 'react'
+import { Route } from 'react-router-dom'
+
+import App from 'pubsweet-component-xpub-app/src/components'
+
+import {
+    PrivateRoute,
+    LoginPage,
+    LogoutPage,
+} from 'pubsweet-component-xpub-authentication/src/components'
+
+import DashboardPage from 'pubsweet-component-xpub-dashboard/src/components/DashboardPage'
+
+import DummyPage from './DummyPage'
+
+const Routes = () => (
+    <App>
+        <Route component={LoginPage} exact path="/login" />
+        <PrivateRoute component={DashboardPage} exact path="/" />
+        <PrivateRoute component={DummyPage} exact path="/dummy" />
+        <PrivateRoute component={LogoutPage} exact path="/logout" />
+    </App>
+)
+
+export default Routes
diff --git a/packages/xpub-faraday/config/authsome.js b/packages/xpub-faraday/config/authsome.js
new file mode 100644
index 0000000000000000000000000000000000000000..d9ffa667b4430ebbef2869ccb2a9547fafcee2ce
--- /dev/null
+++ b/packages/xpub-faraday/config/authsome.js
@@ -0,0 +1,3 @@
+module.exports = (user, operation, project, version) =>
+    // console.log({ user, operation, project, version })
+    true // TODO
diff --git a/packages/xpub-faraday/config/components.json b/packages/xpub-faraday/config/components.json
new file mode 100644
index 0000000000000000000000000000000000000000..45b4d9e63f21b642b37a9451b6d820540e9822bc
--- /dev/null
+++ b/packages/xpub-faraday/config/components.json
@@ -0,0 +1,5 @@
+[
+  "pubsweet-component-xpub-app",
+  "pubsweet-component-xpub-authentication",
+  "pubsweet-component-xpub-dashboard"
+]
diff --git a/packages/xpub-faraday/config/default.js b/packages/xpub-faraday/config/default.js
new file mode 100644
index 0000000000000000000000000000000000000000..336a9c38c7e26ddac4fc2ba978974e06a3a557e0
--- /dev/null
+++ b/packages/xpub-faraday/config/default.js
@@ -0,0 +1,50 @@
+const path = require('path')
+const components = require('./components.json')
+const logger = require('winston')
+
+const environment = process.env.NODE_ENV || 'development'
+
+module.exports = {
+    authsome: {
+        mode: path.resolve(__dirname, 'authsome.js'),
+        teams: {
+            // TODO
+        },
+    },
+    validations: path.resolve(__dirname, 'validations.js'),
+    pubsweet: {
+        components,
+    },
+    'pubsweet-server': {
+        dbPath:
+            process.env.PUBSWEET_DB ||
+            path.join(__dirname, '..', 'api', 'db', environment),
+        logger,
+    },
+    'pubsweet-client': {
+        API_ENDPOINT: '/api',
+        'login-redirect': '/',
+        'redux-log': false,
+        theme: process.env.PUBSWEET_THEME,
+    },
+    'mail-transport': {
+        sendmail: true,
+    },
+    'password-reset': {
+        url:
+            process.env.PUBSWEET_PASSWORD_RESET_URL ||
+            'http://localhost:3000/password-reset',
+        sender: process.env.PUBSWEET_PASSWORD_RESET_SENDER || 'dev@example.com',
+    },
+    'pubsweet-component-ink-backend': {
+        inkEndpoint:
+            process.env.INK_ENDPOINT || 'http://inkdemo-api.coko.foundation',
+        email: process.env.INK_USERNAME,
+        password: process.env.INK_PASSWORD,
+        maxRetries: 500,
+        recipes: {
+            'editoria-typescript': '2',
+        },
+    },
+    publicKeys: ['pubsweet-client', 'authsome', 'validations'],
+}
diff --git a/packages/xpub-faraday/config/validations.js b/packages/xpub-faraday/config/validations.js
new file mode 100644
index 0000000000000000000000000000000000000000..60fee5c2564e80304a349a026cbcf7c6e37f7024
--- /dev/null
+++ b/packages/xpub-faraday/config/validations.js
@@ -0,0 +1,70 @@
+const Joi = require('joi')
+
+module.exports = {
+    collection: {
+        // project
+        collectionType: Joi.string(),
+        created: Joi.date(),
+        title: Joi.string(),
+        status: Joi.string(),
+        reviewers: Joi.array(),
+    },
+    fragment: [
+        {
+            fragmentType: Joi.valid('version').required(),
+            created: Joi.date(),
+            version: Joi.number(),
+            submitted: Joi.date(),
+            source: Joi.string(), // TODO: move to a file
+            metadata: Joi.object({
+                title: Joi.string(),
+                abstract: Joi.string(),
+                articleType: Joi.string(),
+                articleSection: Joi.array().items(Joi.string()),
+                authors: Joi.array(),
+                keywords: Joi.array(),
+            }),
+            declarations: Joi.object().unknown(),
+            suggestions: Joi.object({
+                reviewers: Joi.object({
+                    suggested: Joi.array().items(Joi.string()),
+                    opposed: Joi.array().items(Joi.string()),
+                }),
+                editors: Joi.object({
+                    suggested: Joi.array().items(Joi.string()),
+                    opposed: Joi.array().items(Joi.string()),
+                }),
+            }),
+            files: Joi.object({
+                manuscript: Joi.object({
+                    name: Joi.string().required(),
+                    type: Joi.string(),
+                    size: Joi.number(),
+                    url: Joi.string(),
+                }),
+                supplementary: Joi.array().items(
+                    Joi.object({
+                        name: Joi.string().required(),
+                        type: Joi.string(),
+                        size: Joi.number(),
+                        url: Joi.string(),
+                    }),
+                ),
+            }),
+            notes: Joi.object({
+                fundingAcknowledgement: Joi.string(),
+                specialInstructions: Joi.string(),
+            }),
+            reviewers: Joi.array(),
+            lock: Joi.object(),
+            decision: Joi.object(),
+        },
+    ],
+    user: {
+        name: Joi.string(), // TODO: add "name" to the login form
+        roles: Joi.object(),
+    },
+    team: {
+        group: Joi.string(),
+    },
+}
diff --git a/packages/xpub-faraday/package.json b/packages/xpub-faraday/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..85b2bca01215af093f8c714bb0df9edb9155bf02
--- /dev/null
+++ b/packages/xpub-faraday/package.json
@@ -0,0 +1,73 @@
+{
+  "name": "xpub-faraday",
+  "version": "0.0.1",
+  "description": "xpub configured for faraday",
+  "license": "MIT",
+  "repository": {
+    "type": "git",
+    "url": "https://gitlab.coko.foundation/xpub/xpub"
+  },
+  "dependencies": {
+    "@pubsweet/ui": "^0.1.1",
+    "babel-core": "^6.26.0",
+    "config": "^1.26.2",
+    "font-awesome": "^4.7.0",
+    "fs-extra": "^4.0.2",
+    "history": "^4.7.2",
+    "joi": "^10.0.6",
+    "loadable-components": "^0.3.0",
+    "moment": "^2.18.1",
+    "prop-types": "^15.5.10",
+    "pubsweet": "^1.1.1",
+    "pubsweet-client": "^1.1.1",
+    "pubsweet-component-ink-backend": "^0.1.1",
+    "pubsweet-component-ink-frontend": "^0.2.3",
+    "pubsweet-component-xpub-app": "^0.0.2",
+    "pubsweet-component-xpub-authentication": "^0.0.2",
+    "pubsweet-component-xpub-dashboard": "^0.0.2",
+    "pubsweet-component-xpub-manuscript": "^0.0.2",
+    "pubsweet-component-xpub-review": "^0.0.2",
+    "pubsweet-component-xpub-submit": "^0.0.2",
+    "pubsweet-server": "^1.0.1",
+    "react": "^15.6.1",
+    "react-dom": "^15.6.1",
+    "react-router-dom": "^4.2.2",
+    "recompose": "^0.26.0",
+    "redux": "^3.6.0",
+    "redux-form": "^7.0.3",
+    "redux-logger": "^3.0.1",
+    "winston": "^2.4.0",
+    "xpub-journal": "^0.0.2",
+    "xpub-selectors": "^0.0.2",
+    "xpub-theme": "^0.0.2"
+  },
+  "devDependencies": {
+    "babel-core": "^6.26.0",
+    "babel-loader": "^7.1.2",
+    "babel-preset-env": "^1.6.0",
+    "babel-preset-react": "^6.24.1",
+    "babel-preset-stage-2": "^6.24.1",
+    "clean-webpack-plugin": "^0.1.17",
+    "copy-webpack-plugin": "^4.0.1",
+    "css-loader": "^0.28.4",
+    "extract-text-webpack-plugin": "^3.0.0",
+    "file-loader": "^1.1.5",
+    "html-webpack-plugin": "^2.24.0",
+    "joi-browser": "^10.0.6",
+    "node-sass": "^4.5.3",
+    "react-hot-loader": "^3.1.1",
+    "sass-loader": "^6.0.6",
+    "string-replace-loader": "^1.3.0",
+    "style-loader": "^0.19.0",
+    "uglifyjs-webpack-plugin": "^1.1.2",
+    "webpack": "^3.8.1",
+    "webpack-dev-middleware": "^1.12.0",
+    "webpack-hot-middleware": "^2.20.0"
+  },
+  "scripts": {
+    "setupdb": "pubsweet setupdb ./",
+    "reset": "pubsweet setupdb --clobber ./",
+    "start": "pubsweet start",
+    "build": "NODE_ENV=production pubsweet build"
+  }
+}
diff --git a/packages/xpub-faraday/static/pubsweet-rgb-small.jpg b/packages/xpub-faraday/static/pubsweet-rgb-small.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..57efdcb962ffac6c6ce60777af38e62d4f872c87
Binary files /dev/null and b/packages/xpub-faraday/static/pubsweet-rgb-small.jpg differ
diff --git a/packages/xpub-faraday/static/pubsweet.jpg b/packages/xpub-faraday/static/pubsweet.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..57efdcb962ffac6c6ce60777af38e62d4f872c87
Binary files /dev/null and b/packages/xpub-faraday/static/pubsweet.jpg differ
diff --git a/packages/xpub-faraday/webpack/babel-includes.js b/packages/xpub-faraday/webpack/babel-includes.js
new file mode 100644
index 0000000000000000000000000000000000000000..d4e02f637f9711f4ea4006f8b72e17b8f08374f1
--- /dev/null
+++ b/packages/xpub-faraday/webpack/babel-includes.js
@@ -0,0 +1,13 @@
+const path = require('path')
+
+// paths that use ES6 scripts and CSS modules
+// TODO: compile components to ES5 for distribution
+
+module.exports = [
+    path.join(__dirname, '..', 'app'),
+    /pubsweet-[^/]+\/src/,
+    /xpub-[^/]+\/src/,
+    /component-[^/]+\/src/,
+    /wax-[^/]+\/src/,
+    /@pubsweet\/[^/]+\/src/,
+]
diff --git a/packages/xpub-faraday/webpack/common-resolve.js b/packages/xpub-faraday/webpack/common-resolve.js
new file mode 100644
index 0000000000000000000000000000000000000000..ecc8f691920b085413703a659dae0a9f2aea5093
--- /dev/null
+++ b/packages/xpub-faraday/webpack/common-resolve.js
@@ -0,0 +1,26 @@
+const path = require('path')
+const config = require('config')
+const fs = require('fs-extra')
+const { pick } = require('lodash')
+
+// can't use node-config in webpack so save whitelisted client config into the build and alias it below
+const outputPath = path.resolve(__dirname, '..', '_build', 'config')
+const clientConfig = pick(config, config.publicKeys)
+fs.ensureDirSync(outputPath)
+const clientConfigPath = path.join(outputPath, 'client-config.json')
+fs.writeJsonSync(clientConfigPath, clientConfig, { spaces: 2 })
+
+module.exports = {
+    // symlinks: false, // needed so that babel doesn't look for plugins in components
+    modules: [
+        path.resolve(__dirname, '..'), // needed for resolving app/routes
+        path.resolve(__dirname, '../node_modules'),
+        path.resolve(__dirname, '../../../node_modules'),
+        'node_modules',
+    ],
+    alias: {
+        joi: 'joi-browser',
+        config: clientConfigPath,
+    },
+    extensions: ['.js', '.jsx'],
+}
diff --git a/packages/xpub-faraday/webpack/rules.development.js b/packages/xpub-faraday/webpack/rules.development.js
new file mode 100644
index 0000000000000000000000000000000000000000..2aebd5433075a9d5afdf5515508d65a856c2d731
--- /dev/null
+++ b/packages/xpub-faraday/webpack/rules.development.js
@@ -0,0 +1,83 @@
+const include = require('./babel-includes')
+const stringReplaceRule = require('./string-replace')
+
+module.exports = [
+    stringReplaceRule,
+    {
+        oneOf: [
+            // ES6 JS
+            {
+                test: /\.jsx?$/,
+                include,
+                loader: 'babel-loader',
+                options: {
+                    presets: [
+                        [require('babel-preset-env'), { modules: false }],
+                        require('babel-preset-react'),
+                        require('babel-preset-stage-2'),
+                    ],
+                    plugins: [require('react-hot-loader/babel')],
+                },
+            },
+
+            // CSS Modules
+            {
+                test: /\.local\.css$/,
+                include,
+                use: [
+                    'style-loader',
+                    {
+                        loader: 'css-loader',
+                        options: {
+                            modules: true,
+                            localIdentName: '[name]_[local]-[hash:base64:8]',
+                        },
+                    },
+                ],
+            },
+
+            // SCSS Modules
+            {
+                test: /\.local\.scss$/,
+                include,
+                use: [
+                    'style-loader',
+                    {
+                        loader: 'css-loader',
+                        options: {
+                            modules: true,
+                            importLoaders: 1,
+                            localIdentName: '[name]_[local]-[hash:base64:8]',
+                        },
+                    },
+                    'sass-loader',
+                ],
+            },
+
+            // global CSS
+            {
+                test: /\.css$/,
+                use: ['style-loader', 'css-loader'],
+            },
+
+            // global SCSS
+            {
+                test: /\.scss$/,
+                use: [
+                    'style-loader',
+                    'css-loader', // TODO: importLoaders: 1?
+                    'sass-loader',
+                ],
+            },
+
+            // files
+            {
+                exclude: [/\.jsx?$/, /\.html$/, /\.json$/],
+                loader: 'file-loader',
+                options: {
+                    name: 'static/media/[name].[hash:8].[ext]',
+                },
+            },
+        ],
+    },
+]
diff --git a/packages/xpub-faraday/webpack/rules.production.js b/packages/xpub-faraday/webpack/rules.production.js
new file mode 100644
index 0000000000000000000000000000000000000000..17abad8ea4773e9bd7af49b98b8353f03d1a75ef
--- /dev/null
+++ b/packages/xpub-faraday/webpack/rules.production.js
@@ -0,0 +1,94 @@
+const ExtractTextPlugin = require('extract-text-webpack-plugin')
+const include = require('./babel-includes')
+const stringReplaceRule = require('./string-replace')
+
+module.exports = [
+    stringReplaceRule,
+    {
+        oneOf: [
+            // ES6 JS
+            {
+                test: /\.jsx?$/,
+                include,
+                loader: 'babel-loader',
+                options: {
+                    presets: [
+                        [require('babel-preset-env'), { modules: false }],
+                        require('babel-preset-react'),
+                        require('babel-preset-stage-2'),
+                    ],
+                },
+            },
+
+            // CSS Modules
+            {
+                test: /\.local\.css$/,
+                include,
+                use: ExtractTextPlugin.extract({
+                    fallback: 'style-loader',
+                    use: [
+                        {
+                            loader: 'css-loader',
+                            options: {
+                                modules: true,
+                                localIdentName:
+                                    '[name]_[local]-[hash:base64:8]',
+                            },
+                        },
+                    ],
+                }),
+            },
+
+            // SCSS Modules
+            {
+                test: /\.local\.scss$/,
+                include,
+                use: ExtractTextPlugin.extract({
+                    fallback: 'style-loader',
+                    use: [
+                        {
+                            loader: 'css-loader',
+                            options: {
+                                modules: true,
+                                importLoaders: 1,
+                                localIdentName:
+                                    '[name]_[local]-[hash:base64:8]',
+                            },
+                        },
+                        'sass-loader',
+                    ],
+                }),
+            },
+
+            // global CSS
+            {
+                test: /\.css$/,
+                use: ExtractTextPlugin.extract({
+                    fallback: 'style-loader',
+                    use: ['css-loader'],
+                }),
+            },
+
+            // global SCSS
+            {
+                test: /\.scss$/,
+                use: ExtractTextPlugin.extract({
+                    fallback: 'style-loader',
+                    use: [
+                        'css-loader', // TODO: importLoaders: 1?
+                        'sass-loader',
+                    ],
+                }),
+            },
+
+            // files
+            {
+                exclude: [/\.jsx?$/, /\.html$/, /\.json$/],
+                loader: 'file-loader',
+                options: {
+                    name: 'static/media/[name].[hash:8].[ext]',
+                },
+            },
+        ],
+    },
+]
diff --git a/packages/xpub-faraday/webpack/string-replace.js b/packages/xpub-faraday/webpack/string-replace.js
new file mode 100644
index 0000000000000000000000000000000000000000..16adfeaffeca45778db262c87e8648e6d8d12e99
--- /dev/null
+++ b/packages/xpub-faraday/webpack/string-replace.js
@@ -0,0 +1,23 @@
+// replace "PUBSWEET_COMPONENTS" string in pubsweet-client
+
+const components = require('../config/components.json')
+
+const requireComponentsString = components
+    .filter(name => {
+        const component = require(name)
+        // "client" or "frontend" for backwards compatibility
+        return component.client || component.frontend
+    })
+    .map(name => `require('${name}')`)
+    .join(', ')
+
+module.exports = {
+    test: /\.js$/,
+    enforce: 'pre',
+    // include: /pubsweet-client\/src\/components/,
+    loader: 'string-replace-loader',
+    options: {
+        search: 'PUBSWEET_COMPONENTS',
+        replace: `[${requireComponentsString}]`,
+    },
+}
diff --git a/packages/xpub-faraday/webpack/webpack.development.config.js b/packages/xpub-faraday/webpack/webpack.development.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..3dd0dd7d98955ef2373da94cb29dd6674207124d
--- /dev/null
+++ b/packages/xpub-faraday/webpack/webpack.development.config.js
@@ -0,0 +1,52 @@
+process.env.NODE_ENV = 'development'
+process.env.BABEL_ENV = 'development'
+
+const config = require('config')
+const path = require('path')
+const webpack = require('webpack')
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const rules = require('./rules.development')
+const resolve = require('./common-resolve')
+
+module.exports = [
+    {
+        name: 'app',
+        watch: true,
+        target: 'web',
+        context: path.join(__dirname, '..', 'app'),
+        entry: {
+            app: [
+                'react-hot-loader/patch',
+                'webpack-hot-middleware/client?reload=true',
+                './app',
+            ],
+        },
+        output: {
+            path: path.join(__dirname, '..', '_build', 'assets'),
+            filename: '[name].js',
+            publicPath: '/assets/',
+        },
+        devtool: 'eval', // 'cheap-module-source-map',
+        module: {
+            rules,
+        },
+        resolve,
+        plugins: [
+            new webpack.NamedModulesPlugin(),
+            new webpack.HotModuleReplacementPlugin(),
+            new webpack.NoEmitOnErrorsPlugin(),
+            new webpack.DefinePlugin({
+                'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
+            }),
+            new webpack.ContextReplacementPlugin(/./, __dirname, {
+                [config.authsome.mode]: config.authsome.mode,
+                [config.validations]: config.validations,
+            }),
+            new CopyWebpackPlugin([{ from: '../static' }]),
+        ],
+        node: {
+            fs: 'empty',
+            __dirname: true,
+        },
+    },
+]
diff --git a/packages/xpub-faraday/webpack/webpack.production.config.js b/packages/xpub-faraday/webpack/webpack.production.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..22338fe027026d4b013f0e12f8796f8d8f57f36c
--- /dev/null
+++ b/packages/xpub-faraday/webpack/webpack.production.config.js
@@ -0,0 +1,63 @@
+process.env.NODE_ENV = 'production'
+process.env.BABEL_ENV = 'production'
+
+const config = require('config')
+const path = require('path')
+const webpack = require('webpack')
+const CleanWebpackPlugin = require('clean-webpack-plugin')
+const ExtractTextPlugin = require('extract-text-webpack-plugin')
+const HtmlWebpackPlugin = require('html-webpack-plugin')
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
+const rules = require('./rules.production')
+const resolve = require('./common-resolve')
+
+module.exports = [
+    {
+        // The configuration for the client
+        name: 'app',
+        target: 'web',
+        context: path.join(__dirname, '..', 'app'),
+        entry: {
+            app: ['./app'],
+        },
+        output: {
+            path: path.join(__dirname, '..', '_build', 'assets'),
+            filename: '[name].[hash].js',
+            publicPath: '/assets/',
+        },
+        module: {
+            rules,
+        },
+        resolve,
+        // devtool: 'source-map',
+        plugins: [
+            new CleanWebpackPlugin(['assets'], {
+                root: path.join(__dirname, '..', '_build'),
+            }),
+            new HtmlWebpackPlugin({
+                title: 'xpub',
+                template: '../app/index-production.html',
+                inject: 'body',
+            }),
+            new webpack.DefinePlugin({
+                'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
+            }),
+            new webpack.ContextReplacementPlugin(/./, __dirname, {
+                [config.authsome.mode]: config.authsome.mode,
+                [config.validations]: config.validations,
+            }),
+            new ExtractTextPlugin('styles/main.css'),
+            new CopyWebpackPlugin([{ from: '../static' }]),
+            new webpack.optimize.AggressiveMergingPlugin(),
+            new webpack.optimize.OccurrenceOrderPlugin(),
+            new UglifyJSPlugin({
+                // sourceMap: true
+            }),
+        ],
+        node: {
+            fs: 'empty',
+            __dirname: true,
+        },
+    },
+]
diff --git a/packages/xpub-faraday/webpack/webpack.test.config.js b/packages/xpub-faraday/webpack/webpack.test.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..24b5e1804fbd0a98a28fe468d6cadb19f841f817
--- /dev/null
+++ b/packages/xpub-faraday/webpack/webpack.test.config.js
@@ -0,0 +1,52 @@
+process.env.NODE_ENV = 'test'
+process.env.BABEL_ENV = 'test'
+
+const config = require('config')
+const path = require('path')
+const webpack = require('webpack')
+const CopyWebpackPlugin = require('copy-webpack-plugin')
+const rules = require('./rules.production')
+const resolve = require('./common-resolve')
+
+module.exports = [
+    {
+        // The configuration for the client
+        name: 'app',
+        target: 'web',
+        context: path.join(__dirname, '..', 'app'),
+        entry: {
+            app: [
+                'react-hot-loader/patch',
+                'webpack-hot-middleware/client',
+                './app',
+            ],
+        },
+        output: {
+            path: path.join(__dirname, '..', '_build', 'assets'),
+            filename: '[name].js',
+            publicPath: '/assets/',
+        },
+        module: {
+            rules,
+        },
+        resolve,
+        plugins: [
+            new webpack.HotModuleReplacementPlugin(),
+            new webpack.NoEmitOnErrorsPlugin(),
+            new webpack.DefinePlugin({
+                'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
+            }),
+            new webpack.ContextReplacementPlugin(/./, __dirname, {
+                [config.authsome.mode]: config.authsome.mode,
+                [config.validations]: config.validations,
+            }),
+            new CopyWebpackPlugin([{ from: '../static' }]),
+            new webpack.optimize.AggressiveMergingPlugin(),
+            new webpack.optimize.OccurrenceOrderPlugin(),
+        ],
+        node: {
+            fs: 'empty',
+            __dirname: true,
+        },
+    },
+]
diff --git a/yarn.lock b/yarn.lock
index 08ac180ba66320498d4fb284bc0f80292eb9e996..45153ba3ddae739ac8b836a94610161191eee779 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7557,7 +7557,7 @@ prompt@^1.0.0:
     utile "0.3.x"
     winston "2.1.x"
 
-"prompt@github:flatiron/prompt#1c95d1d8d333b5fbc13fa5f0619f3dcf0d514f87":
+prompt@flatiron/prompt#1c95d1d8d333b5fbc13fa5f0619f3dcf0d514f87:
   version "1.0.0"
   resolved "https://codeload.github.com/flatiron/prompt/tar.gz/1c95d1d8d333b5fbc13fa5f0619f3dcf0d514f87"
   dependencies: