New Template Offers Minimal Setup to Get React Working

The initialized project is designed for client-side applications exclusively.


This content originally appeared on HackerNoon and was authored by Valerio Ageno

\

Access the complete project here.

Requirements

  • Node.js (used just for building the project with vite)
  • NPM (node package manager)
  • Rustup (Rust language toolchain)
  • Cargo (Rust package manager)

Getting started

For this example, we will use Vite.js to set up the project and compile the React source code.

npm create vite@latest react-rust -- --template react-ts

\ The initialized project is designed for client-side applications exclusively. In the following section, we will explore what is necessary to adapt it for full-stack bundling.

React setup

React requires two distinct builds tailored for different environments:

  • The client-side build
  • The server-side build

\ What distinguishes these two outputs?

\ The client build incorporates all the hydration logic, enabling React to connect seamlessly with the HTML generated by the server. In contrast, the server build is a more streamlined version focused solely on rendering HTML based on the props received from the server.

\ Now, let’s create a new file named ./src/server.tsx, which will serve as the entry point for the server build, and insert the following code:

\

import "fast-text-encoding"; // Mandatory for React18
import { renderToString } from "react-dom/server";
import App from "./App";

export const Server = () => {
    const app = renderToString(<App />);
    return `<!doctype html>
<html>
    <head>
        <title>React + Rust = ❤️</title>
        <script type="module" crossorigin src="/index.js"></script>
    </head>
    <body>
        <div id="root">${app}</div>
    </body>
</html>`;
};

\

If you're working with React 18 or a newer version, it's essential to run npm install fast-text-encoding. This step is necessary because the Rust server lacks the Node.js objects and functions and the Web APIs. As a result, we need to provide a polyfill for TextEncoder, which is required by react-dom/server (in fact it is declared beforehand).

\ We need to modify the vite.config.ts file to include the two outputs:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        format: "iife",
        dir: "dist/",
      },
    },
  },
  ssr: {
    target: "webworker",
    noExternal: true,
  },
  plugins: [react()],
});

\ Next, we should add a new script in the package.json file.

-- "build": "tsc && vite build",
++ "build": "tsc && vite build && vite build --ssr src/server.tsx",

Prepare the Rust server

For this example, we will use axum, a web framework that works on top of tokio.

\ To get started, let's set up the Rust project by creating a Cargo.toml file in the main directory, containing the following details:

[package]
name = "react-rust-ssr-example"
version = "0.1.0"
edition = "2021"

[[bin]]
name = "ssr"
path = "src/server/server.rs"

[dependencies]
ssr_rs="0.7.0"
tokio = { version = "1", features = ["full"] }
axum = "0.7.4"
tower-http = {version = "0.6.0", features = ["fs"]}

\ This is the Rust manifest - pretty similar to the JavaScript package.json file.

\ Next, we’ll set up a file named src/server/server.rs, which will serve as the entry point for launching the Rust server.

use axum::{response::Html, routing::get, Router};
use ssr_rs::Ssr;
use std::cell::RefCell;
use std::fs::read_to_string;
use std::path::Path;
use tower_http::services::ServeDir;

thread_local! {
    static SSR: RefCell<Ssr<'static, 'static>> = RefCell::new(
            Ssr::from(
                read_to_string(Path::new("./dist/server.js").to_str().unwrap()).unwrap(),
                ""
                ).unwrap()
            )
}

#[tokio::main]
async fn main() {
    Ssr::create_platform();
    // build our application with a single route
    let app = Router::new()
        .route("/", get(root))
        .fallback_service(ServeDir::new("dist"));

    // run our app with hyper, listening globally on port 3000
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();
}

async fn root() -> Html<String> {
    let result = SSR.with(|ssr| ssr.borrow_mut().render_to_string(None));
    Html(result.unwrap())
}

\ This is where the magic unfolds. At the start of the program, we kick things off by initializing the JavaScript V8 engine with Ssr::create_platform(); Next, we create a V8 context in each thread using thread_local!. Finally, we render the HTML with SSR.with(|ssr| ssr.borrow_mut().render_to_string(None)); and send it to the client when the route http://localhost:3000/ is requested.

Run the server

To start the server, simply compile the assets with Vite and then launch the Rust server.

npm run build && cargo run

\ 🎊 You are running a full-stack React application using a Rust server. Finally, React runs within a multithreaded server (you can find some benchmarks here).

Final words

Managing a full-stack React application is not easy with Node.js that plenty of tools have been built overtime to support it, and as you could see with Rust it is even harder.

\ Tuono is an experimental full-stack framework aimed at simplifying the development of high-performance Rust applications, with a strong focus on both usability and speed.


This content originally appeared on HackerNoon and was authored by Valerio Ageno


Print Share Comment Cite Upload Translate Updates
APA

Valerio Ageno | Sciencx (2025-01-10T11:55:39+00:00) New Template Offers Minimal Setup to Get React Working. Retrieved from https://www.scien.cx/2025/01/10/new-template-offers-minimal-setup-to-get-react-working/

MLA
" » New Template Offers Minimal Setup to Get React Working." Valerio Ageno | Sciencx - Friday January 10, 2025, https://www.scien.cx/2025/01/10/new-template-offers-minimal-setup-to-get-react-working/
HARVARD
Valerio Ageno | Sciencx Friday January 10, 2025 » New Template Offers Minimal Setup to Get React Working., viewed ,<https://www.scien.cx/2025/01/10/new-template-offers-minimal-setup-to-get-react-working/>
VANCOUVER
Valerio Ageno | Sciencx - » New Template Offers Minimal Setup to Get React Working. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/01/10/new-template-offers-minimal-setup-to-get-react-working/
CHICAGO
" » New Template Offers Minimal Setup to Get React Working." Valerio Ageno | Sciencx - Accessed . https://www.scien.cx/2025/01/10/new-template-offers-minimal-setup-to-get-react-working/
IEEE
" » New Template Offers Minimal Setup to Get React Working." Valerio Ageno | Sciencx [Online]. Available: https://www.scien.cx/2025/01/10/new-template-offers-minimal-setup-to-get-react-working/. [Accessed: ]
rf:citation
» New Template Offers Minimal Setup to Get React Working | Valerio Ageno | Sciencx | https://www.scien.cx/2025/01/10/new-template-offers-minimal-setup-to-get-react-working/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.