diff --git a/static_src/reducers/projectV0.js b/static_src/reducers/projectV0.js
new file mode 100644
index 0000000..5101ff8
--- /dev/null
+++ b/static_src/reducers/projectV0.js
@@ -0,0 +1,586 @@
+// 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 * as permissions from 'reducers/permissions.js';
+import {fieldTypes, SITEWIDE_DEFAULT_COLUMNS, defaultIssueFieldMap,
+  parseColSpec, stringValuesForIssueField} from 'shared/issue-fields.js';
+import {hasPrefix, removePrefix} from 'shared/helpers.js';
+import {fieldNameToLabelPrefix,
+  labelNameToLabelPrefixes, labelNameToLabelValue, fieldDefToName,
+  restrictionLabelsForPermissions} from 'shared/convertersV0.js';
+import {prpcClient} from 'prpc-client-instance.js';
+import 'shared/typedef.js';
+
+/** @typedef {import('redux').AnyAction} AnyAction */
+
+// Actions
+export const SELECT = 'projectV0/SELECT';
+
+const FETCH_CONFIG_START = 'projectV0/FETCH_CONFIG_START';
+export const FETCH_CONFIG_SUCCESS = 'projectV0/FETCH_CONFIG_SUCCESS';
+const FETCH_CONFIG_FAILURE = 'projectV0/FETCH_CONFIG_FAILURE';
+
+export const FETCH_PRESENTATION_CONFIG_START =
+  'projectV0/FETCH_PRESENTATION_CONFIG_START';
+export const FETCH_PRESENTATION_CONFIG_SUCCESS =
+  'projectV0/FETCH_PRESENTATION_CONFIG_SUCCESS';
+export const FETCH_PRESENTATION_CONFIG_FAILURE =
+  'projectV0/FETCH_PRESENTATION_CONFIG_FAILURE';
+
+export const FETCH_CUSTOM_PERMISSIONS_START =
+  'projectV0/FETCH_CUSTOM_PERMISSIONS_START';
+export const FETCH_CUSTOM_PERMISSIONS_SUCCESS =
+  'projectV0/FETCH_CUSTOM_PERMISSIONS_SUCCESS';
+export const FETCH_CUSTOM_PERMISSIONS_FAILURE =
+  'projectV0/FETCH_CUSTOM_PERMISSIONS_FAILURE';
+
+
+export const FETCH_VISIBLE_MEMBERS_START =
+  'projectV0/FETCH_VISIBLE_MEMBERS_START';
+export const FETCH_VISIBLE_MEMBERS_SUCCESS =
+  'projectV0/FETCH_VISIBLE_MEMBERS_SUCCESS';
+export const FETCH_VISIBLE_MEMBERS_FAILURE =
+  'projectV0/FETCH_VISIBLE_MEMBERS_FAILURE';
+
+const FETCH_TEMPLATES_START = 'projectV0/FETCH_TEMPLATES_START';
+export const FETCH_TEMPLATES_SUCCESS = 'projectV0/FETCH_TEMPLATES_SUCCESS';
+const FETCH_TEMPLATES_FAILURE = 'projectV0/FETCH_TEMPLATES_FAILURE';
+
+/* State Shape
+{
+  name: string,
+
+  configs: Object<string, Config>,
+  presentationConfigs: Object<string, PresentationConfig>,
+  customPermissions: Object<string, Array<string>>,
+  visibleMembers:
+      Object<string, {userRefs: Array<UserRef>, groupRefs: Array<UserRef>}>,
+  templates: Object<string, Array<TemplateDef>>,
+  presentationConfigsLoaded: Object<string, boolean>,
+
+  requests: {
+    fetchConfig: ReduxRequestState,
+    fetchMembers: ReduxRequestState
+    fetchCustomPermissions: ReduxRequestState,
+    fetchPresentationConfig: ReduxRequestState,
+    fetchTemplates: ReduxRequestState,
+  },
+}
+*/
+
+// Reducers
+export const nameReducer = createReducer(null, {
+  [SELECT]: (_state, {projectName}) => projectName,
+});
+
+export const configsReducer = createReducer({}, {
+  [FETCH_CONFIG_SUCCESS]: (state, {projectName, config}) => ({
+    ...state,
+    [projectName]: config,
+  }),
+});
+
+export const presentationConfigsReducer = createReducer({}, {
+  [FETCH_PRESENTATION_CONFIG_SUCCESS]:
+    (state, {projectName, presentationConfig}) => ({
+      ...state,
+      [projectName]: presentationConfig,
+    }),
+});
+
+/**
+ * Adds custom permissions to Redux in a normalized state.
+ * @param {Object<string, Array<String>>} state Redux state.
+ * @param {AnyAction} Action
+ * @return {Object<string, Array<String>>}
+ */
+export const customPermissionsReducer = createReducer({}, {
+  [FETCH_CUSTOM_PERMISSIONS_SUCCESS]:
+    (state, {projectName, permissions}) => ({
+      ...state,
+      [projectName]: permissions,
+    }),
+});
+
+export const visibleMembersReducer = createReducer({}, {
+  [FETCH_VISIBLE_MEMBERS_SUCCESS]: (state, {projectName, visibleMembers}) => ({
+    ...state,
+    [projectName]: visibleMembers,
+  }),
+});
+
+export const templatesReducer = createReducer({}, {
+  [FETCH_TEMPLATES_SUCCESS]: (state, {projectName, templates}) => ({
+    ...state,
+    [projectName]: templates,
+  }),
+});
+
+const requestsReducer = combineReducers({
+  fetchConfig: createRequestReducer(
+      FETCH_CONFIG_START, FETCH_CONFIG_SUCCESS, FETCH_CONFIG_FAILURE),
+  fetchMembers: createRequestReducer(
+      FETCH_VISIBLE_MEMBERS_START,
+      FETCH_VISIBLE_MEMBERS_SUCCESS,
+      FETCH_VISIBLE_MEMBERS_FAILURE),
+  fetchCustomPermissions: createRequestReducer(
+      FETCH_CUSTOM_PERMISSIONS_START,
+      FETCH_CUSTOM_PERMISSIONS_SUCCESS,
+      FETCH_CUSTOM_PERMISSIONS_FAILURE),
+  fetchPresentationConfig: createRequestReducer(
+      FETCH_PRESENTATION_CONFIG_START,
+      FETCH_PRESENTATION_CONFIG_SUCCESS,
+      FETCH_PRESENTATION_CONFIG_FAILURE),
+  fetchTemplates: createRequestReducer(
+      FETCH_TEMPLATES_START, FETCH_TEMPLATES_SUCCESS, FETCH_TEMPLATES_FAILURE),
+});
+
+export const reducer = combineReducers({
+  name: nameReducer,
+  configs: configsReducer,
+  customPermissions: customPermissionsReducer,
+  presentationConfigs: presentationConfigsReducer,
+  visibleMembers: visibleMembersReducer,
+  templates: templatesReducer,
+  requests: requestsReducer,
+});
+
+// Selectors
+export const project = (state) => state.projectV0 || {};
+
+export const viewedProjectName =
+  createSelector(project, (project) => project.name || null);
+
+export const configs =
+  createSelector(project, (project) => project.configs || {});
+export const presentationConfigs =
+  createSelector(project, (project) => project.presentationConfigs || {});
+export const customPermissions =
+  createSelector(project, (project) => project.customPermissions || {});
+export const visibleMembers =
+  createSelector(project, (project) => project.visibleMembers || {});
+export const templates =
+  createSelector(project, (project) => project.templates || {});
+
+export const viewedConfig = createSelector(
+    [viewedProjectName, configs],
+    (projectName, configs) => configs[projectName] || {});
+export const viewedPresentationConfig = createSelector(
+    [viewedProjectName, presentationConfigs],
+    (projectName, configs) => configs[projectName] || {});
+
+// TODO(crbug.com/monorail/7080): Come up with a more clear and
+// consistent pattern for determining when data is loaded.
+export const viewedPresentationConfigLoaded = createSelector(
+    [viewedProjectName, presentationConfigs],
+    (projectName, configs) => !!configs[projectName]);
+export const viewedCustomPermissions = createSelector(
+    [viewedProjectName, customPermissions],
+    (projectName, permissions) => permissions[projectName] || []);
+export const viewedVisibleMembers = createSelector(
+    [viewedProjectName, visibleMembers],
+    (projectName, visibleMembers) => visibleMembers[projectName] || {});
+export const viewedTemplates = createSelector(
+    [viewedProjectName, templates],
+    (projectName, templates) => templates[projectName] || []);
+
+/**
+ * Get the default columns for the currently viewed project.
+ */
+export const defaultColumns = createSelector(viewedPresentationConfig,
+    ({defaultColSpec}) =>{
+      if (defaultColSpec) {
+        return parseColSpec(defaultColSpec);
+      }
+      return SITEWIDE_DEFAULT_COLUMNS;
+    });
+
+
+/**
+ * Get the default query for the currently viewed project.
+ */
+export const defaultQuery = createSelector(viewedPresentationConfig,
+    (config) => config.defaultQuery || '');
+
+// Look up components by path.
+export const componentsMap = createSelector(
+    viewedConfig,
+    (config) => {
+      if (!config || !config.componentDefs) return new Map();
+      const acc = new Map();
+      for (const v of config.componentDefs) {
+        acc.set(v.path, v);
+      }
+      return acc;
+    },
+);
+
+export const fieldDefs = createSelector(
+    viewedConfig, (config) => ((config && config.fieldDefs) || []),
+);
+
+export const fieldDefMap = createSelector(
+    fieldDefs, (fieldDefs) => {
+      const map = new Map();
+      fieldDefs.forEach((fd) => {
+        map.set(fd.fieldRef.fieldName.toLowerCase(), fd);
+      });
+      return map;
+    },
+);
+
+export const labelDefs = createSelector(
+    [viewedConfig, viewedCustomPermissions],
+    (config, permissions) => [
+      ...((config && config.labelDefs) || []),
+      ...restrictionLabelsForPermissions(permissions),
+    ],
+);
+
+// labelDefs stored in an easily findable format with label names as keys.
+export const labelDefMap = createSelector(
+    labelDefs, (labelDefs) => {
+      const map = new Map();
+      labelDefs.forEach((ld) => {
+        map.set(ld.label.toLowerCase(), ld);
+      });
+      return map;
+    },
+);
+
+/**
+ * A selector that builds a map where keys are label prefixes
+ * and values equal to sets of possible values corresponding to the prefix
+ * @param {Object} state Current Redux state.
+ * @return {Map}
+ */
+export const labelPrefixValueMap = createSelector(labelDefs, (labelDefs) => {
+  const prefixMap = new Map();
+  labelDefs.forEach((ld) => {
+    const prefixes = labelNameToLabelPrefixes(ld.label);
+
+    prefixes.forEach((prefix) => {
+      if (prefixMap.has(prefix)) {
+        prefixMap.get(prefix).add(labelNameToLabelValue(ld.label, prefix));
+      } else {
+        prefixMap.set(prefix, new Set(
+            [labelNameToLabelValue(ld.label, prefix)]));
+      }
+    });
+  });
+
+  return prefixMap;
+});
+
+/**
+ * A selector that builds an array of label prefixes, keeping casing intact
+ * Some labels are implicitly used as custom fields in the grid and list view.
+ * Only labels with more than one option are included, to reduce noise.
+ * @param {Object} state Current Redux state.
+ * @return {Array}
+ */
+export const labelPrefixFields = createSelector(
+    labelPrefixValueMap, (map) => {
+      const prefixes = [];
+
+      map.forEach((options, prefix) => {
+      // Ignore label prefixes with only one value.
+        if (options.size > 1) {
+          prefixes.push(prefix);
+        }
+      });
+
+      return prefixes;
+    },
+);
+
+/**
+ * A selector that wraps labelPrefixFields arrays as set for fast lookup.
+ * @param {Object} state Current Redux state.
+ * @return {Set}
+ */
+export const labelPrefixSet = createSelector(
+    labelPrefixFields, (fields) => new Set(fields.map(
+        (field) => field.toLowerCase())),
+);
+
+export const enumFieldDefs = createSelector(
+    fieldDefs,
+    (fieldDefs) => {
+      return fieldDefs.filter(
+          (fd) => fd.fieldRef.type === fieldTypes.ENUM_TYPE);
+    },
+);
+
+/**
+ * A selector that builds a function that's used to compute the value of
+ * a given field name on a given issue. This function abstracts the difference
+ * between custom fields, built-in fields, and implicit fields created
+ * from labels and considers these values in the context of the current
+ * project configuration.
+ * @param {Object} state Current Redux state.
+ * @return {function(Issue, string): Array<string>} A function that processes a
+ *   given issue and field name to find the string value for that field, in
+ *   the issue.
+ */
+export const extractFieldValuesFromIssue = createSelector(
+    viewedProjectName,
+    (projectName) => (issue, fieldName) =>
+      stringValuesForIssueField(issue, fieldName, projectName),
+);
+
+/**
+ * A selector that builds a function that's used to compute the type of a given
+ * field name.
+ * @param {Object} state Current Redux state.
+ * @return {function(string): string}
+ */
+export const extractTypeForFieldName = createSelector(fieldDefMap,
+    (fieldDefMap) => {
+      return (fieldName) => {
+        const key = fieldName.toLowerCase();
+
+        // If the field is a built in field. Default fields have precedence
+        // over custom fields.
+        if (defaultIssueFieldMap.hasOwnProperty(key)) {
+          return defaultIssueFieldMap[key].type;
+        }
+
+        // If the field is a custom field. Custom fields have precedence
+        // over label prefixes.
+        if (fieldDefMap.has(key)) {
+          return fieldDefMap.get(key).fieldRef.type;
+        }
+
+        // Default to STR_TYPE, including for label fields.
+        return fieldTypes.STR_TYPE;
+      };
+    },
+);
+
+export const optionsPerEnumField = createSelector(
+    enumFieldDefs,
+    labelDefs,
+    (fieldDefs, labelDefs) => {
+      const map = new Map(fieldDefs.map(
+          (fd) => [fd.fieldRef.fieldName.toLowerCase(), []]));
+      labelDefs.forEach((ld) => {
+        const labelName = ld.label;
+
+        const fd = fieldDefs.find((fd) => hasPrefix(
+            labelName, fieldNameToLabelPrefix(fd.fieldRef.fieldName)));
+        if (fd) {
+          const key = fd.fieldRef.fieldName.toLowerCase();
+          map.get(key).push({
+            ...ld,
+            optionName: removePrefix(labelName,
+                fieldNameToLabelPrefix(fd.fieldRef.fieldName)),
+          });
+        }
+      });
+      return map;
+    },
+);
+
+export const fieldDefsForPhases = createSelector(
+    fieldDefs,
+    (fieldDefs) => {
+      if (!fieldDefs) return [];
+      return fieldDefs.filter((f) => f.isPhaseField);
+    },
+);
+
+export const fieldDefsByApprovalName = createSelector(
+    fieldDefs,
+    (fieldDefs) => {
+      if (!fieldDefs) return new Map();
+      const acc = new Map();
+      for (const fd of fieldDefs) {
+        if (fd.fieldRef && fd.fieldRef.approvalName) {
+          if (acc.has(fd.fieldRef.approvalName)) {
+            acc.get(fd.fieldRef.approvalName).push(fd);
+          } else {
+            acc.set(fd.fieldRef.approvalName, [fd]);
+          }
+        }
+      }
+      return acc;
+    },
+);
+
+export const fetchingConfig = (state) => {
+  return state.projectV0.requests.fetchConfig.requesting;
+};
+
+/**
+ * Shorthand method for detecting whether we are currently
+ * fetching presentationConcifg
+ * @param {Object} state Current Redux state.
+ * @return {boolean}
+ */
+export const fetchingPresentationConfig = (state) => {
+  return state.projectV0.requests.fetchPresentationConfig.requesting;
+};
+
+// Action Creators
+/**
+ * Action creator to set the currently viewed Project.
+ * @param {string} projectName The name of the Project to select.
+ * @return {function(function): Promise<void>}
+ */
+export const select = (projectName) => {
+  return (dispatch) => dispatch({type: SELECT, projectName});
+};
+
+/**
+ * Fetches data required to view project.
+ * @param {string} projectName
+ * @return {function(function): Promise<void>}
+ */
+export const fetch = (projectName) => async (dispatch) => {
+  const configPromise = dispatch(fetchConfig(projectName));
+  const visibleMembersPromise = dispatch(fetchVisibleMembers(projectName));
+
+  dispatch(fetchPresentationConfig(projectName));
+  dispatch(fetchTemplates(projectName));
+
+  const customPermissionsPromise = dispatch(
+      fetchCustomPermissions(projectName));
+
+  // TODO(crbug.com/monorail/5828): Remove window.TKR_populateAutocomplete once
+  // the old autocomplete code is deprecated.
+  const [config, visibleMembers, customPermissions] = await Promise.all([
+    configPromise,
+    visibleMembersPromise,
+    customPermissionsPromise]);
+  config.labelDefs = [...config.labelDefs,
+    ...restrictionLabelsForPermissions(customPermissions)];
+  dispatch(fetchFieldPerms(config.projectName, config.fieldDefs));
+  // eslint-disable-next-line new-cap
+  window.TKR_populateAutocomplete(config, visibleMembers, customPermissions);
+};
+
+/**
+ * Fetches project configuration including things like the custom fields in a
+ * project, the statuses, etc.
+ * @param {string} projectName
+ * @return {function(function): Promise<Config>}
+ */
+const fetchConfig = (projectName) => async (dispatch) => {
+  dispatch({type: FETCH_CONFIG_START});
+
+  const getConfig = prpcClient.call(
+      'monorail.Projects', 'GetConfig', {projectName});
+
+  try {
+    const config = await getConfig;
+    dispatch({type: FETCH_CONFIG_SUCCESS, projectName, config});
+    return config;
+  } catch (error) {
+    dispatch({type: FETCH_CONFIG_FAILURE, error});
+  }
+};
+
+export const fetchPresentationConfig = (projectName) => async (dispatch) => {
+  dispatch({type: FETCH_PRESENTATION_CONFIG_START});
+
+  try {
+    const presentationConfig = await prpcClient.call(
+        'monorail.Projects', 'GetPresentationConfig', {projectName});
+    dispatch({
+      type: FETCH_PRESENTATION_CONFIG_SUCCESS,
+      projectName,
+      presentationConfig,
+    });
+  } catch (error) {
+    dispatch({type: FETCH_PRESENTATION_CONFIG_FAILURE, error});
+  }
+};
+
+/**
+ * Fetches custom permissions defined for a project.
+ * @param {string} projectName
+ * @return {function(function): Promise<Array<string>>}
+ */
+export const fetchCustomPermissions = (projectName) => async (dispatch) => {
+  dispatch({type: FETCH_CUSTOM_PERMISSIONS_START});
+
+  try {
+    const {permissions} = await prpcClient.call(
+        'monorail.Projects', 'GetCustomPermissions', {projectName});
+    dispatch({
+      type: FETCH_CUSTOM_PERMISSIONS_SUCCESS,
+      projectName,
+      permissions,
+    });
+    return permissions;
+  } catch (error) {
+    dispatch({type: FETCH_CUSTOM_PERMISSIONS_FAILURE, error});
+  }
+};
+
+/**
+ * Fetches the project members that the user is able to view.
+ * @param {string} projectName
+ * @return {function(function): Promise<GetVisibleMembersResponse>}
+ */
+export const fetchVisibleMembers = (projectName) => async (dispatch) => {
+  dispatch({type: FETCH_VISIBLE_MEMBERS_START});
+
+  try {
+    const visibleMembers = await prpcClient.call(
+        'monorail.Projects', 'GetVisibleMembers', {projectName});
+    dispatch({
+      type: FETCH_VISIBLE_MEMBERS_SUCCESS,
+      projectName,
+      visibleMembers,
+    });
+    return visibleMembers;
+  } catch (error) {
+    dispatch({type: FETCH_VISIBLE_MEMBERS_FAILURE, error});
+  }
+};
+
+const fetchTemplates = (projectName) => async (dispatch) => {
+  dispatch({type: FETCH_TEMPLATES_START});
+
+  const listTemplates = prpcClient.call(
+      'monorail.Projects', 'ListProjectTemplates', {projectName});
+
+  // TODO(zhangtiff): Remove (see above TODO).
+  if (!listTemplates) return;
+
+  try {
+    const resp = await listTemplates;
+    dispatch({
+      type: FETCH_TEMPLATES_SUCCESS,
+      projectName,
+      templates: resp.templates,
+    });
+  } catch (error) {
+    dispatch({type: FETCH_TEMPLATES_FAILURE, error});
+  }
+};
+
+// Helpers
+
+/**
+ * Helper to fetch field permissions.
+ * @param {string} projectName The name of the project where the fields are.
+ * @param {Array<FieldDef>} fieldDefs
+ * @return {function(function): Promise<void>}
+ */
+export const fetchFieldPerms = (projectName, fieldDefs) => async (dispatch) => {
+  const fieldDefsNames = [];
+  if (fieldDefs) {
+    fieldDefs.forEach((fd) => {
+      const fieldDefName = fieldDefToName(projectName, fd);
+      fieldDefsNames.push(fieldDefName);
+    });
+  }
+  await dispatch(permissions.batchGet(fieldDefsNames));
+};
