🌇 glre
glre is a simple glsl and wgsl Reactive Engine on the web and native via TypeScript, React, Solid and more.
Installation
npm install glre
DocumentationDocs : glre IntroductionAPI : glre API and featureGuide : Creating a scene | Ecosystem⛪️ reev: reactive event state manager🔮 refr: request animation frame | Staying informedgithub discussions welcome✨@tseijp twittertsei.jp articles |
What does it look like?
glre simplifies WebGl2 / WebGPU programming via TypeScript, React, Solid and more (live demo). | ![]() |
import { createRoot } from 'react-dom/client'
import { useGL, vec4, fract, position, iResolution } from 'glre/react'
const frag = vec4(fract(position.xy.div(iResolution)), 0, 1)
const App = () => {
const gl = useGL({ frag })
return <canvas ref={gl.ref} />
}
createRoot(document.getElementById('root')).render(<App />)
react-native supported (codesandbox demo)
import { GLView } from 'expo-gl'
import { registerRootComponent } from 'expo'
import { useGL, vec4, fract, position, iResolution } from 'glre/native'
const frag = vec4(fract(position.xy.div(iResolution)), 0, 1)
const App = () => {
const gl = useGL({ frag })
return <GLView style={{ flex: 1 }} onContextCreate={gl.ref} />
}
registerRootComponent(App)
solid js supported (codesandbox demo)
import { render } from 'solid-js/web'
import { onGL, vec4, fract, position, iResolution } from 'glre/solid'
const frag = c4(fract(position.xy.div(iResolution)), 0, 1)
const App = () => {
const gl = onGL({ frag })
return <canvas ref={gl.ref} />
}
render(() => <App />, document.getElementById('root'))
esm supported (codesandbox demo)
<script type="module">
import createGL from 'https://esm.sh/glre'
import { vec4, fract, position, iResolution } from 'https://esm.sh/glre'
const frag = vec4(fract(position.xy.div(iResolution)), 0, 1)
function App() {
const el = document.createElement('canvas')
createGL({ el, frag }).mount()
document.body.append(el)
}
document.addEventListener('DOMContentLoaded', App)
</script>
Node System
glre now features a powerful node-based shader system inspired by Three.js Shading Language (TSL). This system allows you to write shaders using TypeScript-like syntax and automatically handles the conversion to both WebGL2 and WebGPU shaders.
The node system provides a declarative approach to shader creation, making your code more readable, maintainable, and portable across different rendering backends.
Node Types and Functions
The node system provides various types and functions that mirror GLSL functionality:
// Basic types
import { float, int, vec2, vec3, vec4, mat3, mat4 } from 'glre'
// Built-in variables
import { position, position, iResolution, iTime } from 'glre'
// Math functions
import { sin, cos, abs, pow, mix, clamp, normalize } from 'glre'
// Texture functions
import { texture, textureCube, sampler2D } from 'glre'
Creating Custom Functions
You can define reusable shader functions using the Fn constructor:
import { Fn, vec3, sin, cos, float } from 'glre'
// Define a function that creates a rotation matrix
const rotateY = Fn(([angle = float(0)]) => {
const s = sin(angle)
const c = cos(angle)
return mat3(c, 0, s, 0, 1, 0, -s, 0, c)
})
// Use the function in your shader
const rotatedPosition = rotateY(iTime).mul(position)
Conditional Logic
The node system supports conditional operations:
import { If, vec4, lessThan } from 'glre'
// Create a conditional color output
const color = vec4(1, 0, 0, 1).toVar()
If(position.y.lessThan(0.5), () => {
color.assign(vec4(0, 1, 0, 1))
})
// Use the color in your shader
const fragment = color
Uniforms
The node system provides a powerful way to define and manage uniform values in your shaders:
import { createRoot } from 'react-dom/client'
import { useGL } from 'glre/react'
import { uniform, vec3, vec4 } from 'glre'
const uRand = uniform(1.0)
// Create a simple pulsing color shader
const App = () => {
const gl = useGL({
fragment: vec4(vec3(uRand), 1.0),
loop() {
pulse.set(0.5 + 0.5 * Math.random())
},
})
return <canvas ref={gl.ref} />
}
createRoot(document.getElementById('root')).render(<App />)
Attributes
Attributes allow you to define per-vertex data for your shaders:
import { createRoot } from 'react-dom/client'
import { useGL } from 'glre/react'
import { attribute, vec3, vec4 } from 'glre'
// Define vertex positions
const positions = attribute(-1.0, -1.0, 0.0, 1.0, -1.0, 0.0, -1.0, 1.0, 0.0, 1.0, 1.0, 0.0)
// Create a shader that uses attributes
const App = () => {
const gl = useGL({ vertex: positions })
return <canvas ref={gl.ref} />
}
createRoot(document.getElementById('root')).render(<App />)
WebGL2 and WebGPU Support
The node system is designed to work with both WebGL2 and WebGPU, providing a seamless transition path as browsers adopt the new standard. Your shader code written with the node system will automatically compile to the appropriate shading language (GLSL ES 3.0 for WebGL2, WGSL for WebGPU) based on the available renderer.









