diff --git a/docusaurus/docs/adding-css-in-js.md b/docusaurus/docs/adding-css-in-js.md
new file mode 100644
index 00000000000..c389bfc4ac0
--- /dev/null
+++ b/docusaurus/docs/adding-css-in-js.md
@@ -0,0 +1,77 @@
+---
+id: adding-css-in-js
+title: Adding CSS in JS
+sidebar_label: Adding CSS in JS
+---
+
+> Note: this feature is an **optional feature** available with `react-scripts@3.1.0` and higher. Regular `` stylesheets and CSS files are fully supported.
+
+This project supports zero-runtime CSS in JSX via [Linaria](https://linaria.now.sh/), complete with dynamic properties, source maps and linting support.
+
+## [Setup](https://github.com/callstack/linaria#setup)
+
+Add the `linaria/babel` [preset](https://babeljs.io/docs/en/presets) to `package.json`:
+
+```json
+"babel": {
+ "presets": [
+ "react-app",
+ "linaria/babel"
+ ]
+}
+```
+
+The [webpack configuration](https://github.com/callstack/linaria/blob/master/docs/BUNDLERS_INTEGRATION.md#webpack) is already provided for you.
+
+## Writing CSS
+
+Import the `styled` helper from `linaria/react` to write a React component with dynamic styles.
+
+### `App.jsx`
+
+```jsx
+import React from 'react';
+import PropTypes from 'prop-types';
+import { styled } from 'linaria/react';
+
+const App = styled.div`
+ background-color: ${props => (props.theme === 'dark') ? 'black' : 'white'};
+`;
+
+const App = props => (
+
+ {props.children}
+
+)
+
+App.propTypes = {
+ theme: PropTypes.oneOf(['light', 'dark']),
+};
+
+export default App
+```
+
+### `App.tsx`
+
+```tsx
+import React from 'react';
+import { styled } from 'linaria/react';
+
+interface AppProps {
+ theme: 'light' | 'dark'
+}
+
+const App = styled.button`
+ background-color: ${props => (props.theme === 'dark') ? 'black' : 'white'};
+`;
+
+const App: React.FC = props => (
+
+ {props.children}
+
+)
+
+export default App
+```
+
+See [Linaria documentation](https://github.com/callstack/linaria#documentation) for more information.
diff --git a/packages/react-scripts/config/webpack.config.js b/packages/react-scripts/config/webpack.config.js
index 8f70442d584..bbc970a3e2d 100644
--- a/packages/react-scripts/config/webpack.config.js
+++ b/packages/react-scripts/config/webpack.config.js
@@ -352,51 +352,61 @@ module.exports = function(webpackEnv) {
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc,
- loader: require.resolve('babel-loader'),
- options: {
- customize: require.resolve(
- 'babel-preset-react-app/webpack-overrides'
- ),
- // @remove-on-eject-begin
- babelrc: false,
- configFile: false,
- presets: [require.resolve('babel-preset-react-app')],
- // Make sure we have a unique cache identifier, erring on the
- // side of caution.
- // We remove this when the user ejects because the default
- // is sane and uses Babel options. Instead of options, we use
- // the react-scripts and babel-preset-react-app versions.
- cacheIdentifier: getCacheIdentifier(
- isEnvProduction
- ? 'production'
- : isEnvDevelopment && 'development',
- [
- 'babel-plugin-named-asset-import',
- 'babel-preset-react-app',
- 'react-dev-utils',
- 'react-scripts',
- ]
- ),
- // @remove-on-eject-end
- plugins: [
- [
- require.resolve('babel-plugin-named-asset-import'),
- {
- loaderMap: {
- svg: {
- ReactComponent: '@svgr/webpack?-svgo,+ref![path]',
+ use: [
+ {
+ loader: require.resolve('babel-loader'),
+ options: {
+ customize: require.resolve(
+ 'babel-preset-react-app/webpack-overrides'
+ ),
+ // @remove-on-eject-begin
+ babelrc: false,
+ configFile: false,
+ presets: [require.resolve('babel-preset-react-app')],
+ // Make sure we have a unique cache identifier, erring on the
+ // side of caution.
+ // We remove this when the user ejects because the default
+ // is sane and uses Babel options. Instead of options, we use
+ // the react-scripts and babel-preset-react-app versions.
+ cacheIdentifier: getCacheIdentifier(
+ isEnvProduction
+ ? 'production'
+ : isEnvDevelopment && 'development',
+ [
+ 'babel-plugin-named-asset-import',
+ 'babel-preset-react-app',
+ 'react-dev-utils',
+ 'react-scripts',
+ ]
+ ),
+ // @remove-on-eject-end
+ plugins: [
+ [
+ require.resolve('babel-plugin-named-asset-import'),
+ {
+ loaderMap: {
+ svg: {
+ ReactComponent: '@svgr/webpack?-svgo,+ref![path]',
+ },
+ },
},
- },
- },
- ],
- ],
- // This is a feature of `babel-loader` for webpack (not Babel itself).
- // It enables caching results in ./node_modules/.cache/babel-loader/
- // directory for faster rebuilds.
- cacheDirectory: true,
- cacheCompression: isEnvProduction,
- compact: isEnvProduction,
- },
+ ],
+ ],
+ // This is a feature of `babel-loader` for webpack (not Babel itself).
+ // It enables caching results in ./node_modules/.cache/babel-loader/
+ // directory for faster rebuilds.
+ cacheDirectory: true,
+ cacheCompression: isEnvProduction,
+ compact: isEnvProduction,
+ },
+ },
+ {
+ loader: 'linaria/loader',
+ options: {
+ sourceMap: isEnvProduction && shouldUseSourceMap,
+ },
+ },
+ ],
},
// Process any JS outside of the app with Babel.
// Unlike the application JS, we only compile the standard ES features.
diff --git a/packages/react-scripts/package.json b/packages/react-scripts/package.json
index 3be87d94ee3..7f303dae136 100644
--- a/packages/react-scripts/package.json
+++ b/packages/react-scripts/package.json
@@ -59,6 +59,7 @@
"jest-environment-jsdom-fourteen": "0.1.0",
"jest-resolve": "24.7.1",
"jest-watch-typeahead": "0.3.0",
+ "linaria": "1.3.1",
"mini-css-extract-plugin": "0.5.0",
"optimize-css-assets-webpack-plugin": "5.0.1",
"pnp-webpack-plugin": "1.2.1",