Skip to content

Latest commit

 

History

538 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

OpenZeppelin UI

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

Packages

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

Installation

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-storage

Version compatibility

These 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.

Why the set is not optional

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'

Read the major numbers as independent

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.

Checking an installed tree

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.

Quick Start

1. Setup Styles

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';

2. Use Components

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>
  );
}

3. Render Transaction Forms

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}
    />
  );
}

Architecture

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

Requirements

  • Node.js >= 20.19.0
  • React 19
  • Tailwind CSS 4

Development

# Install dependencies
pnpm install

# Build all packages
pnpm build

# Run tests
pnpm test

# Lint
pnpm lint

# Type check
pnpm typecheck

Local Development (Consuming Projects)

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

That 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.

Contributing

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.

Documentation

License

AGPL-3.0

About

OpenZeppelin UI - React components and utilities for blockchain applications

Resources

Code of conduct

Contributing

Security policy

Stars

7 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages