Library / SDK
Alchemist0823/three.quarks avatar
Alchemist0823/three.quarks

three.quarks: a particle system and VFX toolkit for three.js

Three.quarks is a general purpose particle system / VFX engine for three.js

1,114 stars72 forksTypeScriptMIT

At a glance

What is it?
three.quarks is a TypeScript particle system and visual effects library for three.js, built around a batched renderer that keeps many emitters in few draw calls. It targets web game and interactive developers who want real-time VFX, and it also carries a visual editor and a React Three Fiber package.
Who is it for?
Adopt three.quarks if you build real-time effects in the browser with three.js and want one batched renderer across many particle systems, plus an editor for authoring and a JSON export path. Skip it if your effect graph needs GPU compute pipelines today, since quarks.nodes is labelled experimental, or if you need Unity Shuriken import in production without testing that bridge.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 155 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One batched renderer for every particle system on the page

The core idea of three.quarks is that individual particle systems should not each cost you a draw call. The library provides a BatchedRenderer that manages all particle systems in a scene, and the README states that optimized batch rendering minimizes draw calls. Everything else hangs off that object: you define a ParticleSystem, add its emitter to the scene, register the system with the batch renderer, and then call the batch renderer update once per frame with your delta. The project describes itself as a general purpose particle system and VFX engine for three.js, written in TypeScript, and the repository is structured as a monorepo with npm workspaces under `packages/`. The target audience is developers building games, interactive experiences and web applications in the browser, where particle count is a frame budget problem rather than a visual flourish.

Values, colors and shapes are objects rather than numbers

The API style is worth understanding before you write any code, because it is the main departure from hand-rolled particle code. Spawn parameters are not plain numbers but value objects. `ConstantValue` fixes a parameter, `IntervalValue` randomises it across a range, and `ConstantColor` carries colour as a four component vector. Emitters are separate objects too, with `PointEmitter` used in the quick start and a list of shapes documented as Point, Sphere, Hemisphere, Cone, Circle, Mesh Surface for emitting from 3D model surfaces, and Grid for structured emission patterns. A system is configured with a `duration`, a `looping` flag, a `maxParticle` ceiling, an `emissionOverTime` rate, a `shape` and a `renderMode`, and it takes a three.js material such as `MeshBasicMaterial`. The result reads like a data description of an effect rather than a sequence of update calls, which is what makes the JSON path below possible.

Four render modes decide how particles look on screen

Rendering is a separate axis from behaviour. The documented render modes are Billboard for camera-facing sprites, Stretched Billboard for velocity-aligned sprites, Mesh for 3D geometry particles, and Trail for ribbon trails behind particles. `RenderMode.BillBoard` appears in both the vanilla quick start and the React example, but the other three are what separate a smoke puff from a sparks-and-smoke fire effect. Materials are drawn from the three.js set, with MeshBasicMaterial described as unlit and MeshStandardMaterial as PBR, plus configurable blending modes and texture atlas support. Behaviors are attached separately and the documented list covers color over lifetime, size over lifetime, rotation over lifetime, force fields, orbital motion, texture animation and sub-emitters, with a plugin system for custom behaviors and emitters.

Installing the package and running the first system

The library is published on npm and the install is a single command:

bash
npm install three.quarks

The quick start then creates the batch renderer, defines one system and drives it from the animation loop:

javascript
import * as THREE from 'three';
import {
    BatchedRenderer,
    ParticleSystem,
    ConstantValue,
    IntervalValue,
    ConstantColor,
    PointEmitter,
    RenderMode
} from 'three.quarks';

const batchRenderer = new BatchedRenderer();
scene.add(batchRenderer);
javascript
const particles = new ParticleSystem({
    duration: 2,
    looping: true,
    startLife: new IntervalValue(1, 2),
    startSpeed: new ConstantValue(5),
    startSize: new IntervalValue(0.1, 0.3),
    startColor: new ConstantColor(new THREE.Vector4(1, 1, 1, 1)),
    maxParticle: 100,
    emissionOverTime: new ConstantValue(20),
    shape: new PointEmitter(),
    material: new THREE.MeshBasicMaterial({
        map: yourTexture,
        transparent: true
    }),
    renderMode: RenderMode.BillBoard
});

scene.add(particles.emitter);
batchRenderer.addSystem(particles);

In your animation loop you call `batchRenderer.update(delta)` and then render the scene as usual. If particles do not appear, the first things to check are that the emitter was added to the scene, that the system was added to the batch renderer, and that the material you passed has a texture and transparency enabled.

Authoring in the visual editor and shipping the JSON

The workflow that makes this more than a code library is the visual editor at quarks.art/create, described as a WYSIWYG particle effect creator with real-time preview and JSON export. An effect exported from the editor is loaded at runtime with `QuarksLoader` and handed to the batch renderer through `QuarksUtil.addToBatchRenderer`:

javascript
import { QuarksLoader, QuarksUtil, BatchedRenderer } from 'three.quarks';

const batchRenderer = new BatchedRenderer();
const loader = new QuarksLoader();

loader.load('effects/explosion.json', (effect) => {
    QuarksUtil.addToBatchRenderer(effect, batchRenderer);
    scene.add(effect);
});

That JSON file is the deliverable an artist can hand you. Reusing one effect in several places is handled by cloning the loaded effect, adding it to the scene and the batch renderer, and calling `QuarksUtil.setAutoDestroy(instance, true)` so the effect cleans itself up when it finishes, plus `QuarksUtil.play(instance)` to start it. The practical consequence is a split between authoring and code: the editor owns the visual design, and the runtime code owns placement, lifetime and cleanup.

React Three Fiber and the wider package set

There is a separate package for React Three Fiber, installed alongside the main library:

bash
npm install quarks.r3f three.quarks

It exposes `QuarksProvider` and a `ParticleSystem` component, and the README example passes values as plain props, for example `startLife={[1, 2]}` and `startColor={{ r: 1, g: 0.5, b: 0.2, a: 1 }}`, while the emitter shape and the behaviours array are built in `useMemo` so they are not rebuilt on every render. Behaviours are passed the same way, as an array built with `useMemo` containing a `SizeOverLife` built from a `PiecewiseBezier` and `Bezier` curve. The monorepo publishes several packages: `quarks.core` for framework-agnostic math, behaviors and emitter shapes with zero dependencies, `three.quarks` as the main three.js package, `quarks.r3f` for React, `quarks.nodes` for an experimental node-based VFX system with visual programming and WebGPU compute support, plus `quarks.examples` and `quarks.playground` which are not published as libraries.

Where the tool falls short

The limits are visible in the project's own labelling. `quarks.nodes`, the node-based visual programming package with WebGPU compute support, is described as experimental, so anyone planning a long-lived pipeline on top of node graphs is building on the least settled part of the tree. The README also lists Unity compatibility, importing particle systems from Unity's Shuriken system, as a feature, but the documentation does not describe a round trip, a fidelity guarantee, or which Shuriken features survive import. Another constraint is the setup cost of the editor and JSON workflow: an effect only becomes an asset once someone has authored it in a browser tool. And the project publishes no GitHub releases at all, so there is no tagged version to pin in a lockfile beyond the npm range you write yourself.

The alternative: writing particle systems directly against three.js

The obvious alternative is to build the effect yourself on top of plain three.js, using `THREE.Points` with a custom `ShaderMaterial` and a per-vertex attribute for age, or a single `InstancedMesh` for geometry particles. That route gives you total control over the shader and costs you the parts three.quarks already solved: the batched renderer that merges many systems, the value objects that make randomised parameters readable, the render modes including trails and stretched billboards, and the behavior list of color, size, rotation, forces, orbital motion, texture animation and sub-emitters. Hand-rolling is still the right answer for a single bespoke effect in a small scene, where a shader and a buffer attribute may be less code than learning this API. Once you have more than one or two systems in a project, the maintenance arithmetic flips, and the editor plus JSON export is the part that has no equivalent in the DIY path.

Editorial conclusion

Adopt three.quarks if you build real-time effects in the browser with three.js and want one batched renderer across many particle systems, plus an editor for authoring and a JSON export path. Skip it if your effect graph needs GPU compute pipelines today, since quarks.nodes is labelled experimental, or if you need Unity Shuriken import in production without testing that bridge. Before committing, check that the package you install matches your renderer path, and note that the repository has no GitHub releases and that the last push was on 2026-05-21, so upgrades come from the changelog rather than a tagged version.

Frequently asked questions

How do I install three.quarks?

The README gives a single npm install for the main library, `npm install three.quarks`, and the React Three Fiber package is added separately with `npm install quarks.r3f three.quarks`.

Why do my three.quarks particles not appear in the scene?

A system needs three things: the emitter added to the scene, the system added to the batch renderer with `batchRenderer.addSystem(particles)`, and a `batchRenderer.update(delta)` call in the animation loop. The material also needs a texture and transparency for sprites to draw.

Can I import particle effects from Unity into three.quarks?

The README lists Unity compatibility, importing particle systems from Unity's Shuriken system, as a feature. It does not describe the import path, so the details are in the editor and the documentation site rather than in the README.

What is the difference between three.quarks and quarks.core?

three.quarks is the main three.js package with batched rendering and shaders, while quarks.core is the framework-agnostic library of math, behaviors, emitter shapes and functions, described as having zero dependencies.

Official sources

  1. Alchemist0823/three.quarks on GitHub
  2. Issues
  3. License: MIT
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/alchemist0823-three-quarks.svg)](https://hysenlabs.com/projects/alchemist0823-three-quarks)

Was this useful?