diff --git a/__tests__/src/reducers/viewers.test.js b/__tests__/src/reducers/viewers.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..9adc942f8e851dd6eb801ba9da23c06d48bb985f
--- /dev/null
+++ b/__tests__/src/reducers/viewers.test.js
@@ -0,0 +1,45 @@
+import { viewersReducer } from '../../../src/state/reducers/viewers';
+import ActionTypes from '../../../src/state/actions/action-types';
+
+describe('viewers reducer', () => {
+  it('should handle UPDATE_VIEWPORT', () => {
+    expect(viewersReducer({
+      abc123: {
+        x: 1,
+      },
+      def456: {
+        y: 1,
+      },
+    }, {
+      type: ActionTypes.UPDATE_VIEWPORT,
+      windowId: 'abc123',
+      payload: { x: 0, y: 1, zoom: 0.5 },
+    })).toEqual({
+      abc123: {
+        x: 0,
+        y: 1,
+        zoom: 0.5,
+      },
+      def456: {
+        y: 1,
+      },
+    });
+  });
+  it('should handle REMOVE_WINDOW', () => {
+    expect(viewersReducer({
+      abc123: {
+        foo: 'bar',
+      },
+      def456: {
+        foo: 'bar',
+      },
+    }, {
+      type: ActionTypes.REMOVE_WINDOW,
+      windowId: 'abc123',
+    })).toEqual({
+      def456: {
+        foo: 'bar',
+      },
+    });
+  });
+});
diff --git a/src/state/reducers/viewers.js b/src/state/reducers/viewers.js
index dccd3dbdfdfe778a26f8a2ce7d46dcdcaef1a04f..e31e42d035658030b9b5a6edd8a7cafb0efd3548 100644
--- a/src/state/reducers/viewers.js
+++ b/src/state/reducers/viewers.js
@@ -12,6 +12,13 @@ export const viewersReducer = (state = {}, action) => {
           ...action.payload,
         },
       };
+    case ActionTypes.REMOVE_WINDOW:
+      return Object.keys(state).reduce((object, key) => {
+        if (key !== action.windowId) {
+          object[key] = state[key]; // eslint-disable-line no-param-reassign
+        }
+        return object;
+      }, {});
     default:
       return state;
   }