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

shaderkit

v0.5.0

Published

Tools and IntelliSense for GLSL and WGSL.

Downloads

482

Readme

Size Version Downloads

shaderkit

Tools and IntelliSense for GLSL and WGSL.

Table of Contents

Installation

To install, use your preferred package manager:

npm install shaderkit
yarn add shaderkit
pnpm add shaderkit

Or, use a CDN:

<script type="module">
  import * as shaderkit from 'https://unpkg.com/shaderkit'
</script>

Tokenize

Tokenizes a string of GLSL or WGSL code, returning an array of Token objects, where each Token object represents a single syntax feature in the input code.

interface Token {
  type: 'whitespace' | 'comment' | 'symbol' | 'bool' | 'float' | 'int' | 'identifier' | 'keyword'
  value: string
}
import { tokenize } from 'shaderkit'

const code = 'void main() { gl_Position = vec4(0, 0, 0, 1); }'
const tokens = tokenize(code)

console.log(tokens)

The output of the above code will be:

[
  { "type": "keyword", "value": "void" },
  { "type": "whitespace", "value": " " },
  { "type": "identifier", "value": "main" },
  { "type": "symbol", "value": "(" },
  { "type": "symbol", "value": ")" },
  { "type": "whitespace", "value": " " },
  { "type": "symbol", "value": "{" },
  { "type": "whitespace", "value": " " },
  { "type": "keyword", "value": "gl_Position" },
  { "type": "whitespace", "value": " " },
  { "type": "symbol", "value": "=" },
  { "type": "whitespace", "value": " " },
  { "type": "keyword", "value": "vec4" },
  { "type": "symbol", "value": "(" },
  { "type": "int", "value": "0" },
  { "type": "symbol", "value": "," },
  { "type": "whitespace", "value": " " },
  { "type": "int", "value": "0" },
  { "type": "symbol", "value": "," },
  { "type": "whitespace", "value": " " },
  { "type": "int", "value": "0" },
  { "type": "symbol", "value": "," },
  { "type": "whitespace", "value": " " },
  { "type": "int", "value": "1" },
  { "type": "symbol", "value": ")" },
  { "type": "symbol", "value": ";" },
  { "type": "whitespace", "value": " " },
  { "type": "symbol", "value": "}" }
]
import { tokenize } from 'shaderkit'

const code = '@vertex fn main() -> @builtin(position) vec4<f32> { return vec4(0, 0, 0, 1); }'
const tokens = tokenize(code)

console.log(tokens)

The output of the above code will be:

[
  { "type": "symbol", "value": "@" },
  { "type": "keyword", "value": "vertex" },
  { "type": "whitespace", "value": " " },
  { "type": "keyword", "value": "fn" },
  { "type": "whitespace", "value": " " },
  { "type": "identifier", "value": "main" },
  { "type": "symbol", "value": "(" },
  { "type": "symbol", "value": ")" },
  { "type": "whitespace", "value": " " },
  { "type": "symbol", "value": "->" },
  { "type": "whitespace", "value": " " },
  { "type": "symbol", "value": "@" },
  { "type": "keyword", "value": "builtin" },
  { "type": "symbol", "value": "(" },
  { "type": "keyword", "value": "position" },
  { "type": "symbol", "value": ")" },
  { "type": "whitespace", "value": " " },
  { "type": "keyword", "value": "vec4" },
  { "type": "symbol", "value": "<" },
  { "type": "keyword", "value": "f32" },
  { "type": "symbol", "value": ">" },
  { "type": "whitespace", "value": " " },
  { "type": "symbol", "value": "{" },
  { "type": "whitespace", "value": " " },
  { "type": "keyword", "value": "return" },
  { "type": "whitespace", "value": " " },
  { "type": "keyword", "value": "vec4" },
  { "type": "symbol", "value": "(" },
  { "type": "int", "value": "0" },
  { "type": "symbol", "value": "," },
  { "type": "whitespace", "value": " " },
  { "type": "int", "value": "0" },
  { "type": "symbol", "value": "," },
  { "type": "whitespace", "value": " " },
  { "type": "int", "value": "0" },
  { "type": "symbol", "value": "," },
  { "type": "whitespace", "value": " " },
  { "type": "int", "value": "1" },
  { "type": "symbol", "value": ")" },
  { "type": "symbol", "value": ";" },
  { "type": "whitespace", "value": " " },
  { "type": "symbol", "value": "}" }
]

The following are the supported token types and their descriptions:

| Type | Description | | ---------- | ------------------------------------------------------------------------- | | whitespace | A sequence of one or more whitespace characters. | | comment | A single-line or multi-line comment. | | symbol | A symbol, such as an operator or punctuation mark. | | bool | A boolean value, either true or false. | | float | A floating-point number, represented by a sequence of digits and symbols. | | int | An integer number, represented by a sequence of digits. | | identifier | A user-defined identifier, such as a variable name or function name. | | keyword | A keyword reserved by the language, such as if, else, for, etc. |

Minify

Minifies a string of GLSL or WGSL code, returning a minified version of the input code.

const minified: string = minify(code: string, {
  /** Whether to rename variables. Will call a MangleMatcher if specified. Default is `false`. */
  mangle: boolean | ((token: Token, index: number, tokens: Token[]) => boolean)
  /** A map to read and write renamed variables to when mangling. */
  mangleMap: Map<string, string>
  /** Whether to rename external variables such as uniforms or varyings. Default is `false`. */
  mangleExternals: boolean
})

To shared mangled interfaces when using mangleExternal, declare and re-use a mangleMap between shaders:

const options = { mangle: true, mangleExternals: true, mangleMap: new Map() }

// #version 300 es\nin vec2 a;out vec2 b;void main(){b=a;}
minify(`#version 300 es\nin vec2 sstt;out vec2 c;void main(){c=sstt;}`, options)

// #version 300 es\nin vec2 b;out vec4 a[gl_MaxDrawBuffers];void main(){a[0]=b.sstt;}
minify(`#version 300 es\nin vec2 c;out vec4 data[gl_MaxDrawBuffers];void main(){data[0]=c.sstt;}`, options)

Parse

Parses a string of GLSL (WGSL is WIP) code into an AST.

const ast: Program = parse(code: string)

Generate

Generates a string of GLSL (WGSL is WIP) code from an AST.

const code: string = generate(program: Program, {
  target: 'GLSL' // | 'WGSL'
})

Visit

Recurses through an AST, calling a visitor object on matching nodes.

visit(
  program: Program,
  visitors: {
    Program: {
      enter(node, ancestors) {
        // Called before any descendant nodes are processed
      },
      exit(node, ancestors) {
        // Called after all nodes are processed
      }
    },
    Identifier(node, ancestors) {
      // Called before any descendant nodes are processed (alias to enter)
    }
  } satisfies Visitors
)

AST

An Abstract Syntax Tree loosely based on ESTree for GLSL and WGSL grammars.

Node Objects

AST nodes extend Node objects which implement the following abstract interface:

interface Node {
  type: string
}

The type field is a string representing the AST variant type which can determine the interface a node implements.

Identifier

A variable identifier.

interface Identifier extends Node {
  type: 'Identifier'
  name: string
}

Literal

A shader literal representing a bool, float, int, or uint type.

interface Literal extends Node {
  type: 'Literal'
  value: string
}

ArraySpecifier

An array and its dimensions.

interface ArraySpecifier extends Node {
  type: 'ArraySpecifier'
  typeSpecifier: Identifier
  dimensions: (Literal | Identifier | null)[]
}

Program

Represents the root of an AST.

interface Program extends Node {
  type: 'Program'
  body: Statement[]
}

ExpressionStatement

An expression as a standalone statement.

interface ExpressionStatement extends Node {
  type: 'ExpressionStatement'
  expression: Expression
}

BlockStatement

A block statement.

interface BlockStatement extends Node {
  type: 'BlockStatement'
  body: Statement[]
}

DiscardStatement

A discard statement in fragment shaders.

interface DiscardStatement extends Node {
  type: 'DiscardStatement'
}

PreprocessorStatement

A GLSL preprocessor statement with an optional value.

interface PreprocessorStatement extends Node {
  type: 'PreprocessorStatement'
  name: string
  value: Expression[] | null
}

PrecisionQualifierStatement

A GLSL precision qualifier statement.

interface PrecisionQualifierStatement extends Node {
  type: 'PrecisionQualifierStatement'
  precision: PrecisionQualifier
  typeSpecifier: Identifier
}

InvariantQualifierStatement

A GLSL invariant qualifier statement.

interface InvariantQualifierStatement extends Node {
  type: 'InvariantQualifierStatement'
  typeSpecifier: Identifier
}

LayoutQualifierStatement

A layout qualifier statement.

interface LayoutQualifierStatement extends Node {
  type: 'LayoutQualifierStatement'
  layout: Record<string, string | boolean>
  qualifier: StorageQualifier
}

ReturnStatement

A return statement with an optional argument.

interface ReturnStatement extends Node {
  type: 'ReturnStatement'
  argument: Expression | null
}

BreakStatement

A break statement.

interface BreakStatement extends Node {
  type: 'BreakStatement'
}

ContinueStatement

A continue statement.

interface ContinueStatement extends Node {
  type: 'ContinueStatement'
}

IfStatement

An if-else statement.

interface IfStatement extends Node {
  type: 'IfStatement'
  test: Expression
  consequent: Statement
  alternate: Statement | null
}

SwitchStatement

A switch statement.

interface SwitchStatement extends Node {
  type: 'SwitchStatement'
  discriminant: Expression
  cases: SwitchCase[]
}

SwitchCase

A switch-case statement. test is null for a default case.

interface SwitchCase extends Node {
  type: 'SwitchCase'
  test: Expression | null
  consequent: Statement[]
}

WhileStatement

A while statement.

interface WhileStatement extends Node {
  type: 'WhileStatement'
  test: Expression
  body: Statement
}

DoWhileStatement

A do-while statement.

interface DoWhileStatement extends Node {
  type: 'DoWhileStatement'
  body: Statement
  test: Expression
}

ForStatement

A for statement.

interface ForStatement extends Node {
  type: 'ForStatement'
  init: VariableDeclaration | Expression | null
  test: Expression | null
  update: Expression | null
  body: Statement
}

FunctionDeclaration

A function declaration. body is null for overloads.

interface FunctionDeclaration extends Node {
  type: 'FunctionDeclaration'
  id: Identifier
  qualifiers: PrecisionQualifier[]
  typeSpecifier: Identifier | ArraySpecifier
  params: FunctionParameter[]
  body: BlockStatement | null
}

FunctionParameter

A function parameter within a function declaration.

interface FunctionParameter extends Node {
  type: 'FunctionParameter'
  id: Identifier | null
  qualifiers: (ConstantQualifier | ParameterQualifier | PrecisionQualifier)[]
  typeSpecifier: Identifier | ArraySpecifier
}

VariableDeclaration

A variable declaration.

interface VariableDeclaration extends Node {
  type: 'VariableDeclaration'
  declarations: VariableDeclarator[]
}

VariableDeclarator

A variable declarator within a variable declaration.

interface VariableDeclarator extends Node {
  type: 'VariableDeclarator'
  id: Identifier
  qualifiers: (ConstantQualifier | InterpolationQualifier | StorageQualifier | PrecisionQualifier)[]
  typeSpecifier: Identifier | ArraySpecifier
  layout: Record<string, string | boolean> | null
  init: Expression | null
}

StructuredBufferDeclaration

A buffer interface declaration with optional layout and qualifiers.

interface StructuredBufferDeclaration extends Node {
  type: 'StructuredBufferDeclaration'
  id: Identifier | null
  qualifiers: (InterfaceStorageQualifier | MemoryQualifier | LayoutQualifier)[]
  typeSpecifier: Identifier | ArraySpecifier
  layout: Record<string, string | boolean> | null
  members: VariableDeclaration[]
}

StructDeclaration

A struct declaration. Can be used as a type or constructor.

interface StructDeclaration extends Node {
  type: 'StructDeclaration'
  id: Identifier
  members: VariableDeclaration[]
}

ArrayExpression

An array initialization expression.

interface ArrayExpression extends Node {
  type: 'ArrayExpression'
  typeSpecifier: ArraySpecifier
  elements: Expression[]
}

UnaryExpression

A unary expression with a left or right handed operator.

interface UnaryExpression extends Node {
  type: 'UnaryExpression'
  operator: UnaryOperator
  prefix: boolean
  argument: Expression
}

UnaryOperator

type UnaryOperator = '-' | '+' | '!' | '~'

UpdateExpression

An update expression with an optionally prefixed operator.

interface UpdateExpression extends Node {
  type: 'UpdateExpression'
  operator: UpdateOperator
  argument: Expression
  prefix: boolean
}

UpdateOperator

type UpdateOperator = '++' | '--'

BinaryExpression

A binary expression with a left and right operand.

interface BinaryExpression extends Node {
  type: 'BinaryExpression'
  operator: BinaryOperator
  left: Expression
  right: Expression
}

BinaryOperator

type BinaryOperator =
  | '=='
  | '!='
  | '<'
  | '<='
  | '>'
  | '>='
  | '<<'
  | '>>'
  | '+'
  | '-'
  | '*'
  | '/'
  | '%'
  | '|'
  | '^'
  | '&'

AssignmentExpression

An assignment expression.

interface AssignmentExpression extends Node {
  type: 'AssignmentExpression'
  operator: AssignmentOperator
  left: Expression
  right: Expression
}

AssignmentOperator

type AssignmentOperator = '=' | '+=' | '-=' | '*=' | '/=' | '%=' | '<<=' | '>>=' | '>>>=' | '|=' | '^=' | '&='

LogicalExpression

A logical operation between two expressions.

interface LogicalExpression extends Node {
  type: 'LogicalExpression'
  operator: LogicalOperator
  left: Expression
  right: Expression
}

LogicalOperator

type LogicalOperator = '||' | '&&' | '^^'

MemberExpression

A member expression.

interface MemberExpression extends Node {
  type: 'MemberExpression'
  object: Expression
  property: Expression
  computed: boolean
}

ConditionalExpression

A conditional expression or ternary.

interface ConditionalExpression extends Node {
  type: 'ConditionalExpression'
  test: Expression
  alternate: Expression
  consequent: Expression
}

CallExpression

A function call expression or struct initialization.

interface CallExpression extends Node {
  type: 'CallExpression'
  callee: Expression
  arguments: Expression[]
}