tsParticles 2.0.5 is out. Breaking changes ahead, keeping the 1.x support.
Tags: showdev, javascript, typescript, webdev
Published: 2022-04-14 22:04:00

# tsParticles 2.0.5 Changelog

## Breaking Changes

Starting from version `2.0.0`, `tsparticles` won't be a single package anymore. Its growth makes me think a lot about splitting the project in more packages.

The new structure will be a common engine and lot of packages with single features that can be installed and loaded, so everyone can install only the features they need, and for the lazy ones there are bundles and presets ready to be used.

For example, if you want to stick with the `tsparticles` library you can still install it, and use the bundle file with the CDN. You can easily set it up when using `import` or `require`, since you have to add few lines of code to the `v1` configuration.

``` javascript
import { tsParticles } from "tsparticles-engine"; // this is the new common package
import { loadFull } from "tsparticles"; // this function loads all the features contained in v1 package

(async () => {
    await loadFull(tsParticles); // this is needed to load all the features and can be done everywhere before using tsParticles.load

    await tsParticles.load("tsparticles", { /* options */ }); // this must be done after loadFull
})();
```

### PRO

- Smaller output, you can import only the features you need without a lot of unused code.
- Better performance, since a lot of features are not imported, they are not running reducing general performance. More features, more calculations needed.

### CONS

- All features needs to be installed, which result in a long `package.json` file, that's why presets will be more important now.
- Previous code won't work anymore without importing the right packages, this is a needed breaking change.

## New Features

- Added `outside` and `inside` values to particles move direction options
- Added `outside` and `inside` values to particles move out modes options

---

# How to migrate from `v1` to `v2`?

Version `1.x` is still the `latest` tag on `npm`, but the `next` version has a `2.0.0` version, which is something I need to release to the public to find issues, and receive some feedbacks.

## Migration Steps

### Vanilla JS / HTML usage

Just change the `tsparticles` file from `tsparticles.min.js` to `tsparticles.bundle.min.js`, if the `slim` version is used, there's a bundle also there but it's a different package, now called `tsparticles-slim`.

### Modules

1. Install the package `"tsparticles-engine"` using the `next` tag like this: `npm install tsparticles-engine@next`
2. Replace all your `"tsparticles"` imports to `"tsparticles-engine"`
3. Add `import { loadFull } from "tsparticles";` in the imports, or its RequireJS version. This requires the new `2.0.x` version, you can install it using `npm install tsparticles@next`
4. Call `loadFull`
  - If using a React/Vue/Angular/Svelte or other kind of component: in `particlesInit/init` property, passing the same parameter coming from the `init` function to `loadFull`
  - If not just call `loadFull(tsParticles)` before any `tsParticles` usage

## Alternative

Using the bundled version of the `tsparticles` package is not optimal, it's easier to implement but it could load a lot of unnecessary stuff.

I want to take the following code as an example (it's the core of `tsparticles-slim` package)

``` typescript
import type { Engine } from "tsparticles-engine";
import { loadAngleUpdater } from "tsparticles-updater-angle";
import { loadBaseMover } from "tsparticles-move-base";
import { loadCircleShape } from "tsparticles-shape-circle";
import { loadColorUpdater } from "tsparticles-updater-color";
import { loadExternalAttractInteraction } from "tsparticles-interaction-external-attract";
import { loadExternalBounceInteraction } from "tsparticles-interaction-external-bounce";
import { loadExternalBubbleInteraction } from "tsparticles-interaction-external-bubble";
import { loadExternalConnectInteraction } from "tsparticles-interaction-external-connect";
import { loadExternalGrabInteraction } from "tsparticles-interaction-external-grab";
import { loadExternalPauseInteraction } from "tsparticles-interaction-external-pause";
import { loadExternalPushInteraction } from "tsparticles-interaction-external-push";
import { loadExternalRemoveInteraction } from "tsparticles-interaction-external-remove";
import { loadExternalRepulseInteraction } from "tsparticles-interaction-external-repulse";
import { loadImageShape } from "tsparticles-shape-image";
import { loadLifeUpdater } from "tsparticles-updater-life";
import { loadLineShape } from "tsparticles-shape-line";
import { loadOpacityUpdater } from "tsparticles-updater-opacity";
import { loadOutModesUpdater } from "tsparticles-updater-out-modes";
import { loadParallaxMover } from "tsparticles-move-parallax";
import { loadParticlesAttractInteraction } from "tsparticles-interaction-particles-attract";
import { loadParticlesCollisionsInteraction } from "tsparticles-interaction-particles-collisions";
import { loadParticlesLinksInteraction } from "tsparticles-interaction-particles-links";
import { loadPolygonShape } from "tsparticles-shape-polygon";
import { loadSizeUpdater } from "tsparticles-updater-size";
import { loadSquareShape } from "tsparticles-shape-square";
import { loadStarShape } from "tsparticles-shape-star";
import { loadStrokeColorUpdater } from "tsparticles-updater-stroke-color";
import { loadTextShape } from "tsparticles-shape-text";

export async function loadSlim(engine: Engine): Promise<void> {
    await loadBaseMover(engine);
    await loadParallaxMover(engine);

    await loadExternalAttractInteraction(engine);
    await loadExternalBounceInteraction(engine);
    await loadExternalBubbleInteraction(engine);
    await loadExternalConnectInteraction(engine);
    await loadExternalGrabInteraction(engine);
    await loadExternalPauseInteraction(engine);
    await loadExternalPushInteraction(engine);
    await loadExternalRemoveInteraction(engine);
    await loadExternalRepulseInteraction(engine);

    await loadParticlesAttractInteraction(engine);
    await loadParticlesCollisionsInteraction(engine);
    await loadParticlesLinksInteraction(engine);

    await loadCircleShape(engine);
    await loadImageShape(engine);
    await loadLineShape(engine);
    await loadPolygonShape(engine);
    await loadSquareShape(engine);
    await loadStarShape(engine);
    await loadTextShape(engine);

    await loadLifeUpdater(engine);
    await loadOpacityUpdater(engine);
    await loadSizeUpdater(engine);
    await loadAngleUpdater(engine);
    await loadColorUpdater(engine);
    await loadStrokeColorUpdater(engine);
    await loadOutModesUpdater(engine);
}
```

### Vanilla JS / HTML Usage

Splitting things can be a long activity using `<script>` tags, but nothing impossible.

From the example above, every package needs its own `<script>` tag, and every `load` function needs to be called using `tsParticles` as a parameter, then use the `tsParticles` object as always.

The `tsparticles-engine` must be always present, if there are no bundles (`tsparticles-slim`, `tsparticles` or any bundled preset). Every other package is required only if you want to use that feature.

Let's see an example:

{% codepen https://codepen.io/matteobruni/pen/zYPEbjx %}

As you can see, in the JS options there are the needed scripts, and before using `tsParticles.load` their functions are called to load everything correctly. Every `load` function is `async`, so it's a Promise that can be awaited, it's not always necessary (like in this case), but it's recommended.

### Modules

In this case importing modules is easier, since every module can be installed easily using `npm`, `yarn` or `pnpm`.

Once installed the required packages, import them and the code used for `"Vanilla JS / HTML Usage"` works also here.

The module sample can be found here:

{% codesandbox immutable-cookies-n2lm9p %}

#### Components (React, Vue, Angular, Svelte, ...)

Every component has a `init` or `particlesInit` (checkout the documentation until everything has the same attribute), that is the place to load all the components, that function has an `engine` attribute, which is the `tsParticles` instance used by the component.

**React Sample**

{% codesandbox optimistic-http-mxz8bg %}

**Vue.js 2.x Sample**

{% codesandbox eager-wildflower-co03th %}

**Vue.js 3.x Sample**

{% codesandbox angry-hellman-xv6ifv %}

**Angular Sample**

{% codesandbox crazy-villani-nc0nfj %}