Build a Polymarket-Style UI in Minutes: Open-Source Prediction Market Components for React
23 shadcn-compatible React components and hooks for HIP-4 prediction markets on Hyperliquid. One command installs live orderbooks, market cards, price charts, and trading forms into your project.
The problem: every HIP-4 builder starts from scratch
Hyperliquid’s HIP-4 protocol is the most compelling infrastructure for prediction markets in crypto. On-chain orderbooks, sub-second finality, shared margin across asset classes, and the same matching engine that processes $200B+ per month in perpetual futures. The protocol is excellent. The developer tooling around it was not.
Every team building on HIP-4 was writing the same code: a market card component, an orderbook renderer, a trade form with tick size validation, WebSocket hooks for live prices. There was no shared component library, no reference implementation, no way to go from zero to a working prediction market UI without weeks of custom development.
We decided to fix that. Today we are open-sourcing @purrdict/hip4-ui — a shadcn-compatible component registry with 23 items (10 components, 11 hooks, 1 utility library, 1 quickstart bundle) that gives you a production-grade prediction market interface out of the box.
One command to get started
If you already have a React project with shadcn/ui set up, you can install everything with a single command:
npx shadcn@latest add https://ui.purrdict.xyz/r/hip4-quickstart.jsonThis installs all 23 registry items into your project — components, hooks, formatters, and a working example. The files land in your codebase (not hidden in node_modules), so you own and can modify every line.
Prefer to install only what you need? Each item has its own registry entry:
npx shadcn@latest add https://ui.purrdict.xyz/r/market-card.json
npx shadcn@latest add https://ui.purrdict.xyz/r/orderbook.json
npx shadcn@latest add https://ui.purrdict.xyz/r/trade-form.jsonThe registry lives at ui.purrdict.xyz and follows the same conventions as every other shadcn registry. If you have used shadcn/ui before, this will feel familiar.
What is in the registry
Components (10)
The component library covers the full surface area of a prediction market trading interface:
MarketCard — the workhorse. Displays a market with its current probability, expiry countdown, and volume. Supports four variants: event (one-time resolution), recurring (daily/weekly markets), named-binary (e.g., “BTC > $95k”), and question (multi-outcome). Feed it data from useMarkets and you have a market grid.
LivePriceChart — canvas-based real-time chart showing the underlying asset price (BTC, ETH, SOL, HYPE) that a prediction market resolves against. Includes a target price line so traders can see how close the underlying is to the strike. Powered by useUnderlyingPrice, which prefetches candle history then streams live updates via WebSocket.
ProbabilityChart — multi-line step-function chart for question markets with 3+ outcomes. Each outcome gets its own series, updated in real-time as prices move. For binary markets, use ProbabilityBar instead — a simpler two-tone visualization.
Orderbook — dual-pane Level 2 order book with bid/ask depth, spread display, and clickable price levels. Wired to useOrderbook for live WebSocket data.
TradeForm — complete trading form with side selection (Yes/No), order type, size input, slippage handling, and tick size validation. Handles the complexity of HIP-4’s 5-significant-figure pricing rule internally. Connects to useTrade for order submission.
RecentTrades, MarketStats, PositionCard, Countdown, ProbabilityBar — supporting components for trade feeds, volume stats, portfolio positions, expiry timers, and binary probability display.
Hooks (11)
The hooks are where the real engineering lives. They manage WebSocket connections, data normalization, and the bridge between Hyperliquid’s API and React’s rendering model.
HIP4Provider — React context that wraps your app. Creates and caches the Hyperliquid client (InfoClient + SubscriptionClient) so every hook can access it without prop drilling. Supports testnet and mainnet:
import { HIP4Provider } from "@/hooks/hip4/hip4-provider";
function App() {
return (
<HIP4Provider testnet={false}>
<MarketGrid />
</HIP4Provider>
);
}useMarkets — discovers all active HIP-4 prediction markets and streams live mid prices via WebSocket. Returns { markets, mids, isLoading }. This is the primary data source for building market listing pages.
useOrderbook — subscribes to a coin’s L2 order book. Returns { bids, asks, spread, midPrice }. Pass the result to the Orderbook component and TradeForm’s bookData prop.
useTrade — the order placement hook. Takes an ExchangeClient from @nktkas/hyperliquid and exposes buy(), sell(), and cancel(). Handles order action construction, tick size rounding, and builder fee attachment internally.
usePortfolio — fetches USDH balance, outcome token positions, and open orders for a connected wallet. Returns { usdh, positions, openOrders, refresh }.
useMinShares — computes the minimum order size for a given coin based on its current mark price. HIP-4’s minimum order formula is ceil(10 / max(min(markPx, 1-markPx), 0.01)) — at 50 cents that is 20 shares, at 1 cent it is 1,000 shares.
useUnderlyingPrice, useRecentTrades, useProbabilityHistory, useHIP4Client, useHIP4Signer round out the hook system for price charts, trade feeds, multi-outcome history, client management, and wagmi wallet integration.
The wiring model
Every component has a designated hook that feeds it data. The mapping is explicit:
MarketCard <- useMarkets
LivePriceChart <- useUnderlyingPrice
ProbabilityChart <- useProbabilityHistory
Orderbook <- useOrderbook
TradeForm <- useOrderbook + useTrade + useMinShares
RecentTrades <- useRecentTrades
PositionCard <- usePortfolioPresentation-only components (ProbabilityBar, MarketStats, Countdown) take raw props and have no data dependencies. This makes the architecture predictable: you always know which hook powers which component.
The SDK: @purrdict/hip4
The components are built on @purrdict/hip4 (v0.2.0), a pure knowledge layer for HIP-4 prediction markets. The SDK handles market discovery, tick size computation, order payload construction, and price formatting — all without doing any network I/O.
Key exports:
// Market discovery
discoverMarkets(outcomeMeta, allMids) // -> Market[]
getMinShares(markPx) // -> minimum order size
timeToExpiry(market) // -> ms until expiry
// Pricing (5 significant figure rule)
computeTickSize(price) // -> tick size
roundToTick(price) // -> nearest valid price
// Order construction
buildOrderAction({ asset, isBuy, price, size, tif, markPx })
// -> { ok: OrderAction } | { err: string }The SDK is tree-shakable, MIT-licensed, has zero runtime dependencies (only a peer dependency on @nktkas/hyperliquid), and is covered by 65 tests. It works with any Hyperliquid client — you do not need to use our UI components to benefit from it.
A working example: market grid to trading page
Here is what a minimal but functional prediction market app looks like with the registry components:
import { HIP4Provider } from "@/hooks/hip4/hip4-provider";
import { useMarkets } from "@/hooks/hip4/use-markets";
import { useOrderbook } from "@/hooks/hip4/use-orderbook";
import { useMinShares } from "@/hooks/hip4/use-min-shares";
import { useTrade } from "@/hooks/hip4/use-trade";
import { MarketCard } from "@/components/hip4/market-card";
import { Orderbook } from "@/components/hip4/orderbook";
import { TradeForm } from "@/components/hip4/trade-form";
function TradingPage({ coin }: { coin: string }) {
const { bids, asks } = useOrderbook(coin);
const { minShares } = useMinShares(coin);
return (
<div className="grid grid-cols-3 gap-4">
<Orderbook coin={coin} bids={bids} asks={asks} />
<TradeForm
sides={[{ name: "Yes", coin }]}
bookData={{ bids, asks }}
minShares={minShares}
isConnected={true}
onSubmit={async (params) => {
// wire to useTrade's buy()/sell()
}}
/>
</div>
);
}
function MarketGrid() {
const { markets, mids, isLoading } = useMarkets();
if (isLoading) return <div>Loading...</div>;
return (
<div className="grid grid-cols-3 gap-4">
{markets.map((m) => (
<MarketCard
key={m.yesCoin}
market={m}
yesMid={mids[m.yesCoin] ? parseFloat(mids[m.yesCoin]) : 0.5}
/>
))}
</div>
);
}
export default function App() {
return (
<HIP4Provider testnet={false}>
<MarketGrid />
</HIP4Provider>
);
}That is a live-updating market grid with real orderbook data and a trade form — all from registry components. A complete reference implementation lives at github.com/purrdict/hip4-example.
Zero-rerender architecture
Performance was a design constraint, not an afterthought. The hooks use useSyncExternalStore with a module-level price store, which means WebSocket price updates do not trigger React re-renders on every tick. Only components that actually display a changed price re-render.
This matters for prediction market UIs where you might be displaying dozens of markets with live prices simultaneously. Traditional useEffect + useState patterns would cause the entire market grid to re-render on every WebSocket message. Our approach keeps renders surgical.
AI-friendly by design
We built this registry expecting that many developers would use AI tools to integrate it. The repository includes a comprehensive CLAUDE.md file that serves as a knowledge base for Claude Code and other AI coding assistants. It documents every component, every hook, every prop, and every gotcha.
The CLAUDE.md covers things that trip up both humans and AI agents: StrictMode killing WebSocket connections, the difference between ExchangeClient (needs agent key) and HIP4Client (read-only), why builder addresses must be lowercased, and the distinction between ProbabilityChart (multi-outcome) and LivePriceChart (underlying asset price).
We also maintain Claude Code skills that provide specialized context for AI agents working with HIP-4 components. The goal is that an AI agent can go from “add prediction market trading to this app” to a working implementation without hallucinating prop names or misunderstanding the data flow.
Why shadcn, not a traditional component library
We chose the shadcn registry model deliberately. Traditional npm component libraries create a dependency relationship — you import from a package, and you are locked into that package’s API decisions, styling approach, and release cycle.
With the shadcn model, running npx shadcn@latest add copies the source code into your project. You get the component files in src/components/hip4/ and hook files in src/hooks/hip4/. You can read, modify, restyle, and extend anything. If our TradeForm does not match your product’s design, change it. If you need a custom variant of MarketCard, fork the file.
This is particularly important for prediction market UIs where every product has different requirements — different market types to emphasize, different trading workflows, different visual identities. A rigid component library would force everyone into the same mold.
How to contribute
The registry is MIT-licensed and lives at github.com/purrdict/hip4-ui. We welcome contributions of all kinds:
- New components — portfolio analytics, market creation forms, resolution displays
- Hook improvements — better caching, reconnection logic, new data sources
- Bug fixes and documentation — always appreciated
- AI-generated code — explicitly welcome. If Claude or Copilot wrote it and it passes tests, we will review it the same as any other PR
To get started developing:
git clone https://github.com/purrdict/hip4-ui
cd hip4-ui
bun install
bun testThe test suite validates component rendering, hook behavior, and SDK integration. Run bun run build to compile, and use bun scripts/generate-registry.ts in the site/ directory to regenerate the registry JSON files after changes.
What is next
This is v0.1.0. The component set covers the core trading experience, but there is more to build:
- Market creation UI — forms for deploying new prediction markets as HIP-4 moves toward permissionless creation
- Portfolio analytics — PnL tracking, trade history, performance charts
- Multi-outcome trading — specialized interfaces for question markets with many outcomes
- Mobile-optimized variants — responsive components designed for mobile-first trading
The Hyperliquid ecosystem is growing fast, and prediction markets are one of its most compelling applications. We want the developer tooling to keep pace with the protocol.
Try it
Install the quickstart bundle in your React project:
npx shadcn@latest add https://ui.purrdict.xyz/r/hip4-quickstart.jsonBrowse the registry at ui.purrdict.xyz. Read the SDK docs for @purrdict/hip4. Star the repo at github.com/purrdict/hip4-ui.
If you are building on HIP-4, you do not need to start from scratch anymore.
Ready to trade?
Put your predictions to work on Hyperliquid. Instant fills, no custody risk, fully on-chain.