diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9bb256b75e15f03b0d496817cbf0551b051f3116..894e8bd12bcfa09bb59879b6910f7e9bfdd23e54 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,10 @@ Note that since we don't clearly distinguish between a public and private interf
 
 ## [Unreleased]
 
+- Add ``PluginFeatureDetection`` and disable WBOIT in Safari 15.
+
+## [v3.0.0-dev.7] - 2021-12-20
+
 - Reduce number of created programs/shaders
     - Support specifying variants when creating graphics render-items
     - Change double-side shader param from define to uniform
diff --git a/package-lock.json b/package-lock.json
index 1978aa826aa419118c5fe1b515dcd8b69fd9654c..62691b84a4b42723bcd246aaedbec564b0143b14 100644
Binary files a/package-lock.json and b/package-lock.json differ
diff --git a/package.json b/package.json
index 051b1b593da0fe15779c35c176af728edab8790f..4e20e326c8b302b60aa97b8da99db9d757465222 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "molstar",
-  "version": "3.0.0-dev.6",
+  "version": "3.0.0-dev.7",
   "description": "A comprehensive macromolecular library.",
   "homepage": "https://github.com/molstar/molstar#readme",
   "repository": {
diff --git a/src/mol-plugin/config.ts b/src/mol-plugin/config.ts
index 4e12347af3d4241dfe62190f1176446d24676e8e..99fc21ae8cfaca5e11ec447d28dc8b64cb46e04e 100644
--- a/src/mol-plugin/config.ts
+++ b/src/mol-plugin/config.ts
@@ -10,6 +10,7 @@ import { PluginContext } from './context';
 import { PdbDownloadProvider } from '../mol-plugin-state/actions/structure';
 import { EmdbDownloadProvider } from '../mol-plugin-state/actions/volume';
 import { StructureRepresentationPresetProvider } from '../mol-plugin-state/builder/structure/representation-preset';
+import { PluginFeatureDetection } from './features';
 
 export class PluginConfigItem<T = any> {
     toString() { return this.key; }
@@ -19,31 +20,6 @@ export class PluginConfigItem<T = any> {
 
 function item<T>(key: string, defaultValue?: T) { return new PluginConfigItem(key, defaultValue); }
 
-
-export function preferWebGl1() {
-    if (typeof navigator === 'undefined' || typeof window === 'undefined') return false;
-
-    // WebGL2 isn't working in MacOS 12.0.1 Safari 15.1, 15.2. It is working in Safari 15.4 tech preview, so disabling all versions before that.
-    // prefer webgl 1 based on the userAgent substring
-    const unpportedSafariVersions = [
-        'Version/15.1 Safari',
-        'Version/15.2 Safari',
-        'Version/15.3 Safari'
-    ];
-    if (unpportedSafariVersions.some(v => navigator.userAgent.indexOf(v) > 0)) {
-        return true;
-    }
-
-    // Check for iOS device which enabled WebGL2 recently but it doesn't seem
-    // to be full up to speed yet.
-
-    // adapted from https://stackoverflow.com/questions/9038625/detect-if-device-is-ios
-    const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
-    const isAppleDevice = navigator.userAgent.includes('Macintosh');
-    const isTouchScreen = navigator.maxTouchPoints >= 4; // true for iOS 13 (and hopefully beyond)
-    return !(window as any).MSStream && (isIOS || (isAppleDevice && isTouchScreen));
-}
-
 export const PluginConfig = {
     item,
     General: {
@@ -53,10 +29,10 @@ export const PluginConfig = {
         PixelScale: item('plugin-config.pixel-scale', 1),
         PickScale: item('plugin-config.pick-scale', 0.25),
         PickPadding: item('plugin-config.pick-padding', 3),
-        EnableWboit: item('plugin-config.enable-wboit', true),
+        EnableWboit: item('plugin-config.enable-wboit', PluginFeatureDetection.wboit),
         // as of Oct 1 2021, WebGL 2 doesn't work on iOS 15.
         // TODO: check back in a few weeks to see if it was fixed
-        PreferWebGl1: item('plugin-config.prefer-webgl1', preferWebGl1()),
+        PreferWebGl1: item('plugin-config.prefer-webgl1', PluginFeatureDetection.preferWebGl1),
     },
     State: {
         DefaultServer: item('plugin-state.server', 'https://webchem.ncbr.muni.cz/molstar-state'),
diff --git a/src/mol-plugin/features.ts b/src/mol-plugin/features.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ad04c71c6287bbae2ca4f8439632503403ea3b71
--- /dev/null
+++ b/src/mol-plugin/features.ts
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author David Sehnal <david.sehnal@gmail.com>
+ */
+
+export const PluginFeatureDetection = {
+    get preferWebGl1() {
+        if (typeof navigator === 'undefined' || typeof window === 'undefined') return false;
+
+        // WebGL2 isn't working in MacOS 12.0.1 Safari 15.1, 15.2. It is working in Safari 15.4 tech preview, so disabling all versions before that.
+        // prefer webgl 1 based on the userAgent substring
+        const unpportedSafariVersions = [
+            'Version/15.1 Safari',
+            'Version/15.2 Safari',
+            'Version/15.3 Safari'
+        ];
+        if (unpportedSafariVersions.some(v => navigator.userAgent.indexOf(v) > 0)) {
+            return true;
+        }
+
+        // Check for iOS device which enabled WebGL2 recently but it doesn't seem
+        // to be full up to speed yet.
+
+        // adapted from https://stackoverflow.com/questions/9038625/detect-if-device-is-ios
+        const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
+        const isAppleDevice = navigator.userAgent.includes('Macintosh');
+        const isTouchScreen = navigator.maxTouchPoints >= 4; // true for iOS 13 (and hopefully beyond)
+        return !(window as any).MSStream && (isIOS || (isAppleDevice && isTouchScreen));
+    },
+    get wboit() {
+        if (typeof navigator === 'undefined' || typeof window === 'undefined') return true;
+
+        // disable Wboit in Safari 15
+        return !/Version\/15.\d Safari/.test(navigator.userAgent);
+    }
+};
\ No newline at end of file