How To: Using Svelte In A React App
Published: 2024-01-29 18:00:35

by [Chisom Uma](https://blog.openreplay.com/authors/chisom-uma)


<blockquote><em>
In web development, as we know it, we often encounter a lot of frameworks and libraries, each with its own strengths, nuances, and philosophies. React, a “juggernaut” in this domain, has firmly established itself as the go-to choice for building interactive UIs. But what happens when we want to incorporate the elegance and simplicity of another emerging star—Svelte—into our existing React-based applications? Can these two powerhouses coexist harmoniously within the same codebase? The answer is a resounding "yes," and this article aims to show you how.
</em></blockquote>


<div style="background-color:#efefef; border-radius:8px; padding:10px; display:block;">
<hr/>
<h3><em>Session Replay for Developers</em></h3> 
<p><em>Uncover frustrations, understand bugs and fix slowdowns like never before with <strong><a href="https://github.com/openreplay/openreplay" target="_blank">OpenReplay</a></strong> — an open-source session replay suite for developers. It can be <strong>self-hosted</strong> in minutes, giving you complete control over your customer data.</em></p>
<img alt="OpenReplay" style="margin-top:5px; margin-bottom:5px;" width="768" height="400" src="https://raw.githubusercontent.com/openreplay/openreplay/main/static/openreplay-git-hero.svg" class="astro-UXNKDZ4E" loading="lazy" decoding="async">
<p><em>Happy debugging! <a href="https://openreplay.com" target="_blank">Try using OpenReplay today.</a></em><p>
<hr/>
</div>


If you love dynamic web apps, [Svelte](https://svelte.dev/) is a framework you would love to use if you aren't already familiar with it. Svelte is a modern JavaScript framework designed to create fast, lightweight static web applications, providing an enjoyable experience for developers and users. It allows you to construct individual, reusable components for diverse projects, including larger applications built with Angular, React, Vue, or other frameworks. Alternatively, you can use Svelte to develop entire web applications.

In most comparisons with other frameworks, Svelte stands out due to its ability to generate smaller code bundles, resulting in faster browser performance than Angular or React. This efficiency is a significant aspect of Svelte's appeal. More importantly, developers find working with Svelte highly satisfying, as building components and applications with it feels akin to using pure JavaScript.

### Why use Svelte in a React App?

Incorporating Svelte into a React app can offer several advantages, enhancing the development process and user experience. Here are a few reasons why you might consider using Svelte within the React application:


- **Performance:** Svelte is renowned for its small bundle size and efficient runtime, leading to faster loading times and improved performance. Integrating Svelte components into a React app can enhance overall speed and responsiveness.


- **Simplicity:** Svelte's intuitive syntax and simplicity make it attractive, especially for developers who find React's learning curve steep. Svelte's approach to reactive programming and component-based architecture simplifies complex UI tasks, making the development process more straightforward.


- **Ease of Learning:** If your team is already familiar with React, introducing Svelte can be relatively seamless. Svelte's similarity to vanilla JavaScript and its minimalistic approach make it easy for React developers to grasp and adopt.


- **Reduced Boilerplate Code:** Svelte requires less boilerplate code than React. This reduced code overhead can lead to more concise and readable components, improving maintainability and reducing the chance of errors.


- **Reactivity:** Svelte's reactivity system allows developers to create highly responsive user interfaces without complex state management libraries. This can simplify state handling within your React application, making it easier to manage and debug.


- **Animation and Transitions:** Svelte provides a straightforward way to implement animations and transitions, making creating visually appealing user interfaces easier. Integrating Svelte components into your React app can enhance the user experience through smooth animations and transitions.


- **Community and Ecosystem:** While React has a vast and established ecosystem, Svelte's community is growing rapidly. By combining both frameworks, you can leverage the strengths of both communities, accessing a wider range of libraries, tools, and resources.


- **Micro Frontends:** Svelte can be a great choice for building micro frontends within a React application. Its lightweight nature and ease of integration make it suitable for creating self-contained, independent components that can be seamlessly incorporated into a larger React-based project.

By incorporating Svelte into your React app, you can capitalize on the strengths of both frameworks, leading to a more performant, efficient, and visually appealing user interface while simplifying the development process for your team.


## Integrating Svelte Into React

To get started with our project, we are going to use `pnpm` to create a Vite application by running this command on your terminal:

```
pnpm create vite svelte-inside-react --template
```

After running the command, you will get the following framework options shown below:


![-](https://blog.openreplay.com/images/how-to--using-svelte-in-a-react-app/images/s_6AC958C739B3A56D1D06C82DBB06E6EAB23EFC084827BE790A22827D0638A0BE_1698944154315_Screenshot+2023-11-02+175540.png)


Select React and JavaScript as the main languages used in the project. After installation, run the `pnpm run dev` command. This is what it looks like on the browser:


![-](https://blog.openreplay.com/images/how-to--using-svelte-in-a-react-app/images/s_6AC958C739B3A56D1D06C82DBB06E6EAB23EFC084827BE790A22827D0638A0BE_1698944605169_Screenshot+2023-11-02+180118.png)


 


Our `src` folder looks like this:


    📦src
     ┣ 📂assets
     ┃ ┗ 📜react.svg
     ┣ 📜App.css
     ┣ 📜App.jsx
     ┣ 📜index.css
     ┗ 📜main.jsx

Next, let's clear out the default code in the `App.css` and `index.css` files and edit the `App.jsx` file to look like this:
```javascript
import { useState } from "react";
import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";
import "./App.css";
function App() {
  const [count, setCount] = useState(0);
  return (
    <div className="card">
      <button onClick={() => setCount((count) => count + 1)}>
        count is {count}
      </button>
    </div>
  );
}
export default App;
```
Now for the exciting moment: integrating Svelte into our React app. To do this, head over to your code editor terminal and install the Vite plugin for Svelte using the following command:

```
pnpm add @sveltejs/vite-plugin-svelte -D
```

Next, we want to install Svelte by running the following command:

```
pnpm add svelte
```

We need to configure it. To do this, go to the `vite.config.js` file at the bottom of the directory and edit it to look like this:
```javascript
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { svelte } from "@sveltejs/vite-plugin-svelte";
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react(), svelte()],
});
```
Here, we imported our Svelte plugin and included the code `svelte()`. To create our first Svelte component, navigate to the `src` folder and create a `Hello.svelte` file, then write a simple HTML code inside the file. In our case, we created a simple `div` tag with a “Hello from Svelte” greeting like this:
```html
<div>
    Hello from Svelte!
</div>
```
In our `App.jsx` file, we imported it like this:
```javascript
import { useState } from "react";
import Hello from "./Hello.svelte";
```
Now, to make it work properly, we need to first define an element where we will mount our Svelte component. Inside the `App.jsx` file, let's edit the code to look like this:
```javascript
import { useState, useRef, useLayoutEffect } from "react";
import Hello from "./Hello.svelte";

function App() {
  const [count, setCount] = useState(0);
  const svelteRef = useRef();
  useLayoutEffect(() => {
    while (svelteRef.current?.firstChild) {
      svelteRef.current?.firstChild?.remove();
    }
    new Hello({
      target: svelteRef.current,
    });
  }, []);
  return (
    <div>
      <div ref={svelteRef}></div>
      <button onClick={() => setCount((count) => count + 1)}>
        count is {count}
      </button>
    </div>
  );
}
export default App;
```
In the code snippet above, the React functional component `App` utilizes `useState` to manage a simple counter state, `useRef` to create a reference to a DOM element, and `useLayoutEffect` for imperative DOM manipulations essential for embedding the Svelte component `Hello`. 

We strategically employed the `useLayoutEffect`  to clear any existing children of the referenced DOM element and then mount the Svelte component, ensuring smooth integration and avoiding conflicts in DOM management. The code also features a button that, when clicked, increments the counter, demonstrating basic React state management. 

We also created a `div` tag to reference our HTML component by using `use.` In this case, `svelteRef.current` references the HTML `div` element. Before this worked, we mounted the app using the `useLayoutEffect` hook.

When we run our app on the browser, this is what it looks like:

![-](https://blog.openreplay.com/images/how-to--using-svelte-in-a-react-app/images/s_6AC958C739B3A56D1D06C82DBB06E6EAB23EFC084827BE790A22827D0638A0BE_1698965506572_Screenshot+2023-11-02+235042.png)

Congratulations! Your Svelte has been successfully integrated into your React App. Let's build out the rest of our demo app using Svelte in React.


## Shared CSS (Tailwind and Daisy UI) between React and Svelte

In this section, we will look at how to perform shared CSS between React and Svelte. For our CSS, we will be using Tailwind and Daisy UI. 

To get started, head to your code editor terminal and run the following command:

```
pnpm add autoprefixer postcss tailwindcss daisyui -D
```

Next, let's create a `tailwind.config.cjs` file in our directory like this:

![-](https://blog.openreplay.com/images/how-to--using-svelte-in-a-react-app/images/s_6AC958C739B3A56D1D06C82DBB06E6EAB23EFC084827BE790A22827D0638A0BE_1699383558952_Screenshot+2023-11-07+195858.png)

Here we bring in our tailwind configuration:
```javascript
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx,svelte}"],
  theme: {
    extend: {},
  },
  plugins: [require("daisyui")],
};
```   
Above is the stock React tailwind configuration. Daisy UI is included here, as well as Svelte. The next thing we need to do is create a `postcss.config` file and include the following code:
```javascript
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
};
```
In our `index.css` file, we can then bring in tailwind CSS :
```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```
If you rerun the project, this is what you see:

![-](https://blog.openreplay.com/images/how-to--using-svelte-in-a-react-app/images/s_6AC958C739B3A56D1D06C82DBB06E6EAB23EFC084827BE790A22827D0638A0BE_1699385578607_Screenshot+2023-11-07+203118.png)


This indicates that the project is now running on tailwind CSS. In our `App.jsx` file, let's edit the code to create a button. The code should look like this:
```html
<div>
  <div ref={svelteRef}></div>
  <button
    className="btn btn-success"
    onClick={() => setCount((count) => count + 1)}
  >
    count is {count}
  </button>
</div>
```
Then, in our `Hello.svelte` file, let's enlarge the text by writing the following code:
```html
<div class="text-3xl font-bold">
    Hello from Svelte!
</div>
```
Here's what our demo should look like after running the app on the browser:


![-](https://blog.openreplay.com/images/how-to--using-svelte-in-a-react-app/images/s_6AC958C739B3A56D1D06C82DBB06E6EAB23EFC084827BE790A22827D0638A0BE_1699388366503_Screenshot+2023-11-07+211822.png)


<CTA_Middle_Frameworks />



## Sending properties to our Svelte Components in React

In this section, you will learn how to send properties to our Svelte components. This starts with knowing how to define properties in Svelte. To do this, go to the `Hello.svelte` file and include the following code:
```javascript
<script>
    export let extraText = "Default text";
</script>
<div class="text-3xl font-bold">
    Hello from Svelte! {extraText}
</div>
```
We first brought in a `script` tag, then we defined a property using the `export let` variable and gave it a value of “default text.” This is what it looks like on the browser:


![-](https://blog.openreplay.com/images/how-to--using-svelte-in-a-react-app/images/s_6AC958C739B3A56D1D06C82DBB06E6EAB23EFC084827BE790A22827D0638A0BE_1699390562563_Screenshot+2023-11-07+215141.png)


Now, let's go over to our `App.jsx` and edit the code to look like this:
```javascript
new Hello({
      target: svelteRef.current,
      props: {
        extraText: "Text from React",
      },
    });
```
The code creates a new instance of a Svelte component `Hello` and mounts it within a React component, using a reference `svelteRef.current` to a DOM element. This setup allows for the passage of props from the React parent to the Svelte child, exemplified by the `extraText` prop carrying the string "Text from React." This technique can be particularly useful when specific Svelte features are needed in a React project or during a transition phase from Svelte to React.

It should look like this on the browser:

![-](https://blog.openreplay.com/images/how-to--using-svelte-in-a-react-app/images/s_6AC958C739B3A56D1D06C82DBB06E6EAB23EFC084827BE790A22827D0638A0BE_1699390915365_Screenshot+2023-11-07+220131.png)


You are probably wondering what happened to the “default text” value. In our code above, we specified `props` and `extraText` in `new Hello`. Now, we have a property going to the Svelte component. 

We can even use this for callbacks. So, in our `App.jsx` file, edit the code like this:
```javascript
new Hello({
      target: svelteRef.current,
      props: {
        extraText: "Text from React",
        onClick: () => alert("Got click from Svelte"),
      },
    });
```
In the `Hello.svelte` file, edit it to look like this:
```javascript
<script>
    export let extraText = "Default text";
    export let onClick = () => {};
</script>
<div class="text-3xl font-bold" on:click={onClick}>
    Hello from Svelte! {extraText}
</div>
```
When you click on the text on our app, you get this notification:


![-](https://blog.openreplay.com/images/how-to--using-svelte-in-a-react-app/images/s_6AC958C739B3A56D1D06C82DBB06E6EAB23EFC084827BE790A22827D0638A0BE_1699392860471_Screenshot+2023-11-07+222636.png)


How cool is that?  🙂

 

## Creating a Svelte `Wrap` in our React App

You may be wondering, “how do we make this generic so we can do this for any Svelte component? ” To answer this, what we have to do is create a Svelte wrapper function. Navigate to your `App.jsx` file and paste it into the following code:
```javascript
import { useState, useRef, useLayoutEffect } from "react";
import Hello from "./Hello.svelte";
import { svelte } from "@sveltejs/vite-plugin-svelte";

function SvelteWrapper(Component) {
  return (props) => {
    const svelteRef = useRef();
    useLayoutEffect(() => {
      while (svelteRef.current?.firstChild) {
        svelteRef.current?.firstChild?.remove();
      }
      new Component({
        target: svelteRef.current,
        props,
      });
    }, []);
    return <div ref={svelteRef}></div>;
  };
}
const SvelteHello = SvelteWrapper(Hello);
function App() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <SvelteHello
        extraText="This is a prop passed from React to Svelte"
        onClick={() => setCount((count) => count + 1)}
      />
      <button className="btn btn-success" onClick={(count) => count + 1}>
        count is {count}
      </button>
    </div>
  );
}
export default App;
```
We created a `SveleteWrapper` function. Its job is to take a Svelte component and return a React component. This is what it looks like on the browser:


![-](https://blog.openreplay.com/images/how-to--using-svelte-in-a-react-app/images/s_6AC958C739B3A56D1D06C82DBB06E6EAB23EFC084827BE790A22827D0638A0BE_1699398099908_Screenshot+2023-11-08+000102.png)


As shown in the image above, the “This is a prop passed from React to Svelte” text was gotten from React.


## Shared Global State between Svelte and React

This section shows you how to do shared global states between Svelte and React. We will use Zustand, authored by [Daishi Kato](https://github.com/dai-shi) for this. 

To get started, go to your terminal and run this command:

```
pnpm add zustand
```

Next, we will create a `store.js` file in our `src` folder and include the following code:
```javascript
import { create } from "zustand";
import { readable } from "svelte/store";
const useStore = create((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
}));
export const counter = readable(useStore.getState(), (set) => {
  const unsubscribe = useStore.subscribe(set);
  return () => unsubscribe();
});
export default useStore;
```
In your `App.jsx` file, edit the code to look like this:
```javascript
import { useState, useRef, useLayoutEffect } from "react";
import Hello from "./Hello.svelte";
import Counter from "./Counter.svelte";
import useStore from "./store";

function SvelteWrapper(Component) {
  return (props) => {
    const svelteRef = useRef();
    useLayoutEffect(() => {
      while (svelteRef.current?.firstChild) {
        svelteRef.current?.firstChild?.remove();
      }
      new Component({
        target: svelteRef.current,
        props,
      });
    }, []);
    return <div ref={svelteRef}></div>;
  };
}
const SvelteHello = SvelteWrapper(Hello);
const SvelteCounter = SvelteWrapper(Counter);

function App() {
  const { count, increment } = useStore();
  return (
    <div>
      <SvelteHello
        extraText="This is a prop passed from React to Svelte"
        onClick={increment}
      />
      <button className="btn btn-success" onClick={increment}>
        count is {count}
      </button>
      <SvelteCounter />
    </div>
  );
}
export default App;
```    
In our `store.js` code, we started by bringing in the `create` function from Zustand. The `create` function creates a global React hook. With this, we created our `useState` counter. 

In our `App.jsx` file, we imported `useStore`. Instead of `setCount`, we used `increment`. 

Back in our `store.js` file, we created a `readable` Svelte store, invoked it, and `exported` it as our `counter.` We also wrote an initialization function that takes in `set`. Then we `subscribe` to our store. When our app fires up, it will call `set`. To do that, we have to create a `Counter.svelte` file and include the following code:
```javascript
<script>
  import {counter} from "./store.js";
</script>
<button
  type="button"
  class="btn btn-success btn-lg m-2"
  on:click={$counter.increment}
>
  Svelte - Count is {$counter.count}
</button>
```
Here, we started by bringing in our counter. We also created a button where `onClick` calls the increment function we get from the `store`, and then we display the count. Let’s see the outcome in the GIF below:


![-](https://blog.openreplay.com/images/how-to--using-svelte-in-a-react-app/images/s_6AC958C739B3A56D1D06C82DBB06E6EAB23EFC084827BE790A22827D0638A0BE_1699402410126_ezgif.com-video-to-gif.gif)


We have shared states currently running between our React and Svelte app.


## Conclusion 

In conclusion, the seamless integration of Svelte into a React application, as described in this article, underscores the flexibility and interoperability of modern web frameworks. It demonstrates how the streamlined syntax and performance advantages of Svelte can complement the robustness and extensive ecosystem of React. 

This integration leverages the best of both worlds—enhancing performance with Svelte's smaller bundle sizes and simplified reactivity system while capitalizing on React's established practices and community support. By following the steps outlined—from setting up the environment to sharing CSS and global states—developers can create a powerful combination of these technologies to build dynamic, efficient, and visually stunning web applications.

Here is the [GitHub code](https://github.com/ChisomUma/sveltereactdemo) for our project. Happy coding!!