A modular React component library for building blockchain transaction interfaces.
OpenSSF Scorecard Scorecard supply-chain security OpenSSF Best Practices CLA Assistant License: AGPL-3.0
This monorepo contains the following packages:
| Package | Description | npm |
|---|---|---|
| @openzeppelin/ui-types | Shared TypeScript type definitions | npm |
| @openzeppelin/ui-utils | Framework-agnostic utility functions | npm |
| @openzeppelin/ui-styles | Centralized styling system (Tailwind CSS 4) | npm |
| @openzeppelin/ui-components | React UI components (shadcn/ui based) | npm |
| @openzeppelin/ui-renderer | Transaction form rendering engine | npm |
| @openzeppelin/ui-react | React context providers and hooks | npm |
| @openzeppelin/ui-storage | IndexedDB storage abstraction (Dexie.js) | npm |
| @openzeppelin/ui-cli | CLI for new and existing OpenZeppelin UI applications | npm |
Install the packages you need:
# Core types and utilities
pnpm add @openzeppelin/ui-types @openzeppelin/ui-utils
# UI components
pnpm add @openzeppelin/ui-components @openzeppelin/ui-styles
# Form rendering
pnpm add @openzeppelin/ui-renderer
# React integration
pnpm add @openzeppelin/ui-react
# Storage (optional)
pnpm add @openzeppelin/ui-storageThese packages are released together from a single commit and are meant to be installed as one set. Install them at these versions:
| Package | Version | Requires from this set |
|---|---|---|
@openzeppelin/ui-types |
3.5.2 |
— |
@openzeppelin/ui-utils |
4.0.1 |
ui-types |
@openzeppelin/ui-components |
3.9.0 |
ui-types, ui-utils |
@openzeppelin/ui-storage |
1.2.5 |
ui-types, ui-utils |
@openzeppelin/ui-react |
3.3.2 |
ui-components, ui-types, ui-utils |
@openzeppelin/ui-renderer |
3.4.2 |
ui-components, ui-react, ui-types, ui-utils |
Each is optional on its own — install only what you use — but whichever you install must come from this table, not from a mix of it and an older release.
The packages in the table depend on each other through dependencies, not
peerDependencies — there is not one intra-kit peer range anywhere in the kit. A peer range
asks the consumer to supply a single shared copy; a dependency lets the package manager
satisfy the requirement on its own. So a mismatched set does not fail loudly, it resolves:
@openzeppelin/ui-components quietly gets a second, nested copy of @openzeppelin/ui-utils
at the version it asked for, alongside the one you installed.
Two copies of @openzeppelin/ui-utils is the case that bites, because it holds module-level
singletons: appConfigService is a single instance and logger is a getInstance(), and
each copy gets its own. Whichever copy your application initialises, the other stays
uninitialised and answers with defaults instead of your configuration — without throwing, so
nothing points at the cause. Two copies of @openzeppelin/ui-types instead produce TS2322
and TS2345 on structurally identical types.
None of this has to be taken on trust — the edges are in the published manifests:
npm view @openzeppelin/ui-components@3.9.0 dependencies --json | grep '@openzeppelin'The versions in the table do not share a major, and that is not a sign of a mismatch. Each package is versioned on its own API, so a breaking change in one moves that one alone; the others record it as a patch bump for an updated dependency. The set above is coherent whatever the majors happen to read.
@openzeppelin/ui-utils sits at 4.x while @openzeppelin/ui-components is at 3.x for
exactly that reason: it removed WalletConnect support in
#210, which was breaking for its
own consumers and nothing more than a dependency bump for everyone else. Do not try to line
the majors up, and do not read the gap as one package lagging behind another.
The table tells you what to install. To verify what actually resolved — including in a
project that also installs @openzeppelin/adapter-* packages, whose declared peer ranges
have to admit these versions — run:
pnpm add -D @openzeppelin/ui-dev-cli
pnpm exec oz-ui-dev check-peers --project "$PWD"It reports an adapter whose peer is older than the installed kit as an error, and a declared range that no longer admits the installed version as a warning. Worth running in CI after install; the packages it names are the ones to move.
Import the generated Tailwind wiring in your app's entry CSS. For new or existing consumer apps, the recommended path is to let oz-ui-dev tailwind fix create and maintain the managed file for you:
pnpm add -D @openzeppelin/ui-dev-cli
pnpm exec oz-ui-dev tailwind doctor --project "$PWD"
pnpm exec oz-ui-dev tailwind fix --project "$PWD"That command normalizes your entry stylesheet to import oz-tailwind.generated.css, which contains the required Tailwind v4 @source directives for OpenZeppelin UI and adapter packages.
If you need to wire it manually, your entry CSS must explicitly register the OpenZeppelin sources:
@layer base, components, utilities;
@import 'tailwindcss' source(none);
@source "./";
@source "../";
@source "../node_modules/@openzeppelin/ui-components";
@source "../node_modules/@openzeppelin/ui-react";
@source "../node_modules/@openzeppelin/ui-renderer";
@source "../node_modules/@openzeppelin/ui-styles";
@source "../node_modules/@openzeppelin/ui-utils";
@import '@openzeppelin/ui-styles/global.css';import { useForm } from 'react-hook-form';
import { Button, TextField } from '@openzeppelin/ui-components';
function MyForm() {
const { control, handleSubmit } = useForm();
return (
<form onSubmit={handleSubmit(onSubmit)}>
<TextField name="recipient" label="Recipient Address" control={control} placeholder="0x..." />
<Button type="submit">Send Transaction</Button>
</form>
);
}import { TransactionForm } from '@openzeppelin/ui-renderer';
import type { RenderFormSchema } from '@openzeppelin/ui-types';
const schema: RenderFormSchema = {
id: 'transfer-form',
title: 'Transfer Tokens',
fields: [
{ id: 'to', name: 'to', type: 'address', label: 'Recipient' },
{ id: 'amount', name: 'amount', type: 'amount', label: 'Amount' },
],
layout: { columns: 1, spacing: 'normal', labelPosition: 'top' },
submitButton: { text: 'Transfer', loadingText: 'Transferring...' },
};
function TransferPage() {
return (
<TransactionForm
schema={schema}
adapter={myAdapter}
networkConfig={networkConfig}
onSubmit={handleSubmit}
/>
);
}| Layer | Package | Purpose |
|---|---|---|
| App | Your Application | Consumer application |
| 7 | @openzeppelin/ui-storage |
IndexedDB storage |
| 6 | @openzeppelin/ui-renderer |
Form & contract UI rendering |
| 5 | @openzeppelin/ui-react |
Context providers & hooks |
| 4 | @openzeppelin/ui-components |
UI primitives & form fields |
| 3 | @openzeppelin/ui-styles |
Tailwind theme & variables |
| 2 | @openzeppelin/ui-utils |
Shared utilities |
| 1 | @openzeppelin/ui-types |
Type definitions |
- Node.js >= 20.19.0
- React 19
- Tailwind CSS 4
# Install dependencies
pnpm install
# Build all packages
pnpm build
# Run tests
pnpm test
# Lint
pnpm lint
# Type check
pnpm typecheckThis repo now ships the shared oz-ui-dev local-development CLI for OpenZeppelin consumer apps.
Existing first-party consumers such as ui-builder, role-manager, and rwa-wizard already check in the required .openzeppelin-dev.json, .pnpmfile.cjs, and dev:local / dev:npm scripts.
For a new consumer project, install the CLI once like a normal dev tool and then bootstrap the repo:
pnpm add -D @openzeppelin/ui-dev-cli
pnpm exec oz-ui-dev init --project "$PWD" --family uiThat creates a config-driven .pnpmfile.cjs, writes .openzeppelin-dev.json, records @openzeppelin/ui-dev-cli in devDependencies, and adds dev:local / dev:npm scripts that call oz-ui-dev directly. Developers only need local openzeppelin-ui or openzeppelin-adapters checkouts when they want to test package changes from source.
See CONTRIBUTING.md for development guidelines.
This project uses GitHub Speckit for spec-driven development. Feature specifications, implementation plans, and task breakdowns are managed in the .specify/ directory.
Note: Even if you're not using Speckit, please read the project constitution before contributing. It defines the architectural principles and quality standards that all contributions must follow.
- Migration Guide - Migrate from
@openzeppelin/ui-builder-* packages - LLM-led migration reference - AI-assisted workflow for
@openzeppelin/ui-cli(optional) - DevOps Setup Guide - CI/CD secrets and GitHub App configuration
- Operations Runbook - Release management and incident procedures