DEV Community

drkcode
drkcode

Posted on

Using Linaria with React/TS and Vite πŸš€

This guide will walk you through integrating Linaria, a zero-runtime CSS-in-JS library, into your React project built with TypeScript and Vite. Linaria extracts CSS at build time, resulting in smaller bundle sizes and better performance compared to traditional CSS-in-JS solutions that execute in the browser.

Why Linaria? πŸ€”

Linaria offers several advantages:

  • Zero-runtime CSS: CSS is extracted during the build process, meaning no extra CSS processing happens in the user's browser.
  • Improved Performance: Smaller JavaScript bundles and no runtime CSS overhead lead to faster loading times.
  • Developer Experience: Write CSS directly in your JavaScript/TypeScript files using template literals with syntax highlighting and autocompletion (with appropriate editor extensions).
  • Familiar CSS Syntax: You write standard CSS, and Linaria takes care of generating the corresponding CSS files.

Prerequisites βœ…

  • Node.js and npm (or yarn/pnpm) installed.

  • An existing React project set up with TypeScript and Vite. If you don't have one, you can quickly create one by running:

    npm create vite@latest my-app -- --template react-ts
    

Step 1: Install Dependencies πŸ“¦

Open your terminal in the project directory and run the following command to install the necessary packages as development dependencies:

npm install -D @linaria/react @wyw-in-js/vite @babel/typescript @babel/react
Enter fullscreen mode Exit fullscreen mode

Let's briefly understand what each of these dependencies does:

  • @linaria/react: Provides the React-specific API for using Linaria, including the css prop and styled component.
  • @wyw-in-js/vite: A Vite plugin that enables Linaria to process your CSS within JavaScript/TypeScript files during the build. @wyw-in-js (what-you-write-is-what-you-get) is the core library that powers Linaria and other zero-runtime CSS-in-JS solutions.
  • @babel/typescript: Allows Babel to understand and compile TypeScript syntax. While Vite has built-in TypeScript support, Linaria's build process often leverages Babel for transformations.
  • @babel/react: A Babel preset that provides support for React JSX syntax.

Step 2: Configure Vite βš™οΈ

Next, you need to configure the Vite build process to include the @wyw-in-js/vite plugin. Open your vite.config.ts file (or vite.config.js if you haven't switched to TypeScript yet). If you don't have one, create it in the root of your project.

Your vite.config.ts should look similar to this:

// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import wyw from '@wyw-in-js/vite';

export default defineConfig(() => ({
  plugins: [
    react(),
    wyw({
      include: ['./src/**/*.{ts,tsx}'],
      babelOptions: {
        presets: ['@babel/preset-typescript', '@babel/preset-react'],
      },
    }),
  ],
}));
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • We import the necessary functions from vite, @vitejs/plugin-react, and @wyw-in-js/vite.
  • In the plugins array, we include both the react() plugin (for React support) and the wyw() plugin (for Linaria).
  • The wyw() plugin is configured with an include option to specify the file patterns that Linaria should process (in this case, all .ts and .tsx files).
  • The babelOptions tell Linaria to use the @babel/preset-typescript and @babel/preset-react presets to correctly handle TypeScript and JSX syntax within the styled components.

Step 3: Start Using Linaria ✨

Now you can start using Linaria in your React components! You have two main ways to define styles: the css prop and the styled component.

Using the css prop:

You can import the css function from @linaria/react and use it within the className prop of your HTML elements or React components.

// src/components/MyComponent.tsx
import React from 'react';
import { css } from '@linaria/react';

const myStyle = css`
  color: blue;
  font-size: 16px;
  padding: 10px;
  border: 1px solid lightblue;

  &:hover {
    background-color: lightblue;
    color: white;
  }
`;

const MyComponent: React.FC = () => {
  return <div className={myStyle}>Hello from Linaria!</div>;
};

export default MyComponent;
Enter fullscreen mode Exit fullscreen mode

In this example, css is a tagged template literal. The CSS defined within it will be extracted at build time and a unique class name (myStyle) will be generated and applied to the div element.

Using the styled component:

Linaria also provides a styled factory function that allows you to create styled components, similar to other CSS-in-JS libraries.

// src/components/AnotherComponent.tsx
import React from 'react';
import { styled } from '@linaria/react';

const StyledButton = styled.button`
  background-color: green;
  color: white;
  padding: 8px 15px;
  border: none;
  border-radius: 4px;
  cursor: pointer;

  &:hover {
    opacity: 0.8;
  }
`;

const AnotherComponent: React.FC = () => {
  return <StyledButton>Click Me!</StyledButton>;
};

export default AnotherComponent;
Enter fullscreen mode Exit fullscreen mode

Here, styled.button creates a StyledButton component that renders a <button> element with the defined styles.

Step 4: Run Your Application πŸš€

Now, start your Vite development server:

npm run dev
Enter fullscreen mode Exit fullscreen mode

Or build your project for production:

npm run build
Enter fullscreen mode Exit fullscreen mode

During the build process, Linaria will extract the CSS from your components and generate separate .css files, which will be automatically linked in your HTML. You can inspect your browser's developer tools to see that the styles are applied through regular CSS classes.

Conclusion πŸŽ‰

You have successfully integrated Linaria into your React, TypeScript, and Vite project! This setup allows you to enjoy the benefits of zero-runtime CSS-in-JS, leading to optimized performance and a streamlined development experience. Explore the Linaria documentation for more advanced features like theming and more! Happy styling! 🎨

Top comments (0)