MDK Logo
React

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 -v shows 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 mdk

1.2 Install and build

npm install
npm run build

This 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-app

Ignore 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 install

Wrap 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 App

Connected 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 dev

Or from the app folder:

cd apps/my-app
npm run dev

You 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:demo

If your shell is still in the app folder:

cd ../..    # apps/my-app → apps → monorepo root
npm run dev:demo

Open http://localhost:5173/mdk to browse examples.

On this page