Can You Clone or Serialize a GPU.js Kernel?
GPU.js does not provide a native .clone() method to
duplicate kernel objects in memory, as each kernel is bound directly to
the WebGL context of its parent GPU instance. However, you
can achieve serialization and cross-instance reuse by exporting a
compiled kernel using its .toString() method. This extracts
the kernel logic and compiled shaders into a self-contained string that
can be transferred, evaluated, and executed across different JavaScript
runtimes, Web Workers, or separate instances.
Why Direct In-Memory Cloning Fails
A GPU.js kernel is not a standard, stateless JavaScript object. When
you call gpu.createKernel(), the library performs several
low-level setup steps:
- It inspects your JavaScript function and translates it into a WebGL (or WebGL2/WebGPU) GLSL shader string.
- It binds shader programs, textures, and framebuffers to a specific
rendering context tied to the host
GPUinstance. - It maintains internal closures and references to canvas elements or headless contexts.
Because of these context-specific WebGL references, operations like
structuredClone(), Object.assign(), or
standard deep-cloning utilities will fail or produce broken instances
that lack valid GPU bindings.
Serializing a Kernel with
.toString()
To reuse a kernel across different environments without recompiling
the GLSL shader from scratch, GPU.js includes an export feature through
.toString().
When called on a kernel, .toString() outputs a
self-contained, standalone JavaScript function containing:
- The pre-compiled GLSL fragment and vertex shaders.
- The necessary WebGL execution boilerplate.
- The configured output dimensions, argument types, and graphical modes.
const gpu = new GPU();
const kernel = gpu.createKernel(function(a, b) {
return a[this.thread.x] + b[this.thread.x];
}).setOutput([512]);
// Serialize the kernel to a standalone string
const serializedKernel = kernel.toString();Running the Serialized Kernel Across Instances
The output string can be stored in a file, stored in a database, or
transmitted over network boundaries (e.g., using
postMessage to Web Workers).
Because the serialized function contains all required WebGL logic, it
can run independently of the original GPU instance or even
without the GPU.js runtime present in the destination environment.
To recreate the kernel from the serialized string, evaluate it using
new Function:
// Re-instantiate the serialized kernel in a new context or thread
const revivedKernel = new Function(`return ${serializedKernel}`)();
// Run the revived kernel
const result = revivedKernel([1, 2, 3], [4, 5, 6]);Pattern for Multiple Dynamic Instances
If you need multiple kernels operating with the same logic inside the same thread, compiling multiple times via the serialized function string or sharing the source function is standard practice:
- Source-level reuse: Keep the kernel's core logic
function and settings in a plain JavaScript object, then pass them to
gpu.createKernel()on each newGPUinstance. - Pre-compiled reuse: Use
.toString()during a build or initialization step to eliminate shader translation overhead across multiple downstream worker instances.