You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
"@linaria/stylelint-config-standard-linaria": major
10
+
"@linaria/stylelint": major
6
11
---
7
12
8
-
Migrate WyW dependencies to 2.0.0-alpha.1 and expose processor static evaluation semantics for the new evaluator architecture.
13
+
Release Linaria 8 with WyW 2.0.0 stable dependencies and Node.js 22+ support.
14
+
15
+
Linaria processors now expose WyW 2 static evaluation semantics, allowing the default `eval.strategy: "hybrid"` mode to resolve statically provable values before falling back to the evaluator. This keeps existing dynamic/runtime-only interpolation support while reducing evaluator work for values that can be resolved from static bindings and imports.
16
+
17
+
Migration notes:
18
+
19
+
- Node.js 22 or newer is required.
20
+
- Top-level `evaluate` config should be migrated to `eval.strategy`. Use `execute` for evaluator-only compatibility, keep the default `hybrid` for static-first resolution with fallback, or use `static` to reject evaluator fallback.
21
+
- CSS rule emission order may change for cascade ties with identical specificity because WyW 2 uses the Oxc/static-first pipeline and can preserve/process imports differently. Make precedence explicit with selector specificity, composition, or source structure where order matters.
Copy file name to clipboardExpand all lines: README.md
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -65,7 +65,9 @@ See [Configuration](https://wyw-in-js.dev/configuration) to customize how Linari
65
65
66
66
Linaria relies on WyW (`@wyw-in-js/*`) to evaluate your modules at build time and extract CSS. If you hit issues like slow builds, invalidation storms, or unexpected code being executed during the build, it’s usually related to the WyW evaluation model and how your modules are structured.
67
67
68
-
Linaria 7 requires Node.js `>=20` (WyW 1.x enforces this via `engines`).
68
+
Linaria 8 requires Node.js `>=22` (WyW 2.x enforces this via `engines`). WyW 2 defaults to `eval.strategy: "hybrid"`, so statically provable values are resolved before falling back to the evaluator for dynamic values.
69
+
70
+
If your build depends on evaluator-only side effects or exact CSS rule order ties, review the Linaria 8 migration notes in [docs/MIGRATION_GUIDE.md](./docs/MIGRATION_GUIDE.md).
69
71
70
72
See https://wyw-in-js.dev/stability for practical guidance and common pitfalls.
Controls how WyW resolves values used in CSS interpolations. The recommended default, `"hybrid"`, uses static-first resolution: WyW first tries to prove values from Linaria processor static semantics, `staticBindings`, and statically resolvable imports, then falls back to the evaluator for values that cannot be proven statically.
22
26
23
-
Enabling this will evaluate dynamic expressions in the CSS. You need to enable this if you want to use imported variables in the CSS or interpolate other components. Enabling this also ensures that your styled components wrapping other styled components will have the correct specificity and override styles properly.
27
+
Use `"execute"` when you need evaluator-only compatibility, for example while migrating code that relies on build-time side effects or exact import execution order. Use `"static"` as a strict validation mode when fallback to the evaluator should be rejected. The older top-level `evaluate` option should be migrated to `eval.strategy` in Linaria 8 / WyW 2.
28
+
29
+
Evaluated values are included in the generated CSS. Since fallback evaluation runs at build time in Node.js, avoid browser-only APIs, unavailable runtime globals, Node native modules such as `fs`, and side effects in evaluated expressions.
Copy file name to clipboardExpand all lines: docs/HOW_IT_WORKS.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -148,7 +148,7 @@ const Container = styled.h1`
148
148
149
149
We support this usage because it allows you to use a library such as [polished.js](https://polished.js.org) which outputs object based styles along with Linaria.
150
150
151
-
If you've configured the plugin to evaluate expressions with `evaluate: true` (default), any dynamic expressions we encounter will be evaluated during the build-time in a sandbox, and the result will be included in the CSS. Since these expressions are evaluated at build time in Node, you cannot use any browserspecific APIs or any API which is only available in runtime. Access to Node native modules such as `fs` is also not allowed inside the sandbox to prevent malicious scripts. In addition, to achieve consistent build output, you should also avoid doing any side effects in these expressions and keep them pure.
151
+
By default, Linaria uses WyW's `eval.strategy: "hybrid"` mode. WyW first tries to resolve values statically from Linaria processor metadata, `staticBindings`, and statically resolvable imports. If a value cannot be proven statically, WyW falls back to build-time evaluation and includes the result in the generated CSS. Since fallback evaluation runs in Node.js, you cannot use browser-specific APIs, runtime-only globals, or Node native modules such as `fs`. To keep build output consistent, avoid side effects in evaluated expressions and keep them pure.
152
152
153
153
You might want to skip evaluating a certain interpolation if you're using a browser API, a global variable which is only available at runtime, or a module which breaks when evaluating in the sandbox for some reason. To skip evaluating an interpolation, you can always wrap it in a function, like so:
154
154
@@ -162,13 +162,13 @@ But keep in mind that if you're doing SSR for your app, this won't work with SSR
162
162
163
163
### Evaluators
164
164
165
-
Linaria can use different strategies for evaluating the interpolated values.
166
-
Currently, we have two built-in strategies:
165
+
Linaria relies on WyW strategies for resolving interpolated values:
167
166
168
-
-`extractor` was the default strategy in `1.x` version. It takes an interpolated expression, finds all the referenced identifiers, gets all its declarations, repeats cycle for all identifiers in found declarations, and then constructs a new tree of statements from all found declarations. It's a pretty simple strategy, but it significantly changes an evaluated code and doesn't work for non-primitive js-constructions.
169
-
-`shaker` was introduced as an option in `1.4` and became the default in `2.0` version. In contrast to `extractor`, `shaker` tries to find all irrelevant code and cuts it out of the file. As a result, interpolated values can be defined without any restrictions.
167
+
-`hybrid` is the default in Linaria 8 / WyW 2. It resolves statically provable values without starting the evaluator, then falls back to evaluator execution for unresolved dynamic values.
168
+
-`execute` uses evaluator-only behavior and is the compatibility escape hatch for projects that depend on build-time side effects or exact import execution order.
169
+
-`static` is a strict validation mode that rejects fallback to evaluator execution.
170
170
171
-
If an interpolated value or one of its dependencies is imported from another module, that module will be also processed with an evaluator (the implementation of evaluator will be chosen by matching `rules` from [the Linaria config](./CONFIGURATION.md#options)).
171
+
If an interpolated value or one of its dependencies is imported from another module, WyW processes that module according to the configured strategy. In `hybrid` mode, the imported value may be resolved statically; otherwise WyW falls back to the evaluator selected by matching `rules` from [the Linaria config](./CONFIGURATION.md#options).
172
172
173
173
Sometimes it can be useful to implement your own strategy (it can be just a mocked version of some heavy or browser-only library). You can do it by implementing `Evaluator` function:
Copy file name to clipboardExpand all lines: docs/MIGRATION_GUIDE.md
+27Lines changed: 27 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,32 @@
1
1
# Migration Guide
2
2
3
+
# 8.x from 7.x
4
+
5
+
## For Users
6
+
7
+
Linaria 8 updates the WyW toolchain (`@wyw-in-js/*`) to `2.0.0` stable. This is a major release because WyW 2 changes the build-time evaluation pipeline and raises the minimum Node.js version.
- The default evaluation mode is WyW's `eval.strategy: "hybrid"`. It resolves statically provable values first using Linaria processor static semantics, `staticBindings`, and statically resolvable imports, then falls back to the evaluator for values that cannot be proven statically.
11
+
- Top-level `evaluate` config should be migrated to `eval.strategy`. Use `execute` for evaluator-only compatibility, keep the default `hybrid` for static-first resolution with evaluator fallback, or use `static` to reject evaluator fallback.
12
+
- If your project relies on build-time side effects or on the exact order in which evaluated imports execute, compare the generated CSS/JS output after upgrading and use `eval.strategy: "execute"` where evaluator-only behavior is required.
13
+
- CSS rule emission order can change for cascade ties with identical specificity. WyW 2 uses the Oxc/static-first pipeline and can preserve or process imports differently, so make precedence explicit through selector specificity, composition, or source structure where order matters.
14
+
- Review https://wyw-in-js.dev/migration/v2 and https://wyw-in-js.dev/stability for the WyW 2 evaluation model, debugging notes, and performance guidance.
15
+
16
+
Example evaluator-only compatibility config:
17
+
18
+
```js
19
+
module.exports= {
20
+
eval: {
21
+
strategy:'execute',
22
+
},
23
+
};
24
+
```
25
+
26
+
## For Custom Processor Developers
27
+
28
+
Linaria processors now expose WyW 2 static evaluation semantics. Custom processors that integrate with WyW's static-first path should implement the optional static processor contract in `@wyw-in-js/processor-utils`; unresolved values can still fall back to the evaluator in `hybrid` mode.
0 commit comments