diff --git a/package.json b/package.json
index 311b2505203e9d7ff6fd83cad9709547bdeb0b80..811c6aa53863504d3a8c7a078a528a6f889949d4 100644
--- a/package.json
+++ b/package.json
@@ -108,7 +108,6 @@
     "extra-watch-webpack-plugin": "^1.0.3",
     "file-loader": "^6.2.0",
     "fs-extra": "^10.0.0",
-    "gl": "^4.9.2",
     "graphql": "^15.6.0",
     "http-server": "^13.0.2",
     "jest": "^27.2.4",
@@ -153,5 +152,8 @@
     "tslib": "^2.3.1",
     "util.promisify": "^1.1.1",
     "xhr2": "^0.2.1"
+  },
+  "optionalDependencies": {
+    "gl": "^4.9.2"
   }
 }
diff --git a/src/mol-gl/_spec/cylinders.spec.ts b/src/mol-gl/_spec/cylinders.spec.ts
index 5e27ee6794d82bb12e498885e654c2a99b5b935b..7b1f0fc8d72d648a24b45438da37a8b37ab0280b 100644
--- a/src/mol-gl/_spec/cylinders.spec.ts
+++ b/src/mol-gl/_spec/cylinders.spec.ts
@@ -6,9 +6,8 @@
 
 import { createRenderObject } from '../render-object';
 import { Scene } from '../scene';
-import getGLContext from 'gl';
+import { getGLContext, tryGetGLContext } from './gl';
 import { setDebugMode } from '../../mol-util/debug';
-import { createRenderer } from './renderer.spec';
 import { ColorNames } from '../../mol-util/color/names';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { Cylinders } from '../../mol-geo/geometry/cylinders/cylinders';
@@ -22,18 +21,16 @@ export function createCylinders() {
 }
 
 describe('cylinders', () => {
-    const gl = getGLContext(32, 32);
-    const { ctx } = createRenderer(gl);
+    const ctx = tryGetGLContext(32, 32, { fragDepth: true });
 
-    (ctx.extensions.fragDepth ? it : it.skip)('basic', async () => {
-        const gl = getGLContext(32, 32);
-        const { ctx } = createRenderer(gl);
+    (ctx ? it : it.skip)('basic', async () => {
+        const ctx = getGLContext(32, 32);
         const scene = Scene.create(ctx);
         const cylinders = createCylinders();
         scene.add(cylinders);
         setDebugMode(true);
         expect(() => scene.commit()).not.toThrow();
         setDebugMode(false);
-        gl.getExtension('STACKGL_destroy_context')?.destroy();
+        ctx.destroy();
     });
 });
\ No newline at end of file
diff --git a/src/mol-gl/_spec/direct-volume.spec.ts b/src/mol-gl/_spec/direct-volume.spec.ts
index e085ec18265a7764f2e0929e149ffde2a235f48a..8ae6e8092980e33f985530e1abdbcdac7a4aac41 100644
--- a/src/mol-gl/_spec/direct-volume.spec.ts
+++ b/src/mol-gl/_spec/direct-volume.spec.ts
@@ -6,9 +6,8 @@
 
 import { createRenderObject } from '../render-object';
 import { Scene } from '../scene';
-import getGLContext from 'gl';
+import { getGLContext, tryGetGLContext } from './gl';
 import { setDebugMode } from '../../mol-util/debug';
-import { createRenderer } from './renderer.spec';
 import { ColorNames } from '../../mol-util/color/names';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { DirectVolume } from '../../mol-geo/geometry/direct-volume/direct-volume';
@@ -22,15 +21,16 @@ export function createDirectVolume() {
 }
 
 describe('direct-volume', () => {
-    it('basic', async () => {
-        const gl = getGLContext(32, 32);
-        const { ctx } = createRenderer(gl);
+    const ctx = tryGetGLContext(32, 32);
+
+    (ctx ? it : it.skip)('basic', async () => {
+        const ctx = getGLContext(32, 32);
         const scene = Scene.create(ctx);
         const directVolume = createDirectVolume();
         scene.add(directVolume);
         setDebugMode(true);
         expect(() => scene.commit()).not.toThrow();
         setDebugMode(false);
-        gl.getExtension('STACKGL_destroy_context')?.destroy();
+        ctx.destroy();
     });
 });
\ No newline at end of file
diff --git a/src/mol-gl/_spec/gl.ts b/src/mol-gl/_spec/gl.ts
new file mode 100644
index 0000000000000000000000000000000000000000..eadedd99817cde64b2e399ef74fcbde1ab2318cb
--- /dev/null
+++ b/src/mol-gl/_spec/gl.ts
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { createContext } from '../webgl/context';
+
+export function getGLContext(width: number, height: number) {
+    const gl = require('gl')(width, height, {
+        alpha: true,
+        depth: true,
+        premultipliedAlpha: true,
+        preserveDrawingBuffer: true,
+        antialias: true,
+    });
+    return createContext(gl);
+}
+
+export function tryGetGLContext(width: number, height: number, requiredExtensions?: { fragDepth?: boolean }) {
+    try {
+        const ctx = getGLContext(width, height);
+        if (requiredExtensions?.fragDepth && !ctx.extensions.fragDepth) return;
+        return ctx;
+    } catch (e) {
+        return;
+    }
+}
\ No newline at end of file
diff --git a/src/mol-gl/_spec/image.spec.ts b/src/mol-gl/_spec/image.spec.ts
index bf5a2e606f8e6f2e591abc34d682bb199292ddae..aee29d4213a035a079ce3d679dd5c0df16eb074a 100644
--- a/src/mol-gl/_spec/image.spec.ts
+++ b/src/mol-gl/_spec/image.spec.ts
@@ -6,9 +6,8 @@
 
 import { createRenderObject } from '../render-object';
 import { Scene } from '../scene';
-import getGLContext from 'gl';
+import { getGLContext, tryGetGLContext } from './gl';
 import { setDebugMode } from '../../mol-util/debug';
-import { createRenderer } from './renderer.spec';
 import { ColorNames } from '../../mol-util/color/names';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { Image } from '../../mol-geo/geometry/image/image';
@@ -22,15 +21,16 @@ export function createImage() {
 }
 
 describe('image', () => {
-    it('basic', async () => {
-        const gl = getGLContext(32, 32);
-        const { ctx } = createRenderer(gl);
+    const ctx = tryGetGLContext(32, 32);
+
+    (ctx ? it : it.skip)('basic', async () => {
+        const ctx = getGLContext(32, 32);
         const scene = Scene.create(ctx);
         const image = createImage();
         scene.add(image);
         setDebugMode(true);
         expect(() => scene.commit()).not.toThrow();
         setDebugMode(false);
-        gl.getExtension('STACKGL_destroy_context')?.destroy();
+        ctx.destroy();
     });
 });
\ No newline at end of file
diff --git a/src/mol-gl/_spec/lines.spec.ts b/src/mol-gl/_spec/lines.spec.ts
index 07527eb26868ccc6ff20f67d83f37d4c8636ef96..c1f88f8d9650e548cee9bb32909de11047734df5 100644
--- a/src/mol-gl/_spec/lines.spec.ts
+++ b/src/mol-gl/_spec/lines.spec.ts
@@ -6,9 +6,8 @@
 
 import { createRenderObject } from '../render-object';
 import { Scene } from '../scene';
-import getGLContext from 'gl';
+import { getGLContext, tryGetGLContext } from './gl';
 import { setDebugMode } from '../../mol-util/debug';
-import { createRenderer } from './renderer.spec';
 import { ColorNames } from '../../mol-util/color/names';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { Lines } from '../../mol-geo/geometry/lines/lines';
@@ -22,15 +21,16 @@ export function createLines() {
 }
 
 describe('lines', () => {
-    it('basic', async () => {
-        const gl = getGLContext(32, 32);
-        const { ctx } = createRenderer(gl);
+    const ctx = tryGetGLContext(32, 32);
+
+    (ctx ? it : it.skip)('basic', async () => {
+        const ctx = getGLContext(32, 32);
         const scene = Scene.create(ctx);
         const lines = createLines();
         scene.add(lines);
         setDebugMode(true);
         expect(() => scene.commit()).not.toThrow();
         setDebugMode(false);
-        gl.getExtension('STACKGL_destroy_context')?.destroy();
+        ctx.destroy();
     });
 });
\ No newline at end of file
diff --git a/src/mol-gl/_spec/mesh.spec.ts b/src/mol-gl/_spec/mesh.spec.ts
index 18d2c4260b5bf6e941730fa5fd190ecdef1e8b46..c1b00f14f11b9f0a87c3bec67464c9bcec8f3b19 100644
--- a/src/mol-gl/_spec/mesh.spec.ts
+++ b/src/mol-gl/_spec/mesh.spec.ts
@@ -6,9 +6,8 @@
 
 import { createRenderObject } from '../render-object';
 import { Scene } from '../scene';
-import getGLContext from 'gl';
+import { getGLContext, tryGetGLContext } from './gl';
 import { setDebugMode } from '../../mol-util/debug';
-import { createRenderer } from './renderer.spec';
 import { ColorNames } from '../../mol-util/color/names';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { Mesh } from '../../mol-geo/geometry/mesh/mesh';
@@ -22,15 +21,16 @@ export function createMesh() {
 }
 
 describe('mesh', () => {
-    it('basic', async () => {
-        const gl = getGLContext(32, 32);
-        const { ctx } = createRenderer(gl);
+    const ctx = tryGetGLContext(32, 32);
+
+    (ctx ? it : it.skip)('basic', async () => {
+        const ctx = getGLContext(32, 32);
         const scene = Scene.create(ctx);
         const mesh = createMesh();
         scene.add(mesh);
         setDebugMode(true);
         expect(() => scene.commit()).not.toThrow();
         setDebugMode(false);
-        gl.getExtension('STACKGL_destroy_context')?.destroy();
+        ctx.destroy();
     });
 });
\ No newline at end of file
diff --git a/src/mol-gl/_spec/points.spec.ts b/src/mol-gl/_spec/points.spec.ts
index f4b3db772e07576165043d005dac11521cc31e0a..358b3094d90b09565d2bae1aa1dcbbaff729e9dd 100644
--- a/src/mol-gl/_spec/points.spec.ts
+++ b/src/mol-gl/_spec/points.spec.ts
@@ -6,9 +6,8 @@
 
 import { createRenderObject } from '../render-object';
 import { Scene } from '../scene';
-import getGLContext from 'gl';
+import { getGLContext, tryGetGLContext } from './gl';
 import { setDebugMode } from '../../mol-util/debug';
-import { createRenderer } from './renderer.spec';
 import { ColorNames } from '../../mol-util/color/names';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { Points } from '../../mol-geo/geometry/points/points';
@@ -22,15 +21,16 @@ export function createPoints() {
 }
 
 describe('points', () => {
-    it('basic', async () => {
-        const gl = getGLContext(32, 32);
-        const { ctx } = createRenderer(gl);
+    const ctx = tryGetGLContext(32, 32);
+
+    (ctx ? it : it.skip)('basic', async () => {
+        const ctx = getGLContext(32, 32);
         const scene = Scene.create(ctx);
         const points = createPoints();
         scene.add(points);
         setDebugMode(true);
         expect(() => scene.commit()).not.toThrow();
         setDebugMode(false);
-        gl.getExtension('STACKGL_destroy_context')?.destroy();
+        ctx.destroy();
     });
 });
\ No newline at end of file
diff --git a/src/mol-gl/_spec/spheres.spec.ts b/src/mol-gl/_spec/spheres.spec.ts
index 0fcf7f959e140d23fc2364acb23d564844bcc5dc..ecf721aaf719e0b00f25d8014e0d48385804e674 100644
--- a/src/mol-gl/_spec/spheres.spec.ts
+++ b/src/mol-gl/_spec/spheres.spec.ts
@@ -6,9 +6,8 @@
 
 import { createRenderObject } from '../render-object';
 import { Scene } from '../scene';
-import getGLContext from 'gl';
+import { getGLContext, tryGetGLContext } from './gl';
 import { setDebugMode } from '../../mol-util/debug';
-import { createRenderer } from './renderer.spec';
 import { ColorNames } from '../../mol-util/color/names';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { Spheres } from '../../mol-geo/geometry/spheres/spheres';
@@ -22,18 +21,16 @@ export function createSpheres() {
 }
 
 describe('spheres', () => {
-    const gl = getGLContext(32, 32);
-    const { ctx } = createRenderer(gl);
+    const ctx = tryGetGLContext(32, 32, { fragDepth: true });
 
-    (ctx.extensions.fragDepth ? it : it.skip)('basic', async () => {
-        const gl = getGLContext(32, 32);
-        const { ctx } = createRenderer(gl);
+    (ctx ? it : it.skip)('basic', async () => {
+        const ctx = getGLContext(32, 32);
         const scene = Scene.create(ctx);
         const spheres = createSpheres();
         scene.add(spheres);
         setDebugMode(true);
         expect(() => scene.commit()).not.toThrow();
         setDebugMode(false);
-        gl.getExtension('STACKGL_destroy_context')?.destroy();
+        ctx.destroy();
     });
 });
\ No newline at end of file
diff --git a/src/mol-gl/_spec/text.spec.ts b/src/mol-gl/_spec/text.spec.ts
index 4b0f002a56d9918b758bc83369889a02a60e7f60..c808110eb02f0ce17b05c13c8343c2cce306d2fa 100644
--- a/src/mol-gl/_spec/text.spec.ts
+++ b/src/mol-gl/_spec/text.spec.ts
@@ -6,9 +6,8 @@
 
 import { createRenderObject } from '../render-object';
 import { Scene } from '../scene';
-import getGLContext from 'gl';
+import { getGLContext, tryGetGLContext } from './gl';
 import { setDebugMode } from '../../mol-util/debug';
-import { createRenderer } from './renderer.spec';
 import { ColorNames } from '../../mol-util/color/names';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { Text } from '../../mol-geo/geometry/text/text';
@@ -22,15 +21,16 @@ export function createText() {
 }
 
 describe('text', () => {
-    it('basic', async () => {
-        const gl = getGLContext(32, 32);
-        const { ctx } = createRenderer(gl);
+    const ctx = tryGetGLContext(32, 32);
+
+    (ctx ? it : it.skip)('basic', async () => {
+        const ctx = getGLContext(32, 32);
         const scene = Scene.create(ctx);
         const text = createText();
         scene.add(text);
         setDebugMode(true);
         expect(() => scene.commit()).not.toThrow();
         setDebugMode(false);
-        gl.getExtension('STACKGL_destroy_context')?.destroy();
+        ctx.destroy();
     });
 });
\ No newline at end of file
diff --git a/src/mol-gl/_spec/texture-mesh.spec.ts b/src/mol-gl/_spec/texture-mesh.spec.ts
index ab4736e2d48c7f633d0b01a00046fcbb8a78631c..d30cd59e630a643991be00f9c0b197eb55e1dd3a 100644
--- a/src/mol-gl/_spec/texture-mesh.spec.ts
+++ b/src/mol-gl/_spec/texture-mesh.spec.ts
@@ -6,9 +6,8 @@
 
 import { createRenderObject } from '../render-object';
 import { Scene } from '../scene';
-import getGLContext from 'gl';
+import { getGLContext, tryGetGLContext } from './gl';
 import { setDebugMode } from '../../mol-util/debug';
-import { createRenderer } from './renderer.spec';
 import { ColorNames } from '../../mol-util/color/names';
 import { ParamDefinition as PD } from '../../mol-util/param-definition';
 import { TextureMesh } from '../../mol-geo/geometry/texture-mesh/texture-mesh';
@@ -22,15 +21,16 @@ export function createTextureMesh() {
 }
 
 describe('texture-mesh', () => {
-    it('basic', async () => {
-        const gl = getGLContext(32, 32);
-        const { ctx } = createRenderer(gl);
+    const ctx = tryGetGLContext(32, 32);
+
+    (ctx ? it : it.skip)('basic', async () => {
+        const ctx = getGLContext(32, 32);
         const scene = Scene.create(ctx);
         const textureMesh = createTextureMesh();
         scene.add(textureMesh);
         setDebugMode(true);
         expect(() => scene.commit()).not.toThrow();
         setDebugMode(false);
-        gl.getExtension('STACKGL_destroy_context')?.destroy();
+        ctx.destroy();
     });
 });
\ No newline at end of file
diff --git a/src/mol-gl/webgl/context.ts b/src/mol-gl/webgl/context.ts
index 5ce242b2aa25b81dfebe4beb48376d0a3ac582c5..e094bb149bdd69aa3e226ec579793ba17c96e81a 100644
--- a/src/mol-gl/webgl/context.ts
+++ b/src/mol-gl/webgl/context.ts
@@ -358,7 +358,10 @@ export function createContext(gl: GLRenderingContext, props: Partial<{ pixelScal
             unbindResources(gl);
 
             // to aid GC
-            if (!options?.doNotForceWebGLContextLoss) gl.getExtension('WEBGL_lose_context')?.loseContext();
+            if (!options?.doNotForceWebGLContextLoss) {
+                gl.getExtension('WEBGL_lose_context')?.loseContext();
+                gl.getExtension('STACKGL_destroy_context')?.destroy();
+            }
         }
     };
 }
\ No newline at end of file