This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Morpho Lite Monorepo containing two React web applications for Morpho Blue and MetaMorpho contracts, plus a shared UIKit package. The apps are designed to work with only public RPCs—no additional infrastructure required.
Apps:
- Fallback (
apps/fallback) - MIT licensed resilient emergency frontend with minimal dependencies - Lite (
apps/lite) - AGPL-3.0 licensed lightweight frontend for rapid multichain expansion, supports whitelabeling
Shared Package:
- UIKit (
packages/uikit) - MIT licensed component library and utilities used by both apps
# Install dependencies (required first time)
pnpm install
# Development mode (builds UIKit first, then runs app)
pnpm run fallback-app:dev # Fallback app at http://localhost:5173
pnpm run lite-app:dev # Lite app at http://localhost:5173
# Production build
pnpm run fallback-app:build # Builds UIKit + Fallback
pnpm run lite-app:build # Builds UIKit + Lite
# UIKit only
pnpm run uikit:build # Build UIKit package
pnpm run uikit:example # Run UIKit example app# Run tests across all workspaces
pnpm run test # Uses vitest workspace configuration
# Run tests in specific app
cd apps/fallback && pnpm run test
cd apps/lite && pnpm run testTest files use pattern: test/**/*.{test,spec}.{ts,tsx} in each workspace.
# Lint all workspaces
pnpm run lint
# Format checking/fixing (in specific workspace)
cd apps/lite && pnpm run format # Auto-fix
cd apps/lite && pnpm run format:check # Check only
# Type checking
cd packages/uikit && pnpm run typecheckPre-commit Hook: Husky runs lint-staged which applies ESLint and Prettier to changed files.
cd apps/lite
# GraphQL (gql-tada for type-safe queries)
pnpm run tada:doctor # Validate GraphQL setup
pnpm run tada:gen # Generate GraphQL types
pnpm run tada:cache # Cache GraphQL introspection
# Deployment
pnpm run deploy # Build and deploy to Vercel- Framework: React 19 with Vite
- Styling: Tailwind CSS 4 + shadcn components
- Web3: wagmi 2.15.2, viem 2.29.1
- State/Caching: @tanstack/react-query with persistence
- Routing: Lite app uses React Router v7 BrowserRouter
- Type Safety: TypeScript 5.7, strict mode enabled
- Testing: Vitest with jsdom, @testing-library/react
This is a pnpm workspace with three main packages:
apps/fallback- Fallback appapps/lite- Lite apppackages/uikit- Shared UIKit (consumed by both apps as@morpho-org/uikit)
Important: UIKit must be built before running/building apps. The dev/build commands handle this automatically.
Located in packages/uikit/src/:
Hooks:
use-contract-events/- RobustuseContractEventshook with adaptiveeth_getLogsfetching strategies. Automatically handles RPC constraints, retries, and parallel transport testing to find fastest RPC.use-keyed-state.ts- Prevents state desynchronization when switching chains by keying state to chain IDuse-debounced-memo.ts- Memoization with debouncinguse-deep-memo.ts- Deep equality memoizationuse-request-tracking.tsx- Tracks pending requests with context
Utilities:
lib/utils.ts- Formatting helpers (formatBalance,formatBalanceWithSymbol,formatLtv,formatApy), token utilities, bigint comparisonslib/deployments.ts-DEPLOYMENTSmapping of Morpho contracts (Morpho, MetaMorphoFactory, MetaMorphoV1_1Factory) per chain with addresses and fromBlocklib/chains/- Custom chain definitions
Lens Contracts (tevm):
lens/*.sol- Solidity lens contracts for efficient multicall data fetchinglens/*.ts- TypeScript wrappers using tevm for type-safe contract interactions
Components:
components/- shadcn-based UI components with Morpho styling
Important: The restructure function (from @morpho-org/blue-sdk-viem) is used in useReadContracts select parameters to convert tuple arrays into objects. Example in apps/lite/src/hooks/use-markets.ts:15.
Single page app with no URL routing. Key files:
src/App.tsx- DefineswagmiConfig, sets up providers/contextssrc/app/dashboard/earn-subpage.tsx- Fetches MetaMorpho vault data via eventssrc/app/dashboard/borrow-subpage.tsx- Fetches Morpho Blue borrow positions via eventssrc/lib/wagmi-config.ts- Chain and RPC configuration (uses wallet RPC first, falls back to drpc.org)src/lib/constants.ts- App constants including deployment addresses
Multi-page app with React Router. Additional features:
- GraphQL: Uses
gql-tada+urqlfor type-safe Merkl rewards queries - Whitelabeling: Configurable via constants and curators list
- Configuration Files:
src/lib/constants.tsx-APP_DETAILS,WORDMARK,MIN_TIMELOCK,DEFAULT_CHAIN,TERMS_OF_USE,BANNERSsrc/lib/curators.ts- Curator whitelist (addresses must be checksummed)src/lib/tokens.ts- Token metadatasrc/lib/wagmi-config.ts- Chain/RPC configuration.env- API keys and app title (see.env.template)
Important: Lite app requires SPA redirect configuration (all URLs → index.html). Already configured in vercel.json for Vercel deployments.
Both apps fetch on-chain data primarily through event logs using the useContractEvents hook:
- Identify relevant events (e.g.,
CreateMetaMorpho,Deposit,SupplyCollateral) - Fetch events using adaptive strategy that finds optimal block range per request
- Extract addresses/IDs from events
- Batch fetch detailed data using
useReadContracts
This approach minimizes RPC calls and works reliably with public RPCs.
- Update
wagmiConfiginapps/fallback/src/lib/wagmi-config.ts- add chain and RPC URL(s) that supporteth_getLogs - Update
DEPLOYMENTSinpackages/uikit/src/lib/deployments.ts- add Morpho contract addresses andfromBlockvalues - (Optional) Add chain icon SVG to
packages/uikit/src/assets/chains/and updateChainIconcomponent inpackages/uikit/src/components/chain-icon.tsx - Test thoroughly
Same as Fallback, plus:
- Update
apps/lite/src/lib/wagmi-config.ts - Update constants in
apps/lite/src/lib/constants.tsx - (Optional) Add banner configuration in
BANNERSconstant
Note: Default chunk size for eth_getLogs is 10,000 blocks. If a chain has more restrictive RPC limits, the useContractEvents hook may need adjustment.
- Fallback App: MIT - permissive
- Lite App: AGPL-3.0 - requires preserving "Powered by Morpho" branding and open-sourcing modifications
- UIKit: MIT - permissive
- Never commit API keys or secrets to
.envfiles - Only whitelist vault
owneraddresses in curators list (notcuratorrole, as it can be assigned without acceptance) - Addresses in deployments and curators must be checksummed (proper capitalization)
- Lite app deploys to Vercel via
pnpm run deployinapps/lite - Both apps support Fleek deployment (via
@fleek-platform/cli) - Ensure SPA routing is configured (all routes →
index.html)
- UIKit changes require rebuild:
pnpm run uikit:build - Apps automatically rebuild UIKit in dev mode but watch mode is manual
- Use parallel dev scripts (
pnpm run lite-app:dev) which handle UIKit build + parallel watch - Import from UIKit using
@morpho-org/uikit/path/to/file(e.g.,@morpho-org/uikit/hooks/use-contract-events)
- ESLint enforces TypeScript best practices, React hooks rules, and import ordering
- Imports are auto-sorted alphabetically with newlines between groups
- Prettier handles formatting with Tailwind CSS plugin
- No floating promises allowed (
@typescript-eslint/no-floating-promises) - Unused variables error (except rest siblings)