JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://cdn.rawgit.com/kbirk/alfador/master/build/alfador.min.js"></script>
<script src="https://cdn.rawgit.com/kbirk/esper/f517a76f/build/esper.min.js"></script>
<canvas id="glcanvas"></canvas>

CSS

canvas {
    position: fixed;
    margin: 0;
    padding: 0;
    border: 0;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

JavaScript

let phong = {
	// phong vertex shader
	vert :
		`
		// vertex attributes
		attribute highp vec3 aPosition;
		attribute highp vec3 aNormal;
		attribute highp vec2 aTexCoord;
		// uniforms
		uniform highp mat4 uModelMatrix;
		uniform highp mat4 uViewMatrix;
		uniform highp mat4 uProjectionMatrix;
		// varyings
		varying highp vec3 vMVPosition;
		varying highp vec3 vMVNormal;
		varying highp vec2 vTexCoord;
		void main() {
			highp vec4 mvPos = uViewMatrix * uModelMatrix * vec4(aPosition, 1.0);
			gl_Position = uProjectionMatrix * mvPos;
			vMVPosition = vec3(mvPos) / mvPos.w;
			vMVNormal = mat3(uViewMatrix * uModelMatrix) * aNormal;
			vTexCoord = aTexCoord;
		}
		`,
	// phong fragment shader
	frag :
		`
		// uniforms
		uniform highp mat4 uViewMatrix;
		uniform highp vec3 uLightPosition;
		uniform highp sampler2D uTextureSampler;
		// varyings
		varying highp vec3 vMVPosition;
		varying highp vec3 vMVNormal;
		varying highp vec2 vTexCoord;
		void main() {
			highp vec4 texelColor = texture2D(uTextureSampler, vTexCoord);
			highp vec3 vLight = vec3(uViewMatrix * vec4(uLightPosition, 1.0));
			highp vec3 lightDir = normalize(vLight - vMVPosition);
			highp vec3 normal = normalize(vMVNormal);
			highp float diffuse = max(dot(lightDir, normal), 0.0);
			gl_FragColor = vec4(texelColor.rgb * 0.1 + diffuse * texelColor.rgb, texelColor.a);
		}
		`
};

let cube = {
	positions: [
		// front face
		[ -1/2, -1/2,  1/2 ],
		[ 1/2, -1/2,  1/2 ],
		[  1/2,  1/2,  1/2 ],
		[ -1/2,  1/2,  1/2 ],
		// back face
		[ -1/2, -1/2, -1/2 ],
		[ -1/2,  1/2, -1/2 ],
		[  1/2,  1/2, -1/2 ],
		[  1/2, -1/2, -1/2 ],
		// top face
		[ -1/2,  1/2, -1/2 ],
		[ -1/2,  1/2,  1/2 ],
		[  1/2,  1/2,  1/2 ],
		[  1/2,  1/2, -1/2 ],
		// bottom face
		[ -1/2, -1/2, -1/2 ],
		[  1/2, -1/2, -1/2 ],
		[  1/2, -1/2,  1/2 ],
		[ -1/2, -1/2,  1/2 ],
		// right face
		[  1/2, -1/2, -1/2 ],
		[  1/2,  1/2, -1/2 ],
		[  1/2,  1/2,  1/2 ],
		[  1/2, -1/2,  1/2 ],
		// left face
		[ -1/2, -1/2, -1/2 ],
		[ -1/2,...