Wire a React app
[⏱️ ~5 min] Step-by-step walkthrough — scaffold an app, wrap in MdkProvider, and use adapter hooks with foundation components
This tutorial walks you through the full React stack: three workspace packages, <MdkProvider>, and adapter hooks.
For a faster path that renders one presentational component without the provider, see Your first component.
Prerequisites
- Node.js 20+
- npm 11+ (upgrade npm if
npm -vshows 10.x on Node 22) - React 19+ and react-dom 19+
Clone and build
The MDK UI monorepo (mdk-ui) is an npm workspace. Clone the repository, install at the repo root, and build all packages before adding an app or
running the demo.
1.1 Clone the repository
git clone https://github.com/tetherto/mdk.git
cd mdk1.2 Install and build
npm install
npm run buildThis builds @tetherto/mdk-react-devkit and the other packages in the monorepo workspace.
Create your app
2.1 Scaffold a Vite React app
Create a new React app in the apps/ folder:
cd apps
npm create vite@latest my-app -- --template react-ts
cd my-appIgnore the CLI "Now run" instructions — follow the MDK-specific steps below.
2.2 Add MDK to package.json
Open package.json and add all three workspace packages:
"@tetherto/mdk-react-devkit": "*",
"@tetherto/mdk-react-adapter": "*",
"@tetherto/mdk-ui-core": "*",2.3 Install from the workspace root
cd ../.. # from apps/my-app back up to the monorepo root
npm installWrap your app in MdkProvider
<MdkProvider> wires the headless stores from @tetherto/mdk-ui-core into React and sets up the TanStack QueryClient. It is required for adapter hooks and connected foundation components. See also Quickstart — Wrap your app in MdkProvider.
3.1 Update main.tsx
import { MdkProvider } from '@tetherto/mdk-react-adapter'
import '@tetherto/mdk-react-devkit/styles.css'Wrap <App />:
<MdkProvider apiBaseUrl="https://app-node.example.com">
<App />
</MdkProvider>Use adapter hooks and render a component
Adapter hooks subscribe to Zustand stores and re-render when the selected slice changes. This example uses useAuth and useDevices from the adapter, then renders a presentational SingleStatCard from foundation.
4.1 Replace App.tsx
import { Button } from '@tetherto/mdk-react-devkit/core'
import { SingleStatCard } from '@tetherto/mdk-react-devkit/foundation'
import { useAuth, useDevices } from '@tetherto/mdk-react-adapter'
function App() {
const { permissions } = useAuth()
const { selectedDevices } = useDevices()
return (
<div style={{ padding: '2rem', display: 'grid', gap: '1rem', maxWidth: 360 }}>
<h1>Operator dashboard</h1>
<p>Selected devices: {selectedDevices?.length ?? 0}</p>
<p>Permissions loaded: {permissions ? 'yes' : 'no'}</p>
<SingleStatCard
name="Inlet temperature"
value={28}
unit="°C"
variant="primary"
/>
<Button onClick={() => console.log('Ready for connected components')}>
Log readiness
</Button>
</div>
)
}
export default AppConnected foundation components (device explorers, pool manager, settings dashboards) expect <MdkProvider> and often read multiple stores. Start with presentational imports while you wire your API; swap in connected components as your backend comes online.
Run your app
From the monorepo root:
npm -w my-app run devOr from the app folder:
cd apps/my-app
npm run devYou should see the operator dashboard with device and permission readouts plus a temperature card. The adapter hooks confirm <MdkProvider> is wired — without it, they would throw.
Next steps
- Quickstart: install reference, store hooks, and theming
- Core: primitives reference (
@tetherto/mdk-react-devkit/core) - Foundation: mining-domain components (
@tetherto/mdk-react-devkit/foundation)
Run the demo app
If you are already at the monorepo root:
npm run dev:demoIf your shell is still in the app folder:
cd ../.. # apps/my-app → apps → monorepo root
npm run dev:demoOpen http://localhost:5173/mdk to browse examples.