Build a React App
When you want a straightforward client-rendered single-page app โ no build-time rendering, no
hydration โ Poops is just your bundler. One scripts entry points at your JSX/TSX entry, esbuild
does the rest.
Project layout
react-app/
โโ poops.json
โโ package.json # react + react-dom installed here
โโ src/
โโ scss/index.scss
โโ js/
โ โโ main.tsx # entry: mounts the app
โ โโ App.tsx
โ โโ components/
โโ markup/
โโ index.html # the shell with <div id="root">
The entry
// src/js/main.tsx
import { createRoot } from "react-dom/client";
import App from "./App";
createRoot(document.getElementById("root")!).render(<App />);
// src/js/App.tsx
import { useState } from "react";
export default function App() {
const [count, setCount] = useState(0);
return (
<main>
<h1>Hello from Poops</h1>
<button onClick={() => setCount((c) => c + 1)}>Count: {count}</button>
</main>
);
}
The config
{
"scripts": [
{
"in": "src/js/main.tsx",
"out": "dist/js/app.js",
"options": {
"minify": true,
"format": "iife",
"target": "es2019",
"jsx": "automatic"
}
}
],
"styles": [
{
"in": "src/scss/index.scss",
"out": "dist/css/styles.css",
"options": { "minify": true }
}
],
"markup": {
"in": "src/markup",
"out": "dist",
"options": {
"site": { "title": "My React App" },
"includePaths": ["_layouts", "_partials"]
}
},
"copy": [{ "in": "src/static", "out": "dist" }],
"serve": { "port": 4040, "base": "/dist" },
"livereload": true,
"watch": ["src"]
}
"jsx": "automatic" enables React 17+'s JSX runtime, so you don't import React in every file.
The HTML shell
Poops still builds your index.html โ use markup for the shell so relativePathPrefix and
site data work:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>{{ site.title }}</title>
<link rel="stylesheet" href="{{ relativePathPrefix }}css/styles.min.css" />
</head>
<body>
<div id="root"></div>
<script src="{{ relativePathPrefix }}js/app.min.js"></script>
</body>
</html>
Note
React comes from your project's node_modules (npm i react react-dom), not from Poops โ
see React.
Develop and build
poops # watch + serve + livereload at http://localhost:4040
poops -b # one-off production build into dist/
Tip
This is a pure SPA: nothing renders until the JS loads. If you want real HTML on first paint (better SEO and perceived speed), pre-render with Reactor instead โ see A complete React static site.
Info
For a library rather than an app โ shipping ESM/CJS/IIFE builds of your components โ see Transpiling JavaScript โบ Maintaining a JS library.