npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, πŸ‘‹, I’m Ryan HefnerΒ  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you πŸ™

Β© 2025 – Pkg Stats / Ryan Hefner

@bigmistqke/view.gl

v0.1.9

Published

πŸ‘€ Utilities for managing WebGL resources.

Readme

πŸ‘οΈ @bigmistqke/view.gl

πŸ”§ Utilities for managing WebGL resources: uniforms, (interleaved) attributes and buffers.

  • schema-based resource management view-gl
  • compose schema and shader simultaneously via a tag template literal view-gl/tag

Table of Contents

πŸ“¦ Install

npm install @bigmistqke/view.gl
pnpm add @bigmistqke/view.gl
yarn add @bigmistqke/view.gl
bun add @bigmistqke/view.gl

πŸ‘οΈ view.gl

The view system provides type-safe WebGL resource management for uniforms, attributes, and buffers

πŸš€ Basic Usage

const { uniforms, attributes } = view(gl, program, {
  uniforms: {
    time: { kind: 'float' },
    resolution: { kind: 'vec2' },
  },
  attributes: {
    position: { kind: 'vec3' },
    uv: { kind: 'vec2' },
  },
  buffers: {
    indices: { target: 'ELEMENT_ARRAY_BUFFER' },
  },
})

// Type-safe uniform setting
uniforms.time.set(performance.now())
uniforms.resolution.set(canvas.width, canvas.height)

// Attribute management
attributes.position.set(positionData)
attributes.position.bind()

πŸ‘οΈ view

The view() function creates type-safe WebGL resource managers from a schema.

const { uniforms, attributes, buffers } = view(gl, program, schema)

Parameters:

  • gl: WebGL rendering context
  • program: Compiled WebGL program
  • schema: see ViewSchema

Returns:

  • uniforms: Type-safe uniform setters
  • attributes: Attribute managers with buffer handling
  • buffers: Generic buffer managers

πŸ“‹ ViewSchema

The complete schema object that defines all WebGL resources. Contains mappings for:

interface ViewSchema {
  uniforms: UniformSchema
  attributes: AttributeSchema
  interleavedAttributes: InterleavedAttributeSchema
  buffers: BufferSchema
}

πŸ‘€ Resource Views

Each view type can be imported individually.

🎯 uniformView

Manages shader uniform variables.

const uniforms = uniformView(gl, program, {
  time: { kind: 'float' },
  lights: { kind: 'vec3', size: 8 }, // Array uniform: vec3[8]
  transform: { kind: 'mat4' },
})

uniforms.time.set(performance.now())
uniforms.lights.set(lightData) // Takes Float32Array for array uniforms
πŸ“‹ UniformSchema

A mapping of uniform names to their configuration.

  • kind: GLSL type (see Uniform Types for full list and WebGL compatibility)
  • size: Array size (optional) - converts uniform to array type
type UniformKind =
  | 'float'
  | 'int'
  | 'bool'
  | 'vec2'
  | 'vec3'
  | 'vec4'
  | 'ivec2'
  | 'ivec3'
  | 'ivec4'
  | 'bvec2'
  | 'bvec3'
  | 'bvec4'
  | 'mat2'
  | 'mat3'
  | 'mat4'
  | 'sampler2D'
  | 'samplerCube'

interface UniformDefinition {
  kind: UniformKind
  size?: number                               // Creates array uniform with Float32Array setter
}

type UniformSchema = Record<string | symbol, UniformDefinition>

πŸ“ attributeView

Manages vertex attributes with automatic buffer creation and binding.

const attributes = attributeView(gl, program, {
  position: { kind: 'vec3' },
  instanceOffset: { kind: 'vec2', instanced: true },
})

attributes.position.set(positionData).bind()
attributes.instanceOffset.set(instanceData).bind()

gl.drawArraysInstanced(gl.TRIANGLES, 0, 3, 100)
πŸ“‹ AttributeSchema

A mapping of attribute names to their configuration.

  • kind: GLSL type (see Attribute Types for full list and WebGL compatibility)
  • instanced: Boolean (optional) - enables instanced rendering
  • buffer: Custom WebGLBuffer (optional) - by default it gets created automatically during compilation
type AttributeKind =
  | 'float'
  | 'vec2'
  | 'vec3'
  | 'vec4'
  | 'mat2'
  | 'mat3'
  | 'mat4'
  | 'int'
  | 'ivec2'
  | 'ivec3'
  | 'ivec4'

interface AttributeDefinition {
  kind: AttributeKind
  instanced?: boolean                         // Enables vertexAttribDivisor
  buffer?: WebGLBuffer                        // Custom buffer, auto-created if not provided
}

type AttributeSchema = Record<string | symbol, AttributeDefinition>

πŸ”— interleavedAttributeView

Manages interleaved vertex data with automatic stride/offset calculation.

const interleavedAttributes = interleavedAttributeView(gl, program, {
  vertexData: {
    layout: [
      { key: 'position', kind: 'vec3' },
      { key: 'normal', kind: 'vec3' },
      { key: 'uv', kind: 'vec2' },
    ],
  },
})

interleavedAttributes.vertexData.set(interleavedVertexData).bind()
πŸ“‹ InterleavedAttributeSchema

A mapping of interleaved buffer names to their layout configuration. Each layout defines multiple attributes packed into a single buffer.

  • layout: Array of attribute definitions with key and kind (see Attribute Types)
  • instanced: Boolean - applies to all attributes in layout
  • buffer: Custom WebGLBuffer (optional) - by default it gets created automatically during compilation
interface InterleavedAttributeDefinition {
  layout: Array<{
    key: string | symbol
    kind: AttributeKind
  }>
  instanced?: boolean                         // Applies vertexAttribDivisor to all attributes
  buffer?: WebGLBuffer                        // Custom buffer for interleaved data
}

type InterleavedAttributeSchema = Record<string | symbol, InterleavedAttributeDefinition>

πŸ—‚οΈ bufferView

Manages generic WebGL buffers.

const buffers = bufferView(gl, {
  indices: { target: 'ELEMENT_ARRAY_BUFFER' },
  data: { target: 'ARRAY_BUFFER', usage: 'DYNAMIC_DRAW' },
})

buffers.indices.set(indexData).bind()
buffers.data.set(dynamicData).bind()
πŸ“‹ BufferSchema

A mapping of buffer names to their configuration. Each buffer has a target type and optional usage pattern.

  • target: Buffer target ('ARRAY_BUFFER', 'ELEMENT_ARRAY_BUFFER')
  • usage: Usage pattern ('STATIC_DRAW', 'DYNAMIC_DRAW', 'STREAM_DRAW')
interface BufferDefinition {
  target: 'ARRAY_BUFFER' | 'ELEMENT_ARRAY_BUFFER'
  usage?: 'STATIC_DRAW' | 'DYNAMIC_DRAW' | 'STREAM_DRAW' // Defaults to 'STATIC_DRAW'
}

type BufferSchema = Record<string | symbol, BufferDefinition>

🏷️ view.gl/tag

Type-safe GLSL template literals with automatic schema extraction and view creation.

  • Embedded Resources: Define uniforms, attributes, and interleaved layouts directly in GLSL
  • Type Inference: Automatically infers schema types and creates type-safe view
  • Unique Variables: Prevent naming collisions using symbols for unique shader variables
  • GLSL Composition: Compose reusable GLSL fragments with automatic dependency resolution

πŸš€ Basic Usage

const vertexShader = glsl`
  ${attribute.vec3('position')}
  ${uniform.mat4('model')}
  
  varying vec2 vUv;
  
  void main() {
    vUv = uv;
    gl_Position = model * vec4(position, 1.0);
  }
`

const fragmentShader = glsl`
  ${uniform.sampler2D('texture')}
  
  varying vec2 vUv;
  
  void main() {
    gl_FragColor = texture2D(texture, vUv);
  }
`

const { program, schema } = compile(gl, vertexShader, fragmentShader)

πŸ“ glsl

Template literal processor that handles GLSL code and embedded resources. Supports interpolation of:

  • Resource tags: uniform.*(), attribute.*(), interleave()
  • GLSL fragments: Reusable shader code snippets
  • Symbol Variables: Unique variable names to prevent collisions
  • Strings: Interpolated as-is into the shader code
  • Arrays: Arrays of any supported interpolation types
const precision = 'precision mediump float;'
const functionName = Symbol('function')

const shader = glsl`
  ${precision}                                // String interpolated as-is
  ${uniform.vec2('resolution')}
  ${[attribute.vec3('position'), attribute.vec2('uv')]}  // Array interpolation
  
  vec3 ${functionName}(vec2 uv) {             // Symbol interpolated to unique identifier
    return vec3(uv, 0.5);
  }
  
  void main() {
    gl_Position = vec4(position, 1.0);
  }
`

🧩 GLSL Fragment

Compose reusable GLSL code fragments to build complex shaders:

const lighting = glsl`
  vec3 calculateLighting(vec3 normal, vec3 lightDir) {
    float diff = max(dot(normal, lightDir), 0.0);
    return vec3(diff);
  }
`

const vertexShader = glsl`
  ${attribute.vec3('direction')}
  ${attribute.vec3('normal')}
  ${lighting}                                 // Include the lighting fragment
  
  varying vec3 vLighting;
  
  void main() {
    vLighting = calculateLighting(normal, direction);
  }
`

πŸ”’ Symbol Variables

Use JavaScript symbols to prevent naming collisions:

const sum = Symbol('sum')

const sumFragment = glsl`
float ${sum}(float a, float b){
  return a + b;
}`

const shader = glsl`
${sumFragment}

void main(){
  float result = ${sum}(1.0, 2.0);
}
`

Symbols are converted to unique identifiers during the compilation of the shader.

WebGL Version Support

The glsl-function supports both WebGL1 and WebGL2 syntax, automatically using the correct keywords for resource tags:

// WebGL1 (default)
const shader = glsl`
  ${attribute.vec3('position')}               // β†’ attribute vec3 position;
  varying vec2 vUv;
`

If the shader starts with #version 300 es, resource tags generate WebGL2 syntax:

// WebGL2
const shader = glsl`#version 300 es
  ${attribute.vec3('position')}               // β†’ in vec3 position;
  out vec2 vUv;
`

🏷️ Resource Tokens

Utilities for defining WebGL resources directly in GLSL templates. These create metadata that the compile consumes to generate the typesafe schema and view.

🎯 uniform[kind](name, options?)

Define uniform variables in GLSL templates (see Uniform Types).

const uniqueTime = Symbol('time')

const shader = glsl`
  ${uniform.float('time')}                    // String key
  ${uniform.float(uniqueTime)}                // Symbol key
  ${uniform.vec3('lights', { size: 8 })}      // Array uniform: vec3[8]
  
  void main() {
    float wave = sin(time * 2.0 + ${uniqueTime});
    vec3 totalLight = vec3(0.0);
    for(int i = 0; i < 8; i++) {
      totalLight += lights[i] * wave;
    }
    gl_FragColor = vec4(totalLight, 1.0);
  }
`

Parameters:

  • name: Uniform name (string or symbol for unique variables)
  • options: Optional configuration object
    • size: Array size (creates array uniform with Float32Array setter)

πŸ“ attribute[kind](name, options?)

Define vertex attributes in GLSL templates (see Attribute Types).

const uniquePosition = Symbol('position')

const vertexShader = glsl`
  ${attribute.vec3('position')}               // String key
  ${attribute.vec3(uniquePosition)}           // Symbol key
  ${attribute.vec2('offset', { instanced: true })}
  
  void main() {
    gl_Position = vec4(position + vec3(offset, 0.0), 1.0);
  }
`

Parameters:

  • name: Attribute name (string or symbol for unique variables)
  • options: Optional configuration object
    • instanced: Boolean - enables instanced rendering with vertexAttribDivisor
    • buffer: Custom WebGLBuffer (optional)

πŸ”— interleave(name, layout, options?)

Define interleaved attribute layouts for efficient vertex data.

const uniqueVertexData = Symbol('vertexData')
const uniquePosition = Symbol('position')

const vertexShader = glsl`
  ${interleave('vertexData', [
    // String key
    { key: 'position', kind: 'vec3' },
    { key: 'uv', kind: 'vec2' },
  ])}
  ${interleave(uniqueVertexData, [
    // Symbol key
    { key: uniquePosition, kind: 'vec3' },    // Symbol keys in layout
    { key: 'uv', kind: 'vec2' },
  ])}
  
  void main() {
    gl_Position = vec4(position + vec3(uv, 0.0), 1.0);
  }
`

Parameters:

  • name: Buffer name (string or symbol for unique variables)
  • layout: Array of attribute definitions
    • key: Attribute name (string or symbol for unique variables)
    • kind: GLSL type (see Attribute Types)
  • options: Optional configuration object
    • instanced: Boolean - applies vertexAttribDivisor to all attributes

βš™οΈ compile(gl, vertex, fragment, overrideSchema?)

Compiles shaders to a WebGLProgram and extracts typesafe schema and view.

πŸ”„ compile.toQuad(gl, fragment, options?)

Convenient helper for fullscreen quad rendering with fragment shaders. Automatically creates a vertex shader with a quad geometry and handles vertex buffer setup.

const { program, schema, view } = compile.toQuad(gl, fragmentShader)

// Ready to render - no vertex setup required
view.uniforms.time.set(performance.now())
gl.drawArrays(gl.TRIANGLES, 0, 6)

Perfect for:

  • Fragment shader effects (ray-marching, post-processing, etc.)
  • Fullscreen compute-style shaders
  • Quick prototyping and experimentation

Generated vertex shader:

  • Creates a_quad attribute automatically
  • Outputs uv varying (same as vertex position: [-1,1] range)
  • Sets up clip-space quad covering the entire screen

Parameters:

  • gl: WebGL rendering context
  • fragment: Fragment shader with embedded resources
  • options: Optional compilation options (same as compile())

Returns: Same as compile() with pre-configured quad rendering

const { program, schema, view, vertex, fragment } = compile(gl, vertexShader, fragmentShader)

// Use the view directly
view.uniforms.time.set(performance.now())
view.attributes.position.set(vertexData).bind()

// Access the compiled shader strings
console.log(vertex)                           // Compiled vertex shader GLSL
console.log(fragment)                         // Compiled fragment shader GLSL

// Or access the extracted schema
console.log(schema.uniforms)                  // { time: { kind: 'float' }, ... }
console.log(schema.attributes)                // { position: { kind: 'vec3' }, ... }

Override Schema:

You can provide an optional override schema to enhance or override the automatically extracted schema:

const { program, schema, view } = compile(gl, vertexShader, fragmentShader, {
  uniforms: {
    // Add additional uniforms not automatically inferred
    customTime: { kind: 'float' },
  },
  buffers: {
    // Add buffer definitions
    indices: { target: 'ELEMENT_ARRAY_BUFFER' },
  },
})

// The override schema is merged with the extracted schema
view.uniforms.customTime.set(123.45)
view.buffers.indices.set(indexData).bind()

Returns:

  • program: Compiled WebGL program
  • schema: Merged schema (extracted + override)
  • view: Ready-to-use view with type-safe resource access
  • vertex: Compiled vertex shader GLSL string
  • fragment: Compiled fragment shader GLSL string

πŸ” compile.toString(shader)

Converts a GLSL tagged template to a shader string without compilation of the WebGLProgram. Useful for debugging or when you need the raw shader code.

const vertexShader = glsl`
  ${attribute.vec3('position')}
  ${uniform.mat4('mvpMatrix')}
  
  void main() {
    gl_Position = mvpMatrix * vec4(position, 1.0);
  }
`

const shaderString = compile.toString(vertexShader)
console.log(shaderString)
// Output:
// attribute vec3 position;
// uniform mat4 mvpMatrix;
// 
// void main() {
//   gl_Position = mvpMatrix * vec4(position, 1.0);
// }

Features:

  • Converts resource tags to GLSL declarations
  • Handles WebGL1/WebGL2 syntax automatically
  • Resolves symbol variables to unique identifiers
  • Processes nested GLSL fragments and arrays

πŸ“‹ compile.toSchema(shader)

Extracts the ViewSchema from a GLSL tagged template without compilation of the WebGLProgram. Returns the type-safe schema that could be used by view().

const shader = glsl`
  ${uniform.float('time')}
  ${uniform.vec3('lightPos', { size: 4 })}
  ${attribute.vec3('position')}
  ${interleave('vertexData', [
    attribute.vec2('uv'),
    attribute.vec4('color')
  ])}
`

const schema = compile.toSchema(shader)
console.log(schema)
// Output:
// {
//   uniforms: {
//     time: { kind: 'float' },
//     lightPos: { kind: 'vec3', size: 4 }
//   },
//   attributes: {
//     position: { kind: 'vec3' }
//   },
//   interleavedAttributes: {
//     vertexData: {
//       layout: [
//         { key: 'uv', kind: 'vec2' },
//         { key: 'color', kind: 'vec4' }
//       ],
//       instanced: false
//     }
//   }
// }

Use Cases:

  • Analyze shader resources without GL context
  • Generate TypeScript types from shaders
  • Validate shader compatibility before compilation
  • Build tooling around shader resources

When manually constructing GLSL strings, use toID() to convert symbols to valid, unique identifiers:

const u_time = Symbol('time')
const a_position = Symbol('position')

const vertex = `
  attribute vec3 ${toID(a_position)};
  uniform float ${toID(u_time)};

  void main() {
    gl_Position = vec4(${toID(a_position)}, ${toID(u_time)});
  }
`

const fragment = `
  precision mediump float;
  uniform float ${toID(u_time)};

  void main() {
    gl_FragColor = vec4(1.0, 1.0, 1.0, sin(${toID(u_time)}));
  }
`

const program = createProgram(gl, vertex, fragment)

const { attributes, uniforms } = view(gl, program, {
  uniforms: { [u_time]: { kind: 'float' } },
  attributes: { [a_position]: { kind: 'vec3' } },
})

attributes[a_position].set(vertexData)
uniforms[u_time].set(performance.now())

πŸ› οΈ Utils

πŸ—οΈ createProgram

Creates and links a WebGL program from vertex and fragment shader sources.

const program = createProgram(gl, vertexShaderSource, fragmentShaderSource)

πŸ–ΌοΈ createTexture

Creates a WebGL texture with specified parameters.

const texture = createTexture(
  gl,
  {
    width: 512,
    height: 512,
    internalFormat: 'RGBA',
    format: 'RGBA',
    type: 'UNSIGNED_BYTE',
    minFilter: 'LINEAR',
    magFilter: 'LINEAR',
    wrapS: 'CLAMP_TO_EDGE',
    wrapT: 'CLAMP_TO_EDGE',
  },
  data,
)

Automatically validates WebGL2-only formats and provides fallbacks for WebGL1.

πŸ–₯️ createFramebuffer

Creates a framebuffer with attached texture for render-to-texture operations.

const { framebuffer, texture } = createFramebuffer(gl, {
  width: 512,
  height: 512,
  attachment: 'color',
  internalFormat: 'RGBA',
  format: 'RGBA',
  type: 'UNSIGNED_BYTE',
})

Supports color, depth, stencil, and combined depth-stencil attachments with completeness validation.

πŸ” WebGL Type Compatibility

🎯 Uniform Types

| Type | WebGL 1 | WebGL 2 | | ---------------------- | ------- | ------- | | float | βœ… | βœ… | | int | βœ… | βœ… | | bool | βœ… | βœ… | | vec2 | βœ… | βœ… | | vec3 | βœ… | βœ… | | vec4 | βœ… | βœ… | | ivec2 | βœ… | βœ… | | ivec3 | βœ… | βœ… | | ivec4 | βœ… | βœ… | | bvec2 | βœ… | βœ… | | bvec3 | βœ… | βœ… | | bvec4 | βœ… | βœ… | | mat2 | βœ… | βœ… | | mat3 | βœ… | βœ… | | mat4 | βœ… | βœ… | | sampler2D | βœ… | βœ… | | samplerCube | βœ… | βœ… | | uint | ❌ | βœ… | | uvec2 | ❌ | βœ… | | uvec3 | ❌ | βœ… | | uvec4 | ❌ | βœ… | | mat2x3 | ❌ | βœ… | | mat2x4 | ❌ | βœ… | | mat3x2 | ❌ | βœ… | | mat3x4 | ❌ | βœ… | | mat4x2 | ❌ | βœ… | | mat4x3 | ❌ | βœ… | | sampler3D | ❌ | βœ… | | sampler2DArray | ❌ | βœ… | | sampler2DShadow | ❌ | βœ… | | samplerCubeShadow | ❌ | βœ… | | sampler2DArrayShadow | ❌ | βœ… | | isampler2D | ❌ | βœ… | | isampler3D | ❌ | βœ… | | isamplerCube | ❌ | βœ… | | isampler2DArray | ❌ | βœ… | | usampler2D | ❌ | βœ… | | usampler3D | ❌ | βœ… | | usamplerCube | ❌ | βœ… | | usampler2DArray | ❌ | βœ… |

πŸ“ Attribute Types

| Type | WebGL 1 | WebGL 2 | | -------- | ------- | ------- | | float | βœ… | βœ… | | vec2 | βœ… | βœ… | | vec3 | βœ… | βœ… | | vec4 | βœ… | βœ… | | mat2 | βœ… | βœ… | | mat3 | βœ… | βœ… | | mat4 | βœ… | βœ… | | int | ❌ | βœ… | | ivec2 | ❌ | βœ… | | ivec3 | ❌ | βœ… | | ivec4 | ❌ | βœ… | | uint | ❌ | βœ… | | uvec2 | ❌ | βœ… | | uvec3 | ❌ | βœ… | | uvec4 | ❌ | βœ… | | mat2x3 | ❌ | βœ… | | mat2x4 | ❌ | βœ… | | mat3x2 | ❌ | βœ… | | mat3x4 | ❌ | βœ… | | mat4x2 | ❌ | βœ… | | mat4x3 | ❌ | βœ… |