An official SWC plugin can be used for SSR and easier debugging experience in SWC-powered projects, like Next.js or Vite with vite-react-swc plugin.
The plugin has the same functionality as the built-in babel-plugin
.
It provides all Units with unique SID
s (Stable Identifier) and name, as well as other debug information.
This SWC plugin, along with all other SWC plugins, is currently considered experimental and unstable.
SWC and Next.js might not follow semver when it comes to plugin compatibility.
Installation
Install @effector/swc-plugin using your preferred package manager.
npm install -ED @effector/swc-plugin
Versioning
To avoid compatibility issues caused by breaking changes in SWC or Next.js, this plugin publishes different âlabelsâ for different underlying @swc/core
. Refer to the table below to choose the correct plugin version for your setup.
For better stability, we recommend pinning both your runtime (like Next.js or @swc/core
) and the @effector/swc-plugin
version.
Use the --exact
/--save-exact
option in your package manager to install specific, compatible versions. This ensures updates to one dependency donât break your application.
@swc/core version | Next.js version | Correct plugin version |
---|---|---|
>=1.3.63 <1.3.106 | >=13.4.8 <=14.1.4 | @swc1.3.63 |
>=1.3.106 <1.4.0 | @swc1.3.106 | |
>=1.4.0 <1.6.0 | >=14.2.0 <=14.2.14 | @swc1.4.0 |
>=1.6.0 <1.7.0 | >=15.0.0-canary.37 <=15.0.0-canary.116 | @swc1.6.0 |
>=1.7.0 | >=15.0.0-canary.122 | @swc1.7.0 |
For more information on compatibility, refer to the SWC documentation on Selecting the SWC Version.
Usage
To use the plugin, simply add it to your toolâs configuration.
Next.js
If youâre using the Next.js Compiler powered by SWC, add this plugin to your next.config.js
.
const nextConfig = {
experimental: {
// even if empty, pass an options object `{}` to the plugin
swcPlugins: [["@effector/swc-plugin", {}]],
},
};
Youâll also need to install the official @effector/next
bindings to enable SSR/SSG.
Note that some functionality may be broken when using Turbopack with NextJS, especially with relative factories
. Use at your own risk.
.swcrc
Add a new entry to jsc.experimental.plugins
option in your .swcrc
.
{
"$schema": "https://json.schemastore.org/swcrc",
"jsc": {
"experimental": {
"plugins": [["@effector/swc-plugin", {}]]
}
}
}
Configuration
factories
Specify an array of module names or files to treat as custom factories. When using SSR, factories is required for ensuring unique SID
s across your application.
Community packages (patronum
, @farfetched/core
, atomic-router
and @withease/factories
) are always enabled, so you donât need to list them explicitly.
Formulae
["@effector/swc-plugin", { "factories": ["./path/to/factory", "factory-package"] }]
- Type:
string[]
- Default:
[]
If you provide a relative path (starting with ./
), the plugin treats it as a local factory relative to your projectâs root directory. These factories can only be imported using relative imports within your code.
Otherwise, if you specify a package name or TypeScript alias, itâs interpreted as an exact import specifier. You must use such import exactly as specified in configuration.
Examples
// configuraiton
["@effector/swc-plugin", { "factories": ["./src/factory"] }]
// file: /src/factory.ts
import { createStore } from "effector";
/* createBooleanStore is a factory */
export const createBooleanStore = () => createStore(true);
// file: /src/widget/user.ts
import { createBooleanStore } from "../factory";
const $boolean = createBooleanStore(); /* Treated as a factory! */
addNames
Add names to Units when calling factories (like createStore
or createDomain
). This is helpful for debugging during development and testing, but its recommended to disable it for minification.
Formulae
["@effector/swc-plugin", { "addNames": true }]
- Type:
boolean
- Default:
true
addLoc
Include location information (file paths and line numbers) for Units and factories. This is useful for debugging with tools like effector-logger
.
Formulae
["@effector/swc-plugin", { "addLoc": false }]
- Type:
boolean
- Default:
false
debugSids
Append the full file path and Unit name to generated SID
s for easier debugging of SSR issues.
Formulae
["@effector/swc-plugin", { "debugSids": false }]
- Type:
boolean
- Default:
false
forceScope
Inject forceScope: true
into all hooks or @effector/reflect
calls to ensure your app always uses Scope
during rendering. If Scope
is missing, an error will be thrown, eliminating the need for /scope
or /ssr
imports.
Read more about Scope enforcement in the effector-react
documentation.
Formulae
["@effector/swc-plugin", { "forceScope": false }]
- Type:
boolean | { hooks: boolean, reflect: boolean }
- Default:
false
hooks
Enforces all hooks from effector-react
and effector-solid
, like useUnit
and useList
, to use Scope
in runtime.
reflect
Supported by @effector/reflect
since 9.0.0
For @effector/reflect
users, enforces all components created with reflect
library use Scope
in runtime.
transformLegacyDomainMethods
When enabled (default), this option transforms Unit creators in Domains, like domain.event()
or domain.createEffect()
. However, this transformation can be unreliable and may affect unrelated code. If thatâs the case for you, disabling this option can fix these issues.
Disabling this option will stop adding SID
s and other debug information to these unit creators. Ensure your code does not depend on domain methods before disabling.
Instead of using unit creators directly on domain, consider using the domain
argument in regular methods.
Formulae
["@effector/swc-plugin", { "transformLegacyDomainMethods": true }]
- Type:
boolean
- Default:
true