Skip to content

Instantly share code, notes, and snippets.

@teradyne
Created April 22, 2026 00:46
Show Gist options
  • Select an option

  • Save teradyne/9f91f5a870d62ae35bd3ef7780dbc386 to your computer and use it in GitHub Desktop.

Select an option

Save teradyne/9f91f5a870d62ae35bd3ef7780dbc386 to your computer and use it in GitHub Desktop.
Perplexity Finance UI Analysis - Frameworks, Components, and Architecture

Perplexity Finance UI Analysis

Q1: Examine the HTML file and give me a report of what components they are using

Not Next.js

This is not a Next.js project. It's a Vite-based SPA (Single Page Application) served from Perplexity AI's CDN. The build identifier is web-resources-build: 2026.4.21.646.

Frameworks & Libraries

Layer Technology
Bundler Vite (via Rolldown runtime)
UI Framework React (SPA with <div id="root">)
Animation Framer Motion
Data Fetching React Query
Rich Text Editor Lexical
Charting VisX (GridRows, TooltipWithBounds, useTweenedPath)
i18n Custom i18n module
Routing Custom SPA router (sub-router, routes)
Styling CSS bundle + dark/light theme via data-color-scheme attribute
Fonts Custom: PPLX Sans Beta v2 (variable), FK Grotesk Neue

Key UI Components (from module preloads)

  • Finance-specific: FinancePriceChange, FinanceMover, FinanceStockHistoryPeriodUtils, FinanceStockHistoryCurrentPrice, FinanceKeyTickersGroup, FinancePortfolio
  • Charts: PredictionMarketChart, DotGrid, LiveIndicator
  • Content: MarkdownRenderer, MarkdownStreamer, MarkdownResponse, NewsArticleCard, TextBlockSkeleton
  • Citations: CitationDomainBubble, CitationFavicon, CitationPile, CitationDomain, InlineCitationCaption
  • Layout: CanonicalCard, CanonicalHeader, CanonicalContainer, CanonicalQuery, CanonicalLink
  • UI Primitives: Badge, TabBar, ToggleGroup, ToggleTip, SelectButton, DropDownModal, AnimateHeight, Calendar
  • Sharing: ShareDropdown, SocialShareLinks
  • Data: Watchlist queries, quote fetching, earnings, financials, company profile, newswire documents

REST API Endpoints (prefetched)

The page eagerly prefetches for a given ticker symbol:

  • /rest/finance/quote/{symbol} (with history)
  • /rest/finance/profile/{symbol}
  • /rest/finance/documents/{symbol}
  • /rest/finance/earnings/{symbol}
  • /rest/finance/financials/{symbol}

Design System

Perplexity uses an internal design system called "Aether" (aether-core) with a platform component layer (platform-core, platform-components). Icons come from a custom pplx-icons package. Cookie-based visitor tracking and session management are handled inline.


Q2: Tell me more about Aether

What It Is

Aether is Perplexity's custom React design system. It's not open-source or publicly documented — it's bundled as aether-core and consumed internally by their platform-components and platform-core layers.

Architecture (3 Layers)

Layer Module Role
aether-core Design primitives Tokens, base components, theming
platform-core App infrastructure Auth, routing, API clients, analytics, state
platform-components App-level UI Error boundaries, providers, device detection

Aether Core Components

  • Text / Heading — Typography primitives with variant system
  • Button — Core interactive element
  • Link — Navigation-aware anchor
  • Icon — Icon system wrapper
  • Spinner — Loading indicator
  • Tooltip — Compound component (Provider, Trigger, Portal, Content, Arrow)
  • Popper — Generic positioned floating element (Root, Anchor, Content, Arrow)
  • Portal — React portal abstraction
  • VisuallyHidden — Accessibility helper
  • DismissableLayer — Click-outside / Escape dismiss behavior
  • Presence — Mount/unmount animation wrapper

Design Tokens

Spacing scale: 2xs, xs, sm, md, ml, lg, xl

Typography variants: micro, tiny, small, base, section-title, page-title, display, entry-title, editorial

Font sizes: 2xs through 4xl | Weights: normalextrabold | Line heights: tightloose | Tracking: tighterwidest

Colors:

  • Foreground: foreground, quiet, quieter, super, inverse, white
  • Semantic: positive, negative, caution, warning
  • Surface: background, underlay, raised, subtle
  • Finance-specific: finance-positive, finance-negative

Border radius: sm through 3xl, full

Z-index layers: base, raised, navigation, overlay, modal, toast, critical

Key Patterns

  • Compound components — Tooltip and Popper use the Provider/Trigger/Content pattern (similar to Radix UI)
  • Floating UI integration — Offset, Shift, Flip, Size, Hide, Arrow middleware for positioning
  • Tailwind-based — Utility classes are generated/mapped from tokens (e.g., bg-background, px-md, rounded-xl)
  • Responsive helpers — Breakpoint-aware variant selectors
  • Theme systemColorSchemeProvider with data-color-scheme attribute toggling light/dark
  • Context providersAetherProvider wraps the app, composing ColorSchemeProvider, ModalStoreProvider, TooltipProvider, LinkComponentProvider, LabelsProvider, SurfaceProvider

Platform Core (Infrastructure)

Built on top of Aether, this provides:

  • Auth: NextAuth-style session/sign-in/sign-out with CSRF
  • Routing: Custom SPA router with useRouter, useLocation, useSearchParams
  • API client: Typed REST client with SSE streaming support
  • State: Reactive store factory (createReactiveStore) with proxy-based selectors
  • Performance: Datadog integration, page timing vitals, transition perf tracking
  • Feature flags: Query-count gating, subscription tier checks, A/B experimentation
  • Logging: Structured browser logger + Sentry error reporting

Summary

Aether is heavily inspired by Radix UI primitives but is a custom implementation. It pairs with Tailwind CSS for styling and uses Floating UI for positioning. The token system is tight and opinionated — small set of scales, not overly configurable. The whole stack (Aether → Platform Core → Platform Components) gives Perplexity a vertically integrated UI framework purpose-built for their product.


Q3: What other things do I need to know to build a UI like this?

1. Core Stack

Concern What They Use Open-Source Equivalent
Bundler Vite + Rolldown Vite (Rolldown is experimental; Rollup works fine)
UI Library React 19 React 19
Styling Tailwind CSS Tailwind CSS
State (server) React Query v5 @tanstack/react-query
State (client) Zustand + Immer zustand, immer
Routing Custom SPA router react-router or @tanstack/router

2. Charting (Critical for Finance)

They use VisX (Airbnb's low-level D3+React library), not a high-level chart library like Recharts.

Components you'd need:

  • LinePath / AreaClosed — price history curves
  • GridRows — horizontal grid lines
  • Axis (Bottom/Left) — time and price axes
  • TooltipWithBounds — crosshair tooltip on hover
  • scaleLinear / scaleTime — D3 scales for mapping data to pixels
  • useTweenedPath — animated transitions between time periods

This gives full control over segment coloring (green/red based on gain/loss), after-hours shading, and custom tick formatting. Higher-level libraries won't give you this.

3. Financial Data Layer

REST API endpoints you need to serve:

  • GET /quote/{symbol} — current price, change, volume, market cap
  • GET /quote/{symbol}?with_history=true&history_period=1d — OHLC time-series
  • GET /profile/{symbol} — company info, sector, description
  • GET /financials/{symbol} — income statement, balance sheet, cash flow
  • GET /earnings/{symbol} — EPS estimates vs actuals, earnings dates
  • GET /documents/{symbol} — SEC filings, news articles

Time periods supported: 1D, 5D, 1M, 6M, YTD, 1Y, 5Y, Max

Data sources (for your backend): Yahoo Finance API, Polygon.io, Alpha Vantage, or Financial Modeling Prep.

4. Real-Time Streaming

They use SSE (Server-Sent Events) — not WebSockets.

Key patterns:

  • SSE endpoint at /rest/sse/perplexity_ask for AI-generated answers
  • Cursor-based resume via /rest/sse/subscribe/entry/{id}
  • JSON Patch (RFC 6902) for incremental state updates instead of full replacements
  • Rate limiting: 20 reconnects/min, 120/hour
  • Max 50 concurrent streams
  • AbortController for cancellation

For stock price ticking, you'd need a separate WebSocket or SSE feed from your data provider.

5. UI Components to Build

Finance-specific:

  • PriceChangeIndicator — arrow + colored percentage (green/red/neutral), supports animated number transitions
  • FinanceAssetLogo — ticker logo with text-initial fallback
  • StockHistoryChart — the main interactive chart with period selector
  • FinanceMover — market movers cards (top gainers/losers)
  • FinanceKeyTickersGroup — index ticker strip (S&P 500, NASDAQ, DOW)
  • WatchlistTable — user's saved tickers
  • PortfolioView — holdings with P&L
  • EarningsCalendar — upcoming/past earnings with EPS data
  • PeerComparison — side-by-side metrics
  • StockScreener — filterable table of stocks

General (from Aether):

  • TabBar — period selector (1D/5D/1M/etc.)
  • ToggleGroup — segmented control
  • DropDownModal — filter/sort menus
  • Badge — status labels
  • AnimateHeight — collapsible sections
  • ShareDropdown + SocialShareLinks — share functionality
  • MarkdownRenderer / MarkdownStreamer — for AI-generated analysis text

6. Number Formatting

They use Intl.NumberFormat heavily:

  • Currency formatting with locale awareness
  • Percentage with 2 decimal places (change values divided by 100)
  • Compact notation for large numbers (1.2B, 340M)
  • Monospace font toggle for tabular alignment

7. Theming

  • Light/dark mode via data-color-scheme attribute on <html>
  • Cookie-persisted preference with system default fallback
  • Finance-specific tokens: finance-positive (green) and finance-negative (red) with /10 and /20 opacity variants for backgrounds

8. Monitoring

  • Datadog RUM v6 for performance metrics, session replay, and error tracking
  • Page timing vitals (TTFB, TTV) tracked per route
  • Custom duration vitals for key interactions

9. AI Integration (the Perplexity differentiator)

The AI "ask about this stock" feature uses:

  • Lexical as the rich text editor for the input box
  • SSE streaming for token-by-token AI response rendering
  • MarkdownStreamer to render markdown as it arrives
  • Citation system — inline numbered references with favicon bubbles and domain labels

Minimum Viable Stack for a Clone

If you want to build something similar without overengineering:

React 19 + Vite + Tailwind
@tanstack/react-query (server state)
zustand (client state)
@visx/visx (charts)
react-router (routing)
Intl.NumberFormat (formatting)
EventSource API (SSE streaming)

The hardest parts to replicate aren't the UI — they're the real-time data pipeline and the AI-powered analysis. The frontend is well-built but uses standard, accessible tools.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment