diff --git a/src/main/index.js b/src/main/index.js
index 4195197..19aff68 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -1,4 +1,4 @@
-import {BrowserWindow, Menu, app, dialog} from 'electron';
+import {BrowserWindow, Menu, app, dialog, ipcMain} from 'electron';
 import * as path from 'path';
 import {format as formatUrl} from 'url';
 import {getFilterForExtension} from './FileFilters';
@@ -13,20 +13,17 @@ const defaultSize = {width: 1280, height: 800}; // good for MAS screenshots
 
 const isDevelopment = process.env.NODE_ENV !== 'production';
 
-const createMainWindow = () => {
+// global window references prevent them from being garbage-collected
+const _windows = {};
+
+const createWindow = ({url, ...browserWindowOptions}) => {
     const window = new BrowserWindow({
-        width: defaultSize.width,
-        height: defaultSize.height,
         useContentSize: true,
-        show: false
+        show: false,
+        ...browserWindowOptions
     });
     const webContents = window.webContents;
 
-    if (process.platform === 'darwin') {
-        const osxMenu = Menu.buildFromTemplate(MacOSMenu(app));
-        Menu.setApplicationMenu(osxMenu);
-    }
-
     if (isDevelopment) {
         webContents.openDevTools();
         import('electron-devtools-installer').then(importedModule => {
@@ -46,15 +43,38 @@ const createMainWindow = () => {
     });
 
     if (isDevelopment) {
-        window.loadURL(`http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}`);
+        window.loadURL(`http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}/${url}`);
     } else {
         window.loadURL(formatUrl({
-            pathname: path.join(__dirname, 'index.html'),
+            pathname: path.join(__dirname, url),
             protocol: 'file',
             slashes: true
         }));
     }
 
+    return window;
+};
+
+const createAboutWindow = () => {
+    const window = createWindow({
+        width: 400,
+        height: 400,
+        parent: _windows.main,
+        title: 'About Scratch Desktop',
+        url: 'index.html?route=about'
+    });
+    return window;
+};
+
+const createMainWindow = () => {
+    const window = createWindow({
+        width: defaultSize.width,
+        height: defaultSize.height,
+        title: 'Scratch Desktop',
+        url: 'index.html'
+    });
+    const webContents = window.webContents;
+
     webContents.session.on('will-download', (ev, item) => {
         const itemPath = item.getFilename();
         const baseName = path.basename(itemPath);
@@ -104,6 +124,11 @@ const createMainWindow = () => {
     return window;
 };
 
+if (process.platform === 'darwin') {
+    const osxMenu = Menu.buildFromTemplate(MacOSMenu(app));
+    Menu.setApplicationMenu(osxMenu);
+}
+
 // quit application when all windows are closed
 app.on('window-all-closed', () => {
     app.quit();
@@ -113,13 +138,19 @@ app.on('will-quit', () => {
     telemetry.appWillClose();
 });
 
-// global reference to mainWindow (necessary to prevent window from being garbage collected)
-let _mainWindow;
-
 // create main BrowserWindow when electron is ready
 app.on('ready', () => {
-    _mainWindow = createMainWindow();
-    _mainWindow.on('closed', () => {
-        _mainWindow = null;
+    _windows.main = createMainWindow();
+    _windows.main.on('closed', () => {
+        delete _windows.main;
+    });
+    _windows.about = createAboutWindow();
+    _windows.about.on('close', event => {
+        event.preventDefault();
+        _windows.about.hide();
     });
 });
+
+ipcMain.on('open-about-window', () => {
+    _windows.about.show();
+});
diff --git a/src/renderer/about.jsx b/src/renderer/about.jsx
new file mode 100644
index 0000000..6abe151
--- /dev/null
+++ b/src/renderer/about.jsx
@@ -0,0 +1,43 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import {author, productName, version} from '../../package.json';
+
+import logo from '../icon/ScratchDesktop.svg';
+
+// TODO: localization?
+const AboutElement = () => (
+    <div
+        style={{
+            color: 'white',
+            fontFamily: '"Helvetica Neue", Helvetica, Arial, sans-serif',
+            fontWeight: 'bolder',
+            margin: 0,
+            position: 'absolute',
+            top: '50%',
+            left: '50%',
+            transform: 'translate(-50%, -50%)'
+        }}
+    >
+        <div><img
+            alt={`${productName} icon`}
+            src={logo}
+            style={{
+                maxWidth: '10rem',
+                maxHeight: '10rem'
+            }}
+        /></div>
+        <h2>{productName}</h2>
+        <div>Version {version}</div>
+        <table style={{fontSize: 'x-small'}}>
+            {
+                ['Electron', 'Chrome'].map(component => {
+                    const componentVersion = process.versions[component.toLowerCase()];
+                    return <tr key={component}><td>{component}</td><td>{componentVersion}</td></tr>;
+                })
+            }
+        </table>
+    </div>
+);
+
+const appTarget = document.getElementById('app');
+ReactDOM.render(<AboutElement />, appTarget);
diff --git a/src/renderer/app.jsx b/src/renderer/app.jsx
index 8f57506..d129811 100644
--- a/src/renderer/app.jsx
+++ b/src/renderer/app.jsx
@@ -45,6 +45,9 @@ const ScratchDesktopHOC = function (WrappedComponent) {
         componentWillUnmount () {
             ipcRenderer.removeListener('setTitleFromSave', this.handleSetTitleFromSave);
         }
+        handleClickLogo () {
+            ipcRenderer.send('open-about-window');
+        }
         handleProjectTelemetryEvent (event, metadata) {
             ipcRenderer.send(event, metadata);
         }
@@ -66,6 +69,7 @@ const ScratchDesktopHOC = function (WrappedComponent) {
                 isScratchDesktop
                 projectId={defaultProjectId}
                 showTelemetryModal={shouldShowTelemetryModal}
+                onClickLogo={this.handleClickLogo}
                 onProjectTelemetryEvent={this.handleProjectTelemetryEvent}
                 onStorageInit={this.handleStorageInit}
                 onTelemetryModalOptIn={this.handleTelemetryModalOptIn}
diff --git a/src/renderer/index.js b/src/renderer/index.js
index 4ca0734..36f6843 100644
--- a/src/renderer/index.js
+++ b/src/renderer/index.js
@@ -1,3 +1,12 @@
 // this is an async import so that it doesn't block the first render
 // index.html contains a loading/splash screen which will display while this import loads
-import('./app.jsx');
+
+const route = new URLSearchParams(window.location.search).get('route') || 'app';
+switch (route) {
+case 'app':
+    import('./app.jsx');
+    break;
+case 'about':
+    import('./about.jsx');
+    break;
+}