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:

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:

  1. The pre-compiled GLSL fragment and vertex shaders.
  2. The necessary WebGL execution boilerplate.
  3. 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: