diff --git a/static_src/reducers/userV0.js b/static_src/reducers/userV0.js
new file mode 100644
index 0000000..42a93fc
--- /dev/null
+++ b/static_src/reducers/userV0.js
@@ -0,0 +1,384 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {combineReducers} from 'redux';
+import {createSelector} from 'reselect';
+import {createReducer, createRequestReducer} from './redux-helpers.js';
+import {prpcClient} from 'prpc-client-instance.js';
+import {objectToMap} from 'shared/helpers.js';
+import {userRefToId, userToUserRef} from 'shared/convertersV0.js';
+import loadGapi, {fetchGapiEmail} from 'shared/gapi-loader.js';
+import {DEFAULT_MD_PROJECTS} from 'shared/md-helper.js';
+import {viewedProjectName} from 'reducers/projectV0.js';
+
+// Actions
+const FETCH_START = 'userV0/FETCH_START';
+const FETCH_SUCCESS = 'userV0/FETCH_SUCCESS';
+const FETCH_FAILURE = 'userV0/FETCH_FAILURE';
+
+export const FETCH_PROJECTS_START = 'userV0/FETCH_PROJECTS_START';
+export const FETCH_PROJECTS_SUCCESS = 'userV0/FETCH_PROJECTS_SUCCESS';
+export const FETCH_PROJECTS_FAILURE = 'userV0/FETCH_PROJECTS_FAILURE';
+
+const FETCH_HOTLISTS_START = 'userV0/FETCH_HOTLISTS_START';
+const FETCH_HOTLISTS_SUCCESS = 'userV0/FETCH_HOTLISTS_SUCCESS';
+const FETCH_HOTLISTS_FAILURE = 'userV0/FETCH_HOTLISTS_FAILURE';
+
+const FETCH_PREFS_START = 'userV0/FETCH_PREFS_START';
+const FETCH_PREFS_SUCCESS = 'userV0/FETCH_PREFS_SUCCESS';
+const FETCH_PREFS_FAILURE = 'userV0/FETCH_PREFS_FAILURE';
+
+export const SET_PREFS_START = 'userV0/SET_PREFS_START';
+export const SET_PREFS_SUCCESS = 'userV0/SET_PREFS_SUCCESS';
+export const SET_PREFS_FAILURE = 'userV0/SET_PREFS_FAILURE';
+
+const GAPI_LOGIN_START = 'GAPI_LOGIN_START';
+export const GAPI_LOGIN_SUCCESS = 'GAPI_LOGIN_SUCCESS';
+const GAPI_LOGIN_FAILURE = 'GAPI_LOGIN_FAILURE';
+
+const GAPI_LOGOUT_START = 'GAPI_LOGOUT_START';
+export const GAPI_LOGOUT_SUCCESS = 'GAPI_LOGOUT_SUCCESS';
+const GAPI_LOGOUT_FAILURE = 'GAPI_LOGOUT_FAILURE';
+
+
+// Monorial UserPrefs are stored as plain strings in Monorail's backend.
+// We want boolean preferences to be converted into booleans for convenience.
+// Currently, there are no user prefs in Monorail that are NOT booleans, so
+// we default to converting all user prefs to booleans unless otherwise
+// specified.
+// See: https://source.chromium.org/chromium/infra/infra/+/main:appengine/monorail/framework/framework_bizobj.py;l=409
+const NON_BOOLEAN_PREFS = new Set(['test_non_bool']);
+
+
+/* State Shape
+{
+  currentUser: {
+    ...user: Object,
+    groups: Array,
+    hotlists: Array,
+    prefs: Object,
+    gapiEmail: String,
+  },
+  requests: {
+    fetch: Object,
+    fetchHotlists: Object,
+    fetchPrefs: Object,
+  },
+}
+*/
+
+// Reducers
+const USER_DEFAULT = {
+  groups: [],
+  hotlists: [],
+  projects: {},
+  prefs: {},
+  prefsLoaded: false,
+};
+
+const gapiEmailReducer = (user, action) => {
+  return {
+    ...user,
+    gapiEmail: action.email || '',
+  };
+};
+
+export const currentUserReducer = createReducer(USER_DEFAULT, {
+  [FETCH_SUCCESS]: (_user, action) => {
+    return {
+      ...USER_DEFAULT,
+      ...action.user,
+      groups: action.groups,
+    };
+  },
+  [FETCH_HOTLISTS_SUCCESS]: (user, action) => {
+    return {...user, hotlists: action.hotlists};
+  },
+  [FETCH_PREFS_SUCCESS]: (user, action) => {
+    return {
+      ...user,
+      prefs: action.prefs,
+      prefsLoaded: true,
+    };
+  },
+  [SET_PREFS_SUCCESS]: (user, action) => {
+    const newPrefs = action.newPrefs;
+    const prefs = Object.assign({}, user.prefs);
+    newPrefs.forEach(({name, value}) => {
+      prefs[name] = value;
+    });
+    return {
+      ...user,
+      prefs,
+    };
+  },
+  [GAPI_LOGIN_SUCCESS]: gapiEmailReducer,
+  [GAPI_LOGOUT_SUCCESS]: gapiEmailReducer,
+});
+
+export const usersByIdReducer = createReducer({}, {
+  [FETCH_PROJECTS_SUCCESS]: (state, action) => {
+    const newState = {...state};
+
+    action.usersProjects.forEach((userProjects) => {
+      const {userRef, ownerOf = [], memberOf = [], contributorTo = [],
+        starredProjects = []} = userProjects;
+
+      const userId = userRefToId(userRef);
+
+      newState[userId] = {
+        ...newState[userId],
+        projects: {
+          ownerOf,
+          memberOf,
+          contributorTo,
+          starredProjects,
+        },
+      };
+    });
+
+    return newState;
+  },
+});
+
+const requestsReducer = combineReducers({
+  // Request for getting backend metadata related to a user, such as
+  // which groups they belong to and whether they're a site admin.
+  fetch: createRequestReducer(FETCH_START, FETCH_SUCCESS, FETCH_FAILURE),
+  // Requests for fetching projects a user is related to.
+  fetchProjects: createRequestReducer(
+      FETCH_PROJECTS_START, FETCH_PROJECTS_SUCCESS, FETCH_PROJECTS_FAILURE),
+  // Request for getting a user's hotlists.
+  fetchHotlists: createRequestReducer(
+      FETCH_HOTLISTS_START, FETCH_HOTLISTS_SUCCESS, FETCH_HOTLISTS_FAILURE),
+  // Request for getting a user's prefs.
+  fetchPrefs: createRequestReducer(
+      FETCH_PREFS_START, FETCH_PREFS_SUCCESS, FETCH_PREFS_FAILURE),
+  // Request for setting a user's prefs.
+  setPrefs: createRequestReducer(
+      SET_PREFS_START, SET_PREFS_SUCCESS, SET_PREFS_FAILURE),
+});
+
+export const reducer = combineReducers({
+  currentUser: currentUserReducer,
+  usersById: usersByIdReducer,
+  requests: requestsReducer,
+});
+
+// Selectors
+export const requests = (state) => state.userV0.requests;
+export const currentUser = (state) => state.userV0.currentUser || {};
+// TODO(zhangtiff): Replace custom logic to check if the user is logged in
+// across the frontend.
+export const isLoggedIn = createSelector(
+    currentUser, (user) => user && user.userId);
+export const userRef = createSelector(
+    currentUser, (user) => userToUserRef(user));
+export const prefs = createSelector(
+    currentUser, viewedProjectName, (user, projectName = '') => {
+      const prefs = {
+        // Make Markdown default to true for projects who have opted in.
+        render_markdown: String(DEFAULT_MD_PROJECTS.has(projectName)),
+        ...user.prefs
+      };
+      for (let prefName of Object.keys(prefs)) {
+        if (!NON_BOOLEAN_PREFS.has(prefName)) {
+          // Monorail user preferences are stored as strings.
+          prefs[prefName] = prefs[prefName] === 'true';
+        }
+      }
+      return objectToMap(prefs);
+    });
+
+const _usersById = (state) => state.userV0.usersById || {};
+export const usersById = createSelector(_usersById,
+    (usersById) => objectToMap(usersById));
+
+export const projectsPerUser = createSelector(usersById, (usersById) => {
+  const map = new Map();
+  for (const [key, value] of usersById.entries()) {
+    if (value.projects) {
+      map.set(key, value.projects);
+    }
+  }
+  return map;
+});
+
+// Projects for just the current user.
+export const projects = createSelector(projectsPerUser, userRef,
+    (projectsMap, userRef) => projectsMap.get(userRefToId(userRef)) || {});
+
+// Action Creators
+/**
+ * Fetches the data required to view the logged in user.
+ * @param {string} displayName The display name of the logged in user. Note that
+ *   while usernames may be hidden for users in Monorail, the logged in user
+ *   will always be able to view their own name.
+ * @return {function(function): Promise<void>}
+ */
+export const fetch = (displayName) => async (dispatch) => {
+  dispatch({type: FETCH_START});
+
+  const message = {
+    userRef: {displayName},
+  };
+
+  try {
+    const resp = await Promise.all([
+      prpcClient.call(
+          'monorail.Users', 'GetUser', message),
+      prpcClient.call(
+          'monorail.Users', 'GetMemberships', message),
+    ]);
+
+    const user = resp[0];
+
+    dispatch({
+      type: FETCH_SUCCESS,
+      user,
+      groups: resp[1].groupRefs || [],
+    });
+
+    const userRef = userToUserRef(user);
+
+    dispatch(fetchProjects([userRef]));
+    const hotlistsPromise = dispatch(fetchHotlists(userRef));
+    dispatch(fetchPrefs());
+
+    hotlistsPromise.then((hotlists) => {
+      // TODO(crbug.com/monorail/5828): Remove
+      // window.TKR_populateHotlistAutocomplete once the old
+      // autocomplete code is deprecated.
+      window.TKR_populateHotlistAutocomplete(hotlists);
+    });
+  } catch (error) {
+    dispatch({type: FETCH_FAILURE, error});
+  };
+};
+
+export const fetchProjects = (userRefs) => async (dispatch) => {
+  dispatch({type: FETCH_PROJECTS_START});
+  try {
+    const resp = await prpcClient.call(
+        'monorail.Users', 'GetUsersProjects', {userRefs});
+    dispatch({type: FETCH_PROJECTS_SUCCESS, usersProjects: resp.usersProjects});
+  } catch (error) {
+    dispatch({type: FETCH_PROJECTS_FAILURE, error});
+  }
+};
+
+/**
+ * Fetches all of a given user's hotlists.
+ * @param {UserRef} userRef The user to fetch hotlists for.
+ * @return {function(function): Promise<Array<HotlistV0>>}
+ */
+export const fetchHotlists = (userRef) => async (dispatch) => {
+  dispatch({type: FETCH_HOTLISTS_START});
+
+  try {
+    const resp = await prpcClient.call(
+        'monorail.Features', 'ListHotlistsByUser', {user: userRef});
+
+    const hotlists = resp.hotlists || [];
+    hotlists.sort((hotlistA, hotlistB) => {
+      return hotlistA.name.localeCompare(hotlistB.name);
+    });
+    dispatch({type: FETCH_HOTLISTS_SUCCESS, hotlists});
+
+    return hotlists;
+  } catch (error) {
+    dispatch({type: FETCH_HOTLISTS_FAILURE, error});
+  };
+};
+
+/**
+ * Fetches user preferences for the logged in user.
+ * @return {function(function): Promise<void>}
+ */
+export const fetchPrefs = () => async (dispatch) => {
+  dispatch({type: FETCH_PREFS_START});
+
+  try {
+    const resp = await prpcClient.call(
+        'monorail.Users', 'GetUserPrefs', {});
+    const prefs = {};
+    (resp.prefs || []).forEach(({name, value}) => {
+      prefs[name] = value;
+    });
+    dispatch({type: FETCH_PREFS_SUCCESS, prefs});
+  } catch (error) {
+    dispatch({type: FETCH_PREFS_FAILURE, error});
+  };
+};
+
+/**
+ * Action creator for setting a user's preferences.
+ *
+ * @param {Object} newPrefs
+ * @param {boolean} saveChanges
+ * @return {function(function): Promise<void>}
+ */
+export const setPrefs = (newPrefs, saveChanges = true) => async (dispatch) => {
+  if (!saveChanges) {
+    dispatch({type: SET_PREFS_SUCCESS, newPrefs});
+    return;
+  }
+
+  dispatch({type: SET_PREFS_START});
+
+  try {
+    const message = {prefs: newPrefs};
+    await prpcClient.call(
+        'monorail.Users', 'SetUserPrefs', message);
+    dispatch({type: SET_PREFS_SUCCESS, newPrefs});
+
+    // Re-fetch the user's prefs after saving to prevent prefs from
+    // getting out of sync.
+    dispatch(fetchPrefs());
+  } catch (error) {
+    dispatch({type: SET_PREFS_FAILURE, error});
+  }
+};
+
+/**
+ * Action creator to initiate the gapi.js login flow.
+ *
+ * @return {Promise} Resolved only when gapi.js login succeeds.
+ */
+export const initGapiLogin = () => (dispatch) => {
+  dispatch({type: GAPI_LOGIN_START});
+
+  return new Promise(async (resolve) => {
+    try {
+      await loadGapi();
+      gapi.auth2.getAuthInstance().signIn().then(async () => {
+        const email = await fetchGapiEmail();
+        dispatch({type: GAPI_LOGIN_SUCCESS, email: email});
+        resolve();
+      });
+    } catch (error) {
+      // TODO(jeffcarp): Pop up a message that signIn failed.
+      dispatch({type: GAPI_LOGIN_FAILURE, error});
+    }
+  });
+};
+
+/**
+ * Action creator to log the user out of gapi.js
+ *
+ * @return {undefined}
+ */
+export const initGapiLogout = () => async (dispatch) => {
+  dispatch({type: GAPI_LOGOUT_START});
+
+  try {
+    await loadGapi();
+    gapi.auth2.getAuthInstance().signOut().then(() => {
+      dispatch({type: GAPI_LOGOUT_SUCCESS, email: ''});
+    });
+  } catch (error) {
+    // TODO(jeffcarp): Pop up a message that signOut failed.
+    dispatch({type: GAPI_LOGOUT_FAILURE, error});
+  }
+};
