Custom Features
The Venue Starter ships features as self-contained modules — toggle them with env vars, extend them in place, or replace them with your own.
The Venue Starter organizes the app into feature modules under features/. Each module owns its routes, components, hooks, and SDK calls. Modules are cheaply removable (delete the folder + its imports) and cheaply replaceable (swap the implementation while keeping the route surface).
Feature Modules
The starter includes these modules out of the box:
| Module | What It Provides |
|---|---|
auth | Wallet connection via RainbowKit or Privy (email/social login) |
wallet | Deposits, withdrawals, USDC balance UI |
venue | Venue home, stats, and setup guard |
markets | Market browser, filters, tag pages |
market-detail | Per-market page: pricing, chart, orderbook, order form |
market-groups | Grouped-market rendering and NegRisk conversion UI |
price-market | Pyth-powered Up/Down and Strike market UI |
price-chart | Candlestick / line price history from the subgraph |
trading | Order form, slippage controls, batch quote UX |
orderbook | Live CLOB rendering and tick-level depth |
market-holders | Position viewer and redemption flow |
resolution | UMA asserter UI and Pyth resolution triggers |
leaderboard | Trader leaderboards backed by subgraph analytics |
trader-profile | Public profiles, PnL, open positions |
market-creation | Create binary, grouped, and price markets |
market-settings | Tag/metadata editor for market creators and venue operators |
access-control | Deploy and manage whitelist/NFT/token gates |
realtime | Subgraph polling + websocket-style updates |
theme-editor | Live color-picker for theme.config.json |
Each module is a plain directory of React components, hooks, and helpers — no framework of its own, no plugin system to learn.
Toggling Features with Env Vars
The common toggles are wired through config/venue.config.ts and flipped with env vars:
# Show the "Create Market" flow in the nav
NEXT_PUBLIC_ENABLE_MARKET_CREATION=true
# Expose the live theme editor (useful on staging)
NEXT_PUBLIC_ENABLE_THEME_EDITOR=true
# Choose a wallet auth provider
NEXT_PUBLIC_AUTH_PROVIDER=rainbowkit # or "privy"venueConfig.features is the single source of truth — read it in components instead of re-reading process.env:
import { venueConfig } from '@/config/venue.config';
export function Nav() {
return (
<nav>
<Link href="/markets">Markets</Link>
{venueConfig.features.enableMarketCreation && (
<Link href="/create">Create</Link>
)}
</nav>
);
}Removing a Feature
Feature modules are designed to be deleted cleanly. For example, to drop the leaderboard:
- Delete
features/leaderboard/ - Remove any
importof it (your TypeScript build will tell you where) - Remove the corresponding route from
app/if one exists
Because modules don't register with a central manifest, there's no plugin file to update.
Adding a Feature
Create a new folder under features/ and colocate everything the feature needs:
features/
my-feature/
components/
hooks/
queries.ts // subgraph or SDK calls
types.ts
index.ts // public API for the moduleExpose routes by creating files under app/ that import from features/my-feature:
// app/my-feature/page.tsx
import { MyFeaturePage } from '@/features/my-feature';
export default MyFeaturePage;Hook into the SDK client via the existing provider — useOddMakiClient() returns a fully configured client reading from NEXT_PUBLIC_VENUE_ID and the connected wallet.
Replacing a Feature
The common case is replacing the stock order form or market tile with your own. Because modules encapsulate their rendering, you can usually:
- Fork the module folder (e.g. copy
features/tradingtofeatures/my-trading) - Point the affected route at your fork
- Leave the original in place until you're ready to delete it
There's no inheritance or base-class model — just plain React components and SDK calls.
What's Next
- Custom Access Logic → — ship your own access-control contract
- SDK Reference → — every method the feature modules call under the hood
- Branding → — theme and brand configuration