diff --git a/src/apps/basic-wrapper/index.ts b/src/apps/basic-wrapper/index.ts
index f030ff31181b3c406ea3aaf2c77337d0fb23af0c..eda1d52beaadca16798fcec89eee0d30e47ed5c7 100644
--- a/src/apps/basic-wrapper/index.ts
+++ b/src/apps/basic-wrapper/index.ts
@@ -26,9 +26,11 @@ class BasicWrapper {
     init(target: string | HTMLElement) {
         this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, {
             ...DefaultPluginSpec,
-            initialLayout: {
-                isExpanded: false,
-                showControls: false
+            layout: {
+                initial: {
+                    isExpanded: false,
+                    showControls: false
+                }
             }
         });
 
diff --git a/src/apps/viewer/index.ts b/src/apps/viewer/index.ts
index 1309526f08231a055e4b1bbe07ab835678b5db97..947f1be45eedcbdac2a0b5c8a131ba086ce57345 100644
--- a/src/apps/viewer/index.ts
+++ b/src/apps/viewer/index.ts
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
  */
@@ -10,8 +10,10 @@ require('mol-plugin/skin/light.scss')
 
 createPlugin(document.getElementById('app')!, {
     ...DefaultPluginSpec,
-    initialLayout: {
-        isExpanded: true,
-        showControls: true
+    layout: {
+        initial: {
+            isExpanded: true,
+            showControls: true
+        }
     }
 });
\ No newline at end of file
diff --git a/src/examples/proteopedia-wrapper/index.ts b/src/examples/proteopedia-wrapper/index.ts
index 962e5642fab1caf6e3edad9a8c1ff464e31fe04c..335e2a48b0c201ed3e553e1b73902b6850d114c2 100644
--- a/src/examples/proteopedia-wrapper/index.ts
+++ b/src/examples/proteopedia-wrapper/index.ts
@@ -17,6 +17,7 @@ import { StateBuilder, StateObject } from 'mol-state';
 import { EvolutionaryConservation } from './annotation';
 import { LoadParams, SupportedFormats, RepresentationStyle, ModelInfo } from './helpers';
 import { RxEventHelper } from 'mol-util/rx-event-helper';
+import { ControlsWrapper } from './ui/controls';
 require('mol-plugin/skin/light.scss')
 
 class MolStarProteopediaWrapper {
@@ -33,9 +34,14 @@ class MolStarProteopediaWrapper {
     init(target: string | HTMLElement) {
         this.plugin = createPlugin(typeof target === 'string' ? document.getElementById(target)! : target, {
             ...DefaultPluginSpec,
-            initialLayout: {
-                isExpanded: false,
-                showControls: false
+            layout: {
+                initial: {
+                    isExpanded: false,
+                    showControls: false
+                },
+                controls: {
+                    right: ControlsWrapper
+                }
             }
         });
 
diff --git a/src/examples/proteopedia-wrapper/ui/controls.tsx b/src/examples/proteopedia-wrapper/ui/controls.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..d2a79e61b59b5df991b610381e77c7d9e4fe8ecc
--- /dev/null
+++ b/src/examples/proteopedia-wrapper/ui/controls.tsx
@@ -0,0 +1,21 @@
+/**
+ * Copyright (c) 2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+import * as React from 'react';
+import { PluginUIComponent } from 'mol-plugin/ui/base';
+import { CurrentObject } from 'mol-plugin/ui/plugin';
+import { AnimationControls } from 'mol-plugin/ui/state/animation';
+import { CameraSnapshots } from 'mol-plugin/ui/camera';
+
+export class ControlsWrapper extends PluginUIComponent {
+    render() {
+        return <div className='msp-scrollable-container msp-right-controls'>
+            <CurrentObject />
+            <AnimationControls />
+            <CameraSnapshots />
+        </div>;
+    }
+}
\ No newline at end of file
diff --git a/src/mol-plugin/context.ts b/src/mol-plugin/context.ts
index d592a2ef37742a39bdc79c15dfaf0ba1804dbdde..43d7ea16a5e6fe6fd62340ee342f598f73e62b5b 100644
--- a/src/mol-plugin/context.ts
+++ b/src/mol-plugin/context.ts
@@ -99,7 +99,7 @@ export class PluginContext {
     initViewer(canvas: HTMLCanvasElement, container: HTMLDivElement) {
         try {
             this.layout.setRoot(container);
-            if (this.spec.initialLayout) this.layout.setProps(this.spec.initialLayout);
+            if (this.spec.layout && this.spec.layout.initial) this.layout.setProps(this.spec.layout.initial);
             (this.canvas3d as Canvas3D) = Canvas3D.create(canvas, container);
             PluginCommands.Canvas3D.SetSettings.dispatch(this, { settings: { backgroundColor: Color(0xFCFBF9) } });
             this.canvas3d.animate();
diff --git a/src/mol-plugin/layout.ts b/src/mol-plugin/layout.ts
index 63b8f19be005def858b246ed5d7e31317289b9e4..715a84be5cd68db524c193d3add84564c831636b 100644
--- a/src/mol-plugin/layout.ts
+++ b/src/mol-plugin/layout.ts
@@ -176,7 +176,7 @@ export class PluginLayout extends PluginComponent<PluginLayoutStateProps> {
     }
 
     constructor(private context: PluginContext) {
-        super({ ...PD.getDefaultValues(PluginLayoutStateParams), ...context.spec.initialLayout });
+        super({ ...PD.getDefaultValues(PluginLayoutStateParams), ...(context.spec.layout && context.spec.layout.initial) });
 
         PluginCommands.Layout.Update.subscribe(context, e => this.updateProps(e.state));
 
diff --git a/src/mol-plugin/spec.ts b/src/mol-plugin/spec.ts
index 2bfb64ecabb86f3b97d3fbdf0a748c65cd0bfa7f..3a9611eb8d91f954dc718e7c177affaddbde2b48 100644
--- a/src/mol-plugin/spec.ts
+++ b/src/mol-plugin/spec.ts
@@ -16,7 +16,14 @@ interface PluginSpec {
     behaviors: PluginSpec.Behavior[],
     animations?: PluginStateAnimation[],
     customParamEditors?: [StateAction | StateTransformer, StateTransformParameters.Class][],
-    initialLayout?: PluginLayoutStateProps
+    layout?: {
+        initial?: PluginLayoutStateProps,
+        controls?: {
+            left?: React.ComponentClass | 'none',
+            right?: React.ComponentClass | 'none',
+            bottom?: React.ComponentClass | 'none'
+        }
+    }
 }
 
 namespace PluginSpec {
@@ -38,4 +45,10 @@ namespace PluginSpec {
     export function Behavior<T extends StateTransformer>(transformer: T, defaultParams?: StateTransformer.Params<T>): Behavior {
         return { transformer, defaultParams };
     }
+
+    export interface LayoutControls {
+        left?: React.ComponentClass | 'none',
+        right?: React.ComponentClass | 'none',
+        bottom?: React.ComponentClass | 'none'
+    }
 }
\ No newline at end of file
diff --git a/src/mol-plugin/ui/plugin.tsx b/src/mol-plugin/ui/plugin.tsx
index 27c4304a2f9fd5b9246c5e80da8a89cad0a01c3b..1a2b0615822f95389d9175161478dd34bce634d0 100644
--- a/src/mol-plugin/ui/plugin.tsx
+++ b/src/mol-plugin/ui/plugin.tsx
@@ -43,35 +43,44 @@ class Layout extends PluginUIComponent {
         this.subscribe(this.plugin.layout.events.updated, () => this.forceUpdate());
     }
 
-    region(kind: 'left' | 'right' | 'bottom' | 'main', element: JSX.Element) {
+    region(kind: 'left' | 'right' | 'bottom' | 'main', Element: React.ComponentClass) {
         return <div className={`msp-layout-region msp-layout-${kind}`}>
             <div className='msp-layout-static'>
-                {element}
+                <Element />
             </div>
         </div>;
     }
 
     render() {
         const layout = this.plugin.layout.state;
+        const spec = this.plugin.spec.layout && this.plugin.spec.layout.controls;
+
         return <div className='msp-plugin'>
             <div className={`msp-plugin-content ${layout.isExpanded ? 'msp-layout-expanded' : 'msp-layout-standard msp-layout-standard-outside'}`}>
                 <div className={layout.showControls ? 'msp-layout-hide-top' : 'msp-layout-hide-top msp-layout-hide-right msp-layout-hide-bottom msp-layout-hide-left'}>
-                    {this.region('main', <ViewportWrapper />)}
-                    {layout.showControls && this.region('left', <State />)}
-                    {layout.showControls && this.region('right', <div className='msp-scrollable-container msp-right-controls'>
-                        <CurrentObject />
-                        <AnimationControls />
-                        <CameraSnapshots />
-                        <StateSnapshots />
-                    </div>)}
-                    {layout.showControls && this.region('bottom', <Log />)}
+                    {this.region('main', ViewportWrapper)}
+                    {layout.showControls && spec && spec.left !== 'none' && this.region('left', (spec && spec.left) || State)}
+                    {layout.showControls && spec && spec.right !== 'none' && this.region('right', (spec && spec.right) || ControlsWrapper)}
+                    {layout.showControls && spec && spec.bottom !== 'none' && this.region('bottom', (spec && spec.bottom) || Log)}
                 </div>
             </div>
         </div>;
     }
 }
 
-export class ViewportWrapper extends PluginUIComponent {    
+
+export class ControlsWrapper extends PluginUIComponent {
+    render() {
+        return <div className='msp-scrollable-container msp-right-controls'>
+            <CurrentObject />
+            <AnimationControls />
+            <CameraSnapshots />
+            <StateSnapshots />
+        </div>;
+    }
+}
+
+export class ViewportWrapper extends PluginUIComponent {
     render() {
         return <>
             <Viewport />