Skip to main content

Installation

Requirements​

  • Node.js 22.18 or newer. That is everything the simulator needs. The engine ships prebuilt as WebAssembly inside the npm package, so there is no native toolchain to install.
  • A firmware toolchain (ESP-IDF, the Pico SDK, …) only once you flash a board.

Create a project​

npm create embedded-react@latest my-app

Then install and start the simulator:

cd my-app
npm install
npm run dev

npm run dev serves the simulator at http://localhost:3333. The next page, Run it in the simulator, covers what you can do there.

Start from a demo​

The starter is deliberately small: a card with a pulsing logo, a counter-button, and the panel size laid out to fit any panel. To begin from a complete app instead, pass a template:

npm create embedded-react@latest my-thermostat -- --template thermostat
npm create embedded-react@latest my-watch -- --template watch-face
TemplateWhat you get
starterThe minimal starter (the default)
starter-tsThe starter in TypeScript (same as --ts)
thermostatA thermostat with a draggable dial and a 14-day weather panel
watch-faceA digital watch face and a bubble level, sized for a 240×280 panel

npm create embedded-react@latest -- --list prints the current list.

Heading for a board with no external RAM?

Every template builds for the ahead-of-time flow. The thermostat and watch-face templates also come with a ready-made build:aot script. See Your first board.

What you get​

my-app/
index.jsx entry point: registers <App/>
App.jsx your UI
assets/ images and fonts; import them and they are baked automatically
package.json

The project depends on two packages: embedded-react and react. Its scripts wrap the embedded-react command-line tool:

ScriptRunsWhat it does
npm run devembedded-react devThe browser simulator, with hot reload
npm run dev:deviceembedded-react dev --deviceHot reload on a connected board over USB (Flow A)
npm run buildembedded-react buildThe device artifact for Flow A: dist/app.erpkg
npm run exportembedded-react exportA self-contained static copy of the simulator, to share or host

npx embedded-react --help lists every command and flag.

Adding to an existing project​

npm install embedded-react react@18.3.1
Use React 18.3.1 exactly

embedded-react pins react to 18.3.1. If your project resolves a different version, you end up with two copies of React, and the app renders a blank screen with a useRef of null error.

Add an entry file that registers your root component, then run npx embedded-react dev:

index.jsx
import {AppRegistry} from 'embedded-react';
import {App} from './App.jsx';

AppRegistry.registerComponent('my-app', () => App);

The CLI looks for index.jsx, index.tsx, then App.jsx (each at the root, then under src/), then the source or main field of package.json. build --aot looks for App.jsx or App.tsx instead. Pass a path to use a different entry: npx embedded-react dev path/to/entry.jsx.

The engine, for firmware​

The npm package is the app side. The firmware side needs the C engine, plus the Flow B runtime for Flow B. They ship at the same version number through the channels below. You only need this once you are wiring up a board; the example projects already do it for you.

include(FetchContent)
FetchContent_Declare(embedded-react
GIT_REPOSITORY https://github.com/TheMasterCoder007/embedded-react.git
GIT_TAG v0.20.0
SOURCE_SUBDIR engine)
FetchContent_MakeAvailable(embedded-react)
target_link_libraries(my_firmware PRIVATE embedded-react)

For Flow B, add the runtime from the same checkout:

add_subdirectory(${embedded-react_SOURCE_DIR}/runtime ${embedded-react_BINARY_DIR}/runtime)
target_link_libraries(my_firmware PRIVATE erb-runtime)

The engine is backend-agnostic: you supply the code that pushes pixels to your display. See Engine and backends.