UI Component Audit
Generated: 2026-05-31
Branch: feat/ui-changes-1
Scope: every file in the monorepo that renders pixels — packages/ui, packages/marketing, apps/web (components/, app/, UI-relevant hooks/), apps/community (components/, app/), and every third-party UI dependency declared in any package.json.
Summary
| Layer | Files | Used | Unused |
|---|---|---|---|
packages/ui components |
54 | 30 | 24 |
packages/ui hooks |
2 | 2 | 0 |
packages/ui lib |
1 (cn) |
1 (108 indirect consumers) | 0 |
apps/web/components (top-level) |
13 | 12 | 1 (dev-floating-panel) |
apps/web/components/conversation |
9 | 9 | 0 |
apps/web/components/diffs |
9 | 9 | 0 (barrel-exported) |
apps/web/components/legal |
1 | 1 | 0 |
apps/web/components/markdown |
2 | 2 | 0 |
apps/web/components/workbench-tabs |
3 | 3 | 0 |
apps/web/app/** route files |
65 | n/a (each is a route) | n/a |
apps/web/hooks (UI) |
1 | 1 | 0 |
packages/marketing |
7 | 7 | 0 |
apps/community/components |
13 | 13 | 0 |
apps/community/app |
3 | 3 | 0 |
| External UI deps | ~30 | 28 | 2 (@react-three/fiber, @react-three/drei) |
Headline removal candidates:
- Drop
@react-three/fiber+@react-three/dreifromapps/web— 0 imports. - Drop
apps/web/components/dev-floating-panel.tsx— the upstream layout no longer mounts it. - Audit the 22 zero-import
packages/uicomponents — Drawer, Combobox, Command, Calendar, Form, Field, Fieldset, Pagination, OTP Field, Number Field, Meter, Slider, Progress, Table, Empty, Kbd, Group, Frame, Collapsible, Checkbox Group, Preview Card, Alert Dialog, Accordion. Many ship as part of the shadcn baseline; decide which to keep "for future use" vs. delete.
Table of contents
- packages/ui design system
- packages/ui hooks & utilities
- apps/web shared components
- apps/web route files
- apps/web UI hooks
- packages/marketing
- apps/community
- External UI dependencies
- Removal candidates
1. packages/ui design system
54 components, exported via @workspace/ui/components/<name>. Usage column counts unique files outside packages/ui/src/components/ that import ... from "@workspace/ui/components/<name>". "Internal" counts other UI library files that import this component.
Layout
| Component | Path | Exports | Base | Used | Internal |
|---|---|---|---|---|---|
| Card | card.tsx |
Card, CardFrame, CardHeader, CardTitle, CardDescription, CardAction, CardPanel, CardFooter, CardContent (alias of CardPanel), CardFrameHeader, CardFrameTitle, CardFrameDescription, CardFrameAction, CardFrameFooter |
@base-ui/react/merge-props + use-render |
17 | 0 |
| ScrollArea | scroll-area.tsx |
ScrollArea, ScrollBar, ScrollAreaPrimitive |
@base-ui/react/scroll-area |
0 | 6 |
| Separator | separator.tsx |
Separator, SeparatorPrimitive |
@base-ui/react/separator |
5 | 4 |
| Collapsible | collapsible.tsx |
Collapsible, CollapsibleTrigger, CollapsiblePanel, CollapsibleContent (alias) |
@base-ui/react/collapsible |
0 | 0 |
| Group | group.tsx |
Group, GroupText, GroupSeparator, ButtonGroup (alias), ButtonGroupText, ButtonGroupSeparator, groupVariants |
@base-ui/react/merge-props + CVA |
0 | 0 |
| Frame | frame.tsx |
Frame, FramePanel, FrameHeader, FrameTitle, FrameDescription, FrameFooter |
none (plain divs) | 0 | 0 |
| Toolbar | toolbar.tsx |
Toolbar, ToolbarButton, ToolbarLink, ToolbarInput, ToolbarGroup, ToolbarSeparator, ToolbarPrimitive |
@base-ui/react/toolbar |
1 | 0 |
Forms & inputs
| Component | Path | Exports | Base | Used | Internal |
|---|---|---|---|---|---|
| Input | input.tsx |
Input, InputPrimitive, type InputProps |
@base-ui/react/input |
13 | 4 |
| Label | label.tsx |
Label |
@base-ui/react/merge-props + use-render |
4 | 1 |
| Textarea | textarea.tsx |
Textarea, FieldPrimitive, type TextareaProps |
@base-ui/react/field |
3 | 1 |
| Select | select.tsx |
Select, SelectTrigger, SelectValue, SelectPopup, SelectItem, SelectGroup, SelectLabel, SelectGroupLabel, SelectSeparator, SelectButton, selectTriggerVariants, selectTriggerIconClassName, SelectPrimitive |
@base-ui/react/select + CVA |
6 | 0 |
| Switch | switch.tsx |
Switch, SwitchPrimitive |
@base-ui/react/switch |
3 | 0 |
| Checkbox | checkbox.tsx |
Checkbox, CheckboxPrimitive |
@base-ui/react/checkbox |
2 | 0 |
| RadioGroup | radio-group.tsx |
RadioGroup, Radio, RadioGroupItem (alias), RadioGroupPrimitive, RadioPrimitive |
@base-ui/react/radio + radio-group |
2 | 0 |
| InputGroup | input-group.tsx |
InputGroup, InputGroupAddon, InputGroupText, InputGroupInput, InputGroupTextarea |
composes Input/Textarea | 1 | 0 |
| Field | field.tsx |
Field, FieldLabel, FieldItem, FieldDescription, FieldError, FieldControl, FieldValidity, FieldPrimitive |
@base-ui/react/field |
0 | 0 |
| Fieldset | fieldset.tsx |
Fieldset, FieldsetLegend, FieldsetPrimitive |
@base-ui/react/fieldset |
0 | 0 |
| Form | form.tsx |
Form, FormPrimitive |
@base-ui/react/form |
0 | 0 |
| CheckboxGroup | checkbox-group.tsx |
CheckboxGroup, CheckboxGroupPrimitive |
@base-ui/react/checkbox-group |
0 | 0 |
| Combobox | combobox.tsx |
Combobox + ~25 sub-parts, useComboboxFilter |
@base-ui/react/combobox |
0 | 0 |
| Autocomplete | autocomplete.tsx |
Autocomplete + ~15 sub-parts, useAutocompleteFilter |
@base-ui/react/autocomplete |
0 | 1 (Command) |
| NumberField | number-field.tsx |
NumberField, NumberFieldGroup, NumberFieldDecrement, NumberFieldIncrement, NumberFieldInput, NumberFieldScrubArea, CursorGrowIcon, NumberFieldContext, NumberFieldPrimitive |
@base-ui/react/number-field |
0 | 0 |
| OTPField | otp-field.tsx |
OTPField, OTPFieldInput, OTPFieldSeparator, OTPFieldPrimitive |
@base-ui/react/otp-field (uses Base UI's preview API) |
0 | 0 |
| Slider | slider.tsx |
Slider, SliderValue, SliderPrimitive |
@base-ui/react/slider |
0 | 0 |
Buttons & actions
| Component | Path | Exports | Base | Used | Internal |
|---|---|---|---|---|---|
| Button | button.tsx |
Button, interface ButtonProps |
@base-ui/react/merge-props + use-render |
43 | 6 |
| buttonVariants | button-variants.tsx |
buttonVariants, type ButtonVariantProps |
pure CVA | 12 | 3 |
| Toggle | toggle.tsx |
Toggle, TogglePrimitive, toggleVariants |
@base-ui/react/toggle + CVA |
2 | 1 |
| ToggleGroup | toggle-group.tsx |
ToggleGroup, ToggleGroupItem, ToggleGroupSeparator, ToggleGroupContext, ToggleGroupPrimitive |
@base-ui/react/toggle-group |
2 | 0 |
Overlays
| Component | Path | Exports | Base | Used | Internal |
|---|---|---|---|---|---|
| Menu | menu.tsx |
Menu, MenuTrigger, MenuPortal, MenuPopup, MenuGroup, MenuItem, MenuCheckboxItem, MenuRadioGroup, MenuRadioItem, MenuGroupLabel, MenuSeparator, MenuShortcut, MenuSub, MenuSubTrigger, MenuSubPopup, MenuCreateHandle, MenuPrimitive |
@base-ui/react/menu |
3 | 0 |
| Dialog | dialog.tsx |
Dialog, DialogTrigger, DialogPortal, DialogClose, DialogBackdrop, DialogViewport, DialogPopup, DialogHeader, DialogFooter, DialogTitle, DialogDescription, DialogPanel, DialogCreateHandle, DialogPrimitive |
@base-ui/react/dialog |
1 | 0 |
| Popover | popover.tsx |
Popover, PopoverTrigger, PopoverPopup, PopoverClose, PopoverTitle, PopoverDescription, PopoverCreateHandle, PopoverPrimitive |
@base-ui/react/popover |
1 | 0 |
| Tooltip | tooltip.tsx |
Tooltip, TooltipTrigger, TooltipPopup, TooltipContent (alias), TooltipProvider, TooltipCreateHandle, TooltipPrimitive |
@base-ui/react/tooltip |
1 | 1 |
| PreviewCard | preview-card.tsx |
PreviewCard, PreviewCardTrigger, PreviewCardPopup, HoverCard (alias), HoverCardTrigger, HoverCardContent, PreviewCardPrimitive |
@base-ui/react/preview-card |
0 | 0 |
| AlertDialog | alert-dialog.tsx |
AlertDialog, AlertDialogTrigger, AlertDialogPortal, AlertDialogClose, AlertDialogBackdrop, AlertDialogViewport, AlertDialogPopup, AlertDialogHeader, AlertDialogFooter, AlertDialogTitle, AlertDialogDescription, AlertDialogCreateHandle, AlertDialogPrimitive |
@base-ui/react/alert-dialog |
0 | 0 |
| Sheet | sheet.tsx |
Sheet, SheetTrigger, SheetPortal, SheetClose, SheetBackdrop, SheetViewport, SheetPopup, SheetHeader, SheetFooter, SheetTitle, SheetDescription, SheetPanel, SheetOverlay (alias), SheetContent (alias), SheetPrimitive |
@base-ui/react/dialog (side-anchored) |
0 | 1 (Sidebar) |
| Drawer | drawer.tsx |
Drawer + ~25 sub-parts (incl. in-drawer menu set) |
@base-ui/react/drawer + checkbox/radio/radio-group |
0 | 0 |
| Command | command.tsx |
Command, CommandInput, CommandList, CommandEmpty, CommandPanel, CommandGroup, CommandGroupLabel, CommandCollection, CommandItem, CommandSeparator, CommandShortcut, CommandFooter, CommandDialog + dialog sub-parts |
@base-ui/react/dialog wrapping Autocomplete |
0 | 0 |
Navigation
| Component | Path | Exports | Base | Used | Internal |
|---|---|---|---|---|---|
| Tabs | tabs.tsx |
Tabs, TabsList, TabsTab, TabsPanel, TabsTrigger (alias), TabsContent (alias), TabsPrimitive, type TabsVariant |
@base-ui/react/tabs |
1 | 0 |
| Sidebar | sidebar.tsx |
Sidebar + ~25 sub-parts, SidebarProvider, useSidebar, SidebarContext |
@base-ui/react/merge-props + composes Sheet/Tooltip/Input/Skeleton/Separator/ScrollArea/Button |
3 | 0 |
| Breadcrumb | breadcrumb.tsx |
Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbPage, BreadcrumbSeparator, BreadcrumbEllipsis |
@base-ui/react/merge-props + use-render |
2 | 0 |
| Pagination | pagination.tsx |
Pagination, PaginationContent, PaginationItem, PaginationLink, PaginationPrevious, PaginationNext, PaginationEllipsis, type PaginationLinkProps |
uses buttonVariants |
0 | 0 |
Feedback
| Component | Path | Exports | Base | Used | Internal |
|---|---|---|---|---|---|
| Skeleton | skeleton.tsx |
Skeleton |
none | 10 | 1 |
| Toast | toast.tsx |
ToastProvider, AnchoredToastProvider, toastManager, anchoredToastManager, ToastPrimitive, type ToastPosition, interfaces ToastProviderProps, AnchoredToastProviderProps |
@base-ui/react/toast |
2 | 0 |
| Alert | alert.tsx |
Alert, AlertTitle, AlertDescription, AlertAction |
CVA (no Base UI) | 2 | 0 |
| Spinner | spinner.tsx |
Spinner |
none (Tabler IconLoader2) | 0 | 1 (Button) |
| Progress | progress.tsx |
Progress, ProgressLabel, ProgressTrack, ProgressIndicator, ProgressValue, ProgressPrimitive |
@base-ui/react/progress |
0 | 0 |
| Empty | empty.tsx |
Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent |
CVA (no Base UI) | 0 | 0 |
Data display
| Component | Path | Exports | Base | Used | Internal |
|---|---|---|---|---|---|
| Badge | badge.tsx |
Badge, badgeVariants, type BadgeProps |
@base-ui/react/merge-props + CVA |
21 | 0 |
| Avatar | avatar.tsx |
Avatar, AvatarImage, AvatarFallback, AvatarPrimitive |
@base-ui/react/avatar |
6 | 0 |
| Accordion | accordion.tsx |
Accordion, AccordionItem, AccordionTrigger, AccordionPanel, AccordionContent (alias), AccordionPrimitive |
@base-ui/react/accordion |
0 | 0 |
| Table | table.tsx |
Table, TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell, TableCaption, type TableVariant |
none (semantic HTML) | 0 | 0 |
| Calendar | calendar.tsx |
Calendar |
react-day-picker |
0 | 0 |
| Meter | meter.tsx |
Meter, MeterLabel, MeterTrack, MeterIndicator, MeterValue, MeterPrimitive |
@base-ui/react/meter |
0 | 0 |
| Kbd | kbd.tsx |
Kbd, KbdGroup |
none | 0 | 0 |
Notes on packages/ui
- Every Base UI–backed component re-exports its underlying primitive as
<Name>Primitiveso consumers can drop down to raw parts (e.g.DialogPrimitive,TooltipPrimitive). - Several shadcn-style aliases are kept:
AccordionContent,CardContent,CollapsibleContent,HoverCard/HoverCardContent,RadioGroupItem,SheetOverlay/SheetContent,TabsTrigger/TabsContent,TooltipContent,ButtonGroup/ButtonGroupText/ButtonGroupSeparator. button-variants.tsxis separated frombutton.tsxso non-button consumers (pagination.tsx,toast.tsx, several app components) can pull the CVA recipe without importing the Button component.command.tsxandsheet.tsxboth reuse@base-ui/react/dialograther than introducing a new primitive.drawer.tsxis the largest single component (~628 lines) and imports four Base UI primitives to support its in-drawer menu controls.otp-field.tsxuses@base-ui/react/otp-field's preview/unstable namespace — note if API stability matters.calendar.tsxis the only component that builds onreact-day-pickerinstead of Base UI.alert.tsx,empty.tsx,frame.tsx,kbd.tsx,skeleton.tsx,spinner.tsx, andtable.tsxhave no Base UI dependency at all — they're plain styled HTML wrappers.sidebar.tsxcallscookieStore.set(...)to persist sidebar state — that browser API is not available in all browsers (Firefox/Safari at audit time) and there's no try/catch.button-variants.tsxdefines anicon-xssize that overrides icon sizing only when not inside[data-slot=input-group], a subtle context-aware behavior to know when composing buttons insideInputGroup.
2. packages/ui hooks & utilities
Hooks
| File | Exports | Purpose |
|---|---|---|
packages/ui/src/hooks/use-mobile.ts |
useIsMobile(): boolean |
Hard-coded 768px viewport check with matchMedia + useState/useEffect. Initial render returns false, causing a one-frame flicker. |
packages/ui/src/hooks/use-media-query.ts |
useMediaQuery(query), useIsMobile(), type MediaQueryInput |
SSR-safe (useSyncExternalStore) with a typed breakpoint vocabulary (`sm |
Two
useIsMobilehooks exist with different breakpoints and SSR behavior. Sidebar uses theuse-media-query.tsone. Pick one and delete the other.
Utilities
| File | Exports | Purpose |
|---|---|---|
packages/ui/src/lib/utils.ts |
cn(...inputs: ClassValue[]): string |
clsx + tailwind-merge. Imported by 108 files across the monorepo — the single most-used UI helper. |
3. apps/web shared components
apps/web/components (top level)
| File | Exports | Purpose | UI deps | External deps | Used |
|---|---|---|---|---|---|
app-site-chrome.tsx |
AppSiteChrome, SITE_HEADER_CARD_CLASS |
Shared top site chrome (logo, nav, user button, workbench tab strip); standalone floating card or embedded toolbar. | buttonVariants, Skeleton |
@stackframe/stack, next/image, next/link |
7 |
open-git-user-button.tsx |
OpenGitUserButton |
Avatar dropdown menu (profile, settings, sign out); signed-out fallback = sign-in button. | Button, Menu, Avatar, Skeleton |
@stackframe/stack, next/link |
3 |
copy-to-clipboard-button.tsx |
CopyToClipboardButton |
Button that copies a string and flashes a check icon on success. | Button |
@tabler/icons-react |
3 |
user-identity-orb.tsx |
UserIdentityOrb |
3D GPU-rendered username-derived chroma blob shown during onboarding. | — | gsap, three |
2 |
resource-query-filter-bar.tsx |
ResourceQueryFilterBar |
GitHub-style chips + free-text filter bar for issues/PRs, syncs to ?q=. |
Button, InputGroup, InputGroupAddon |
@tabler/icons-react, next/navigation |
2 |
repository-home-doc-panel.tsx |
RepositoryHomeDocPanel |
Renders the repo home doc (README) with tab strip across candidate doc files. | buttonVariants |
next/link |
2 |
legal-page-shell.tsx |
LegalPageShell |
Black/white marketing-style shell for legal pages with header/article/footer. | — | next/link |
2 |
theme-provider.tsx |
ThemeProvider |
next-themes wrapper with hotkey toggling. | — | next-themes |
1 |
stack-profile-image-editor.tsx |
ProfileImageEditor (re-export) |
Re-export of Stack Auth's internal ProfileImageEditor. Fragile — reaches into node_modules/@stackframe/stack/dist/.... |
— | @stackframe/stack (deep import) |
1 |
site-scroll-header.tsx |
SiteScrollHeader |
Sticky site header that floats to a compact pill on scroll past hero. | — (composes AppSiteChrome) |
next/image, next/link |
1 |
settings-nav.tsx |
SettingsNav, SettingsNavSkeleton |
Sidebar nav for /settings/* (account, developer, orgs, payment). |
Sidebar, Skeleton |
@tabler/icons-react, @stackframe/stack, next/link |
1 |
layout-preference-preview.tsx |
LayoutShellPreview |
Mini wireframe preview of contained-vs-full-screen layout option in display preferences. | — | @tabler/icons-react |
1 |
dev-floating-panel.tsx |
DevFloatingPanel |
Dev-only floating bug button → popover of toggles (e.g. mock onboarding). | buttonVariants, Label, Popover, Switch |
@tabler/icons-react |
0 — REMOVAL CANDIDATE (upstream layout dropped the mount) |
apps/web/components/conversation
| File | Exports | Purpose | UI deps | Used |
|---|---|---|---|---|
conversation-profile-username.tsx |
ConversationProfileUsername |
Username rendered as a profile link when namespace is linkable, else plain text. | — | 8 |
conversation-quote-reply.tsx |
ConversationQuoteReplyProvider, ConversationQuoteReplyHeaderMenu, useConversationQuoteReplyOptional, CONVERSATION_QUOTE_COMPOSER_ID, type ConversationQuoteReplySession |
Context + menu that lets readers quote-reply to a comment (prefills main composer). | Button, Menu |
5 |
conversation-meta.tsx |
ConversationRelativeTime, ConversationSignInPrompt |
Tabular <time> element + "Sign in to comment" prompt. |
— | 4 |
timeline-primitives.tsx |
TimelineAvatar, conversationCardClass |
Profile-linked avatar + shared card class for timeline entries. | Avatar |
3 |
conversation-chrome.tsx |
ConversationCardHeader, ConversationCardFooter, ConversationMoreActionsButton |
Card chrome primitives shared by every conversation card. | Button |
3 |
conversation-actor-line.tsx |
ConversationActorLine |
username action · relative-time header line. |
— | 3 |
comment-composer-shared.tsx |
SharedCommentComposer |
Reusable comment composer (avatar + markdown editor + submit) for issues and PRs. | Avatar, Button |
2 |
campfire-mention-timeline-card.tsx |
CampfireMentionTimelineCard |
Timeline card surfacing a Campfire mention of an issue/PR. | — | 2 |
reply-content.tsx |
ConversationReplyContent, ConversationReplyAvatar |
Compact reply row body for nested replies. | Avatar |
1 |
apps/web/components/diffs
Counts here measure barrel imports (
@/components/diffs) and sibling-relative imports. Files marked "0 direct" are still in use — they're consumed via theindex.tsbarrel or sibling imports.
| File | Exports | Purpose | UI deps | External | Used |
|---|---|---|---|---|---|
pull-request-diff-review.tsx |
PullRequestDiffReview |
Top-level PR diff review surface composing header/sidebar/file-tree/code view. | — | @pierre/diffs |
via barrel |
code-view-wrapper.tsx |
CodeViewWrapper |
Wraps Pierre CodeView with custom annotation card + review-comment item handling. |
Button |
@pierre/diffs, @pierre/icons |
sibling |
code-view-header.tsx |
CodeViewHeader |
Header toolbar for diff view — split/unified, indicators, line-numbers, file-tree toggles. | Button, Menu, Switch, ToggleGroup |
@pierre/icons, @pierre/diffs |
sibling |
code-view-sidebar.tsx |
CodeViewSidebar |
Tabbed sidebar (Files / Comments) for the review surface. | Button, ToggleGroup |
@pierre/icons, @pierre/trees |
sibling |
code-view-file-tree.tsx |
CodeViewFileTree |
Pierre-themed file tree used in the PR review sidebar. | — | @pierre/diffs, @pierre/theme, @pierre/trees, next-themes |
sibling |
code-view-comments-list.tsx |
CodeViewCommentsList |
Sidebar list of saved review comments grouped by file and line. | Button |
@pierre/icons, @pierre/diffs |
sibling |
code-view-diff-stats.tsx |
DiffStatsPanel |
Collapsible diff-stats summary (files, additions, deletions). | Button |
@pierre/icons |
sibling |
diff-annotation-card.tsx |
DiffReviewAnnotation, diffAnnotationCardClass |
Inline pending-review-comment card on a diff line; markdown editor + suggestion insertion. | Button |
@pierre/diffs |
sibling |
review-grid.tsx |
ReviewGrid |
CSS grid template (header / tree / viewer) for desktop and mobile review layout. | — | — | sibling |
worker-pool-provider.tsx |
DiffWorkerPoolProvider |
Initializes the Pierre highlight worker pool with mobile-aware resource limits. | — | @pierre/diffs |
via barrel |
Barrel: apps/web/components/diffs/index.ts exports PullRequestDiffReview, DiffWorkerPoolProvider, plus types from ./types.
apps/web/components/legal
| File | Exports | Purpose | Used |
|---|---|---|---|
privacy-policy-content.tsx |
PrivacyPolicyContent |
Static prose body of the privacy policy page. | 1 |
apps/web/components/markdown
| File | Exports | Purpose | UI deps | External | Used |
|---|---|---|---|---|---|
markdown-editor.tsx |
MarkdownEditor, type MarkdownEditorHandle, type MarkdownEditorProps |
Tabbed write/preview markdown editor with toolbar (bold/italic/link/code/list). | Tabs, Textarea, Toolbar |
@tabler/icons-react |
7 |
markdown-content.tsx |
MarkdownContent, splitBodyForSuggestions |
Renders markdown HTML with special handling for ```suggestion fences → Pierre diff previews. |
— | @pierre/diffs |
4 |
apps/web/components/workbench-tabs
| File | Exports | Purpose | UI deps | External | Used |
|---|---|---|---|---|---|
workbench-tabs-provider.tsx |
WorkbenchTabsProvider, useWorkbenchTabs, type WorkbenchTab |
Reducer-backed context that persists open workbench tabs in localStorage. | — | — | 4 |
workbench-tab-bar.tsx |
WorkbenchTabBar, type WorkbenchTabBarProps |
Tab strip under the site toolbar showing visited dashboard/repo/PR/issue tabs. | — | @stackframe/stack, @tabler/icons-react, next/link, next/navigation |
2 |
workbench-route-sync.tsx |
WorkbenchRouteSync |
Headless: mirrors pathname into workbench tab strip on every nav. | — | next/navigation |
1 |
Barrel: apps/web/components/workbench-tabs/index.ts re-exports everything; only apps/web/app/layout.tsx imports the barrel.
4. apps/web route files
Every .tsx under apps/web/app/**. Grouped by route segment.
Root
| Path | Default | Purpose | UI deps | External |
|---|---|---|---|---|
app/layout.tsx |
RootLayout |
Root document — fonts, Stack provider, theme, toast, tooltip, workbench providers. | AnchoredToastProvider, ToastProvider, TooltipProvider |
@stackframe/stack, agentation, next/font/google |
app/page.tsx |
Page |
Home — public repo directory listing for the logged-in app surface. | — (composes AppSiteChrome) |
next/image, next/link, next/navigation |
Marketing / legal / waitlist
| Path | Default | Purpose | UI deps | External |
|---|---|---|---|---|
app/home/page.tsx |
LandingPage |
Marketing landing + waitlist gate at /home — hero hosts the join flow (signed out) or the viewer's queue status. |
buttonVariants, nucleo icons |
next/link, next/navigation, @paper-design/shaders-react (via landing-shaders) |
app/home/home-readme.tsx |
exports HomeReadmeHeader, HomeFallbackHero |
Marketing-home header + fallback hero when README content is missing. | Badge, buttonVariants |
@tabler/icons-react, next/link |
app/tos/page.tsx |
TermsOfServicePage |
Terms of Service prose, wrapped in LegalPageShell. |
— | — |
app/privacy/page.tsx |
PrivacyRedirectPage |
Legacy /privacy → /privacy-policy. |
— | — |
app/privacy-policy/page.tsx |
PrivacyPolicyPage |
Privacy policy page rendering PrivacyPolicyContent in LegalPageShell. |
— | — |
app/home/waitlist-join-flow.tsx |
exports WaitlistJoinFlow |
Email → OTP → password join flow embedded in the landing hero. | Button, Field, Form, Input |
next/link, next/navigation |
app/home/waitlist-status-card.tsx |
exports WaitlistStatusCard |
Queue position / rejection card for signed-in, un-accepted viewers. | — | — |
app/dashboard/page.tsx |
Page |
Authenticated dashboard with stat tiles, repos, issues, PR previews. | Badge, buttonVariants, Card (CardContent, CardDescription, CardHeader, CardTitle) |
next/link |
Auth / onboarding
| Path | Default | Purpose | UI deps | External |
|---|---|---|---|---|
app/sign-up/page.tsx |
SignUpPage |
Two-column sign-up shell hosting SignUpForm. |
— | next/image, next/navigation |
app/sign-up/sign-up-form.tsx |
exports SignUpForm |
Stack Auth email/password sign-up with live password-match validation. | Button, Input, Label |
@stackframe/stack, next/link |
app/onboarding/page.tsx |
OnboardingPage |
Server entry to onboarding flow; radial-gradient hero + OnboardingExperience. |
— | — |
app/onboarding/onboarding-experience.tsx |
exports OnboardingExperience |
Client orchestrator for onboarding — UserIdentityOrb, username form, exit-animation sequencing. |
— | next/navigation |
app/onboarding/onboarding-form.tsx |
exports OnboardingForm |
Username input with live availability status, dev-mock support, completion callback. | Button, Input, Label |
— |
app/handler/[...stack]/page.tsx |
Handler |
Catch-all → Stack Auth StackHandler for sign-in/OAuth/reset. |
— | @stackframe/stack |
Settings (account)
| Path | Default | Purpose | UI deps | External |
|---|---|---|---|---|
app/settings/page.tsx |
SettingsIndexPage |
/settings → /settings/account/profile. |
— | — |
app/settings/layout.tsx |
SettingsLayout |
Two-column shell (settings sidebar + content) respecting layout-mode preference. | composes SettingsNav, AppSiteChrome |
— |
app/settings/tokens/page.tsx |
LegacyGitTokensRedirectPage |
Legacy redirect → /settings/developer. |
— | — |
app/settings/developer/page.tsx |
DeveloperSettingsPage |
Developer settings: list/create/revoke git access tokens. | Card, Badge |
— |
app/settings/developer/tokens/page.tsx |
LegacyDeveloperTokensRedirectPage |
Legacy redirect → /settings/developer. |
— | — |
app/settings/developer/tokens/git-token-forms.tsx |
exports CreateGitTokenForm, RevokeGitTokenForm |
Mint a new token (one-time reveal + copy) and revoke existing. | Button, Input |
composes CopyToClipboardButton |
app/settings/account/page.tsx |
AccountIndexPage |
/settings/account → /settings/account/profile. |
— | — |
app/settings/account/layout.tsx |
AccountSettingsLayout (+ internal AccountSettingsContentSkeleton) |
"Account settings" header + suspended children for every /settings/account/* sub-page. |
Skeleton |
— |
app/settings/account/account-settings-sections.tsx |
exports ~17 sections (ProfileSection, EmailsAndAuthSection, NotificationsSection, ActiveSessionsSection, UserApiKeysSection, PaymentsSection, TeamSection, TeamUserProfileSection, TeamIdentitySection, TeamMembersSection, TeamLeaveSection, TeamApiKeysSection, CreateTeamSection, DisplayPreferencesSection, SettingsSection, usePaymentCandidates, AccountSettingsSkeleton, type PaymentCustomer) |
Catch-all of every account-settings section (profile, emails, notifications, sessions, API keys, payments, teams, display prefs, danger zone). | Badge, Button, Card, Input, Label, Radio, RadioGroup, Skeleton, Switch |
@tabler/icons-react, @stackframe/stack, qrcode, next/navigation |
app/settings/account/sessions/page.tsx |
AccountSessionsPage |
Renders ActiveSessionsSection. |
— | — |
app/settings/account/profile/page.tsx |
AccountProfilePage |
Renders ProfileSection. |
— | — |
app/settings/account/payments/page.tsx |
AccountPaymentsPage |
Renders PaymentsSection; redirects away if no payment candidates. |
— | @stackframe/stack, next/navigation |
app/settings/account/notifications/page.tsx |
AccountNotificationsPage |
Renders NotificationsSection. |
— | — |
app/settings/account/api-keys/page.tsx |
AccountApiKeysPage |
Server entry → AccountApiKeysClient. |
— | — |
app/settings/account/api-keys/api-keys-client.tsx |
exports AccountApiKeysClient |
Client wrapper for UserApiKeysSection if Stack project enables it. |
— | @stackframe/stack, next/navigation |
app/settings/account/emails/page.tsx |
AccountEmailsPage |
Renders EmailsAndAuthSection. |
— | — |
app/settings/account/settings/page.tsx |
AccountDangerZonePage |
Display preferences + danger-zone SettingsSection. |
— | — |
app/settings/account/teams/new/page.tsx |
AccountCreateTeamPage |
Wraps create-organization form in account-settings shell. | — | — |
app/settings/account/teams/new/create-organization-form.tsx |
exports CreateOrganizationForm |
Form to create a new Stack team / org, with live URL slug preview. | Button, Input |
@tabler/icons-react |
app/settings/account/teams/[teamId]/page.tsx |
AccountTeamPage |
Resolves legacy Stack team id → redirect to org settings if matching org exists. | — | next/navigation |
app/settings/account/teams/[teamId]/legacy-team-settings-client.tsx |
exports LegacyTeamSettingsClient |
Client: renders TeamSection for a Stack team id, redirects if not a member. |
— | @stackframe/stack, next/navigation |
Repositories (create)
| Path | Default | Purpose | UI deps | External |
|---|---|---|---|---|
app/repositories/new/page.tsx |
NewRepositoryPage |
Authenticated "new repository" page; collapsed scroll header + NewRepositoryExperience. |
— | — |
app/repositories/new/create-repository-form.tsx |
exports NewRepositoryExperience, RepositoryPreview |
Form to create a repo (owner namespace, name, visibility, README toggle) with live preview tile. | Alert, Badge, Button, Checkbox, Input, Radio, RadioGroup, Select |
@tabler/icons-react |
CI
| Path | Default | Purpose | UI deps | External |
|---|---|---|---|---|
app/ci/runs/[runId]/jobs/[jobId]/page.tsx |
Page |
CI workflow-job detail with steps, status badges, log viewer; cancel/rerun controls. | Breadcrumb (+ subcomponents) |
@tabler/icons-react, drizzle-orm, next/cache, next/link, next/navigation |
app/ci/runs/[runId]/jobs/[jobId]/workflow-job-log-viewer.tsx |
exports WorkflowJobLogViewer |
Client log viewer polling while job is non-terminal, triggers route refresh on done. | — | next/navigation |
Profile / organization (/[username])
| Path | Default | Purpose | UI deps | External |
|---|---|---|---|---|
app/[username]/page.tsx |
ProfilePage |
Public profile or org landing — bio, identity orb, visible repositories. | Badge, buttonVariants |
@tabler/icons-react, next/link, next/navigation |
app/[username]/settings/page.tsx |
OrganizationSettingsIndexPage |
/[username]/settings → /general. |
— | — |
app/[username]/settings/layout.tsx |
OrganizationSettingsLayout |
Page header + sidebar nav shell for org-settings tabs. | Skeleton |
composes OrganizationSettingsNav, AppSiteChrome |
app/[username]/settings/general/page.tsx |
OrganizationSettingsGeneralPage |
General org settings — identity, slug, Stack team display name. | Badge, Card |
— |
app/[username]/settings/danger/page.tsx |
OrganizationSettingsDangerPage |
Danger-zone tab — leave-organization control. | Card |
— |
app/[username]/settings/members/page.tsx |
OrganizationSettingsMembersPage |
Members tab — invite/remove via Stack Auth, cached membership list. | Badge, Card |
— |
app/[username]/settings/repositories/page.tsx |
OrganizationSettingsRepositoriesPage |
List of org-owned repositories visible to viewer, with visibility badges. | Badge, Card |
next/link |
app/[username]/settings/organization-stack-section.tsx |
exports 6 wrappers (OrganizationStackSection, …IdentitySection, …UserProfileSection, …MembersSection, …ApiKeysSection, …LeaveSection) |
Client wrappers that locate Stack team and render matching TeamSection parts. |
— | @stackframe/stack |
app/[username]/settings/_components/organization-settings-nav.tsx |
exports OrganizationSettingsNav |
Sidebar nav for org settings (General, Members, Repositories, Danger). | Sidebar |
@tabler/icons-react, next/link, next/navigation |
Repository (/[username]/[repository])
| Path | Default | Purpose | UI deps | External |
|---|---|---|---|---|
app/[username]/[repository]/page.tsx |
Page |
Repository overview — branch switcher, file tree, README/home doc, fork action, CI status. | Badge, deeper: buttonVariants, Card |
@tabler/icons-react, next/link, next/navigation |
app/[username]/[repository]/repository-shell.tsx |
exports RepositoryShell |
Outer chrome shell — applies layout preference, immersive mode for PR Files, renders scroll header. | — | — |
app/[username]/[repository]/repository-tabs.tsx |
exports RepositoryTabs |
Code / PRs / Issues / Discussions / Insights / Campfire / Settings tab strip. | — | @tabler/icons-react, next/link, next/navigation |
app/[username]/[repository]/repository-scroll-header.tsx |
exports RepositoryScrollHeader |
Sticky combined repo header (site chrome + tabs) that collapses on scroll. | composes AppSiteChrome, RepositoryTabs |
next/image, next/link |
app/[username]/[repository]/repository-file-tree.tsx |
exports RepositoryFileTree |
Pierre-trees–powered repository file tree with optional "last changed" column. | — | @pierre/trees, next/navigation |
app/[username]/[repository]/repository-branch-switcher.tsx |
exports RepositoryBranchSwitcher |
Select dropdown for switching active branch via URL query. | Select |
next/navigation |
app/[username]/[repository]/insights/page.tsx |
Page |
Repo insights — language breakdown, commit activity, CI summary tiles. | Badge, Separator |
@tabler/icons-react, next/link, next/navigation |
app/[username]/[repository]/discussions/page.tsx |
RepositoryDiscussionsPage |
Placeholder Discussions tab. | Card |
@tabler/icons-react, next/navigation |
app/[username]/[repository]/blob/layout.tsx |
RepositoryBlobLayout |
Two-column layout (file tree + child) for blob viewing routes. | Card |
next/navigation |
app/[username]/[repository]/blob/[...path]/page.tsx |
RepositoryFilePage |
Repository file viewer — Shiki syntax highlighting + branch switcher. | Card |
@tabler/icons-react, next/link, next/navigation, shiki (via highlight-code) |
app/[username]/[repository]/docs/page.tsx |
re-export of RepositoryDocsPage |
Repo docs landing (delegates). | — | — |
app/[username]/[repository]/docs/[...slug]/page.tsx |
RepositoryDocsSlugPage |
Repo docs for a specific slug (delegates). | — | — |
app/[username]/[repository]/docs/docs-page.tsx |
exports RepositoryDocsPage |
Shared docs surface — rendered markdown page inside repo shell with sidebar branch switcher. | Card |
@tabler/icons-react, next/link, next/navigation |
app/[username]/[repository]/campfire/page.tsx |
RepositoryCampfirePage |
Campfire chat — loads channels & history, renders CampfireRoom. |
Card |
@tabler/icons-react, next/navigation |
app/[username]/[repository]/campfire/campfire-room.tsx |
exports CampfireRoom + types CampfireChannelOption, CampfireParentPreview, CampfireMessagePayload |
Real-time Campfire chat — message list, composer, thread refs, copy-to-clipboard share links. | Avatar, Button, Card, Textarea, toastManager |
@tabler/icons-react, next/link |
app/[username]/[repository]/campfire/campfire-thread-ref-card.tsx |
exports CampfireThreadRefCard |
Inline preview card for an issue/PR reference embedded in a Campfire message. | Avatar, Skeleton |
@tabler/icons-react, next/link |
app/[username]/[repository]/fork/fork-repository-form.tsx |
exports ForkRepositoryForm |
Dialog + form to fork the current repo into viewer's namespace. | Button, Dialog, Input |
@tabler/icons-react |
Repository settings
| Path | Default | Purpose | UI deps | External |
|---|---|---|---|---|
app/[username]/[repository]/settings/page.tsx |
RepositorySettingsIndexPage |
Redirect → /general. |
— | — |
app/[username]/[repository]/settings/layout.tsx |
RepositorySettingsLayout |
Repo settings shell — RepositoryShell + RepositorySettingsNav + content. |
Skeleton |
— |
app/[username]/[repository]/settings/general/page.tsx |
RepositorySettingsGeneralPage |
Name, description, default branch, campfire toggle (perm-gated) or read-only access card. | delegates to forms | — |
app/[username]/[repository]/settings/danger/page.tsx |
RepositorySettingsDangerPage |
Danger-zone — delete repository form when permitted. | delegates | next/navigation |
app/[username]/[repository]/settings/access/page.tsx |
RepositorySettingsAccessPage |
Access — collaborator grants + pending invitations. | delegates to RepositoryAccessForm |
next/navigation |
app/[username]/[repository]/settings/runners/page.tsx |
RepositorySettingsRunnersPage |
CI runners — mint registration tokens for self-hosted runners. | delegates | next/navigation |
app/[username]/[repository]/settings/repository-settings-forms.tsx |
exports RepositoryDetailsForm, YourAccessCard, RepositoryAccessForm, RunnerRegistrationForm, DeleteRepositoryForm, types |
All repo settings forms (details, access, runner token, deletion confirm). | Alert, Badge, Button, Card, Checkbox, Input, Select |
— |
app/[username]/[repository]/settings/campfire-channels-form.tsx |
exports CampfireChannelsForm |
Mini CRUD form for Campfire channel list. | Button, Input |
— |
app/[username]/[repository]/settings/_components/repository-settings-nav.tsx |
exports RepositorySettingsNav, type RepositorySettingsNavAccess |
Capability-filtered sidebar nav for repo settings. | Sidebar |
@tabler/icons-react, next/link, next/navigation |
Pull requests
| Path | Default | Purpose | UI deps | External |
|---|---|---|---|---|
app/[username]/[repository]/pulls/page.tsx |
Page |
PR list with search/query bar, status filters, per-row metadata. | Badge, buttonVariants, Skeleton |
@tabler/icons-react, next/link, next/navigation |
app/[username]/[repository]/pulls/new/page.tsx |
NewPullRequestPage |
New-PR server page — resolves branches and renders create form. | Card |
next/navigation |
app/[username]/[repository]/pulls/new/create-pull-request-form.tsx |
exports CreatePullRequestForm |
Open new PR — source repo + branches selects, title, markdown description. | Button, Input, Select |
composes MarkdownEditor |
app/[username]/[repository]/pulls/[number]/page.tsx |
PullRequestPage |
PR detail surface — conversation, files review, merge box, status forms (wrapped in quote-reply provider). | composes many forms | @tabler/icons-react, next/link, next/navigation |
app/[username]/[repository]/pulls/[number]/pull-request-files-review.tsx |
exports PullRequestFilesReview |
PR "Files" tab — composes PullRequestDiffReview + review submission form. |
Button, Select |
@tabler/icons-react |
app/[username]/[repository]/pulls/[number]/pull-request-files-chrome.tsx |
exports PullRequestFilesChrome |
Slim "review stage" header for the Files tab. | Badge |
@tabler/icons-react, next/image, next/link |
app/[username]/[repository]/pulls/[number]/pull-request-forms.tsx |
exports PullRequestTitleForm, PullRequestDescriptionForm, PullRequestCommentForm, PullRequestReviewForm, PullRequestStateForms |
Inline edit / status / comment / review submission forms. | Badge, Button, Input, Select |
composes MarkdownEditor, MarkdownContent |
app/[username]/[repository]/pulls/[number]/pull-request-conversation.tsx |
exports PullRequestConversation, type PullRequestConversationProps |
PR conversation timeline — comments, review threads, campfire mentions, commit refs, quote-reply. | delegates to conversation primitives | @tabler/icons-react, next/link, @workspace/code-storage types |
app/[username]/[repository]/pulls/[number]/pull-request-comment-body.tsx |
exports PullRequestCommentBody |
Wraps MarkdownContent with PR-comment defaults. |
— | — |
app/[username]/[repository]/pulls/[number]/review-reply-composer.tsx |
exports ReviewReplyComposer |
Compact markdown composer for replying inside a review thread. | Button |
composes MarkdownEditor |
app/[username]/[repository]/pulls/[number]/pull-request-merge-box.tsx |
exports PullRequestMergeBox, type PullRequestMergeBoxProps |
Merge readiness — approvals/checks summary, ahead/behind, merge button. | Button |
@tabler/icons-react |
app/[username]/[repository]/pulls/[number]/pull-request-comment-composer.tsx |
exports PullRequestCommentComposer |
Thin wrapper around SharedCommentComposer wired to PR comment server action. |
— | — |
Issues
| Path | Default | Purpose | UI deps | External |
|---|---|---|---|---|
app/[username]/[repository]/issues/page.tsx |
RepositoryIssuesPage |
Issue list with search/query bar, open/closed counts, per-row metadata. | buttonVariants, Skeleton |
@tabler/icons-react, next/link, next/navigation |
app/[username]/[repository]/issues/new/page.tsx |
NewIssuePage |
New-issue page — renders NewIssueForm inside repo shell. |
buttonVariants, Card |
next/link, next/navigation |
app/[username]/[repository]/issues/[number]/page.tsx |
IssuePage |
Issue detail — status forms, link-PR form, conversation timeline (wrapped in quote-reply provider). | Badge, Button |
next/link, next/navigation |
app/[username]/[repository]/issues/[number]/issue-conversation.tsx |
exports IssueConversation |
Issue conversation timeline — comments, campfire mentions, signed-out prompt, composer. | Badge |
— |
app/[username]/[repository]/issues/issue-forms.tsx |
exports NewIssueForm, IssueStatusForm, IssueCommentForm, IssueLinkPullRequestForm |
Create / open-close / comment / link-related-PR forms. | Button, Input |
composes MarkdownEditor |
app/[username]/[repository]/issues/[number]/issue-comment-composer.tsx |
exports IssueCommentComposer |
Thin wrapper around SharedCommentComposer wired to issue comment action. |
— | — |
app/[username]/[repository]/issues/[number]/issue-comment-body.tsx |
exports IssueCommentBody |
Wraps PullRequestCommentBody with an "Issue comment" file label for suggestion fences. |
— | — |
5. apps/web UI hooks
| File | Exports | Purpose |
|---|---|---|
apps/web/hooks/use-dev-mock-onboarding.ts |
useDevMockOnboarding |
Subscribes to dev-tools sync event; returns whether onboarding mock mode is enabled in localStorage. |
apps/web/lib/**was checked. No file exports React components or JSX-returning UI utilities. The folder contains data utilities, server loaders, and pure helpers (relative-time.tsreturns class-name strings;markdown.tsandhighlight-code.tsreturn HTML/token data;pull-request-suggestion-preview.tsreturns plain data; etc.). Excluded per scope.
6. packages/marketing
| File | Exports | Purpose | UI deps | External |
|---|---|---|---|---|
marketing-top-nav.tsx |
MarketingTopNav, type MarketingTopNavProps |
Top nav for marketing pages — brand mark, optional Blog crumb, Explore/Sign-in links, primary Sign-up CTA. Highlights based on `home | blog | post`. |
marketing-footer.tsx |
MarketingFooter |
Minimal footer linking to ToS / Privacy on the main app. | — | next/link |
marketing-shell.tsx |
MarketingShell |
Page layout shell (full-bleed black, header/navbar/footer slots, optional animated HomeLogo shader for hero landings, max-width content wrapper). |
— | composes HomeLogo |
home-logo.tsx |
HomeLogo |
Client wrapper toggling between ASCII and Lines shaders on click (full-screen overlay button); used as animated hero background by MarketingShell. |
— | composes AsciiShader, LinesShader |
logo-shaders/logo-shader-utils.ts |
interface SVGPoint, getLogoTransform, fillSVGPath |
Pure helpers — viewport-fitting SVG logo transform + rasterize SVG path into sampled points. | — | — |
logo-shaders/lines-shader.tsx |
default LinesShader, interface JoyConfig |
Full-screen canvas shader drawing animated horizontal noise lines warped by the logo SVG density, with mouse/touch ripple trails. | — | raw Canvas 2D |
logo-shaders/ascii-shader.tsx |
default AsciiShader |
Full-screen ASCII-art shader rasterizing the logo into a character grid that pulses, flickers, and spawns "torn" flying chars on fast mouse moves. | — | raw Canvas 2D |
Notes:
- No
gsap,three,shiki,@stackframe/stack, or@tabler/icons-reactin marketing. Shaders use raw Canvas 2D, not three.js. packages/marketingdeclares zero third-party UI deps; only@workspace/ui.
7. apps/community
Components
| File | Exports | Purpose | UI deps | External |
|---|---|---|---|---|
table-of-contents.tsx |
TableOfContents |
"On this page" rail rendering TOC anchors with per-level indentation. | cn |
— |
post-hero.tsx |
PostHero |
Centered post header — category badge, date · reading-time, title, description. | cn |
composes PostBadge |
post-header.tsx |
PostHeader |
Renders an optional per-post hero "skeleton" React component looked up by name from @/skeletons. |
— | — |
changelog-list.tsx |
ChangelogList |
Blog index — date-gutter / title grid with category badge, reading time, hover styling. | cn |
next/link, composes PostBadge |
blog-content.tsx |
BlogContent |
Centered reading column (max-w-3xl, or wide for max-w-6xl). |
cn |
— |
post-reading-layout.tsx |
PostReadingLayout |
Two-column reading layout — article + sticky TOC sidebar on xl, bottom TOC fallback below. |
— | composes PostBody, TableOfContents |
post-content.tsx |
PostContent, PostBody |
Renders pre-rendered post HTML in heavily-styled .post-content prose container (dangerouslySetInnerHTML). |
— | — |
post-badge.tsx |
PostBadge |
Small rounded white-on-black uppercase category pill. | Badge, cn |
— |
blog-breadcrumb.tsx |
BlogBreadcrumb |
Monospace breadcrumb showing blog and optionally truncated post title. |
Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, cn |
next/link |
blog-top-nav.tsx |
BlogTopNav |
Community blog top nav — brand, BlogBreadcrumb, Explore / Sign-in / Sign-up links to main app. |
buttonVariants, cn |
next/image, next/link, composes BlogBreadcrumb |
blog-shell.tsx |
BlogShell |
Page shell for blog routes — MarketingShell + BlogTopNav + SiteFooter, propagates postTitle. |
— | @workspace/marketing/marketing-shell |
site-footer.tsx |
SiteFooter |
Community-site footer linking ToS / Privacy on the main app via getMainAppUrl. |
— | next/link |
back-to-blog.tsx |
BackToBlog |
Small uppercase "← Back to blog" link above the post hero. | — | next/link |
Routes
| Path | Default | Purpose | Composes |
|---|---|---|---|
app/layout.tsx |
RootLayout (+ metadata) |
Root layout — Inter + Geist Mono Google fonts, dark class with sans/mono vars, black body, site metadata. |
cn; imports @workspace/ui/globals.css |
app/page.tsx |
CommunityHomePage |
Blog index / — fetches all posts, renders ChangelogList inside BlogShell + BlogContent. |
BlogShell, BlogContent, ChangelogList |
app/posts/[slug]/page.tsx |
PostPage (+ generateStaticParams, generateMetadata) |
Dynamic post route — BackToBlog, PostHero, optional PostHeader skeleton, PostReadingLayout. |
BackToBlog, BlogShell, BlogContent, PostHeader, PostHero, PostReadingLayout |
Notes:
BlogTopNavandSiteFooterare near-1:1 community variants ofMarketingTopNav/MarketingFooterbut usegetMainAppUrl()instead of a prop.- Only one community file consumes
@workspace/marketing(blog-shell.tsximportsMarketingShell).
8. External UI dependencies
Audit date: 2026-05-31. Counts are grep -rE "from ['\"]<pkg>" over apps/ + packages/ minus node_modules and .next.
The CLI/runner/gateway/worker apps (
apps/cli,apps/runner,apps/managed-runner,apps/git-worker,apps/git-gateway,apps/campfire-gateway) and the headless packages (packages/code-storage,packages/git-indexing,packages/workflows,packages/ci-runner-executor,packages/eslint-config,packages/typescript-config) declare zero UI deps — not represented below.
Foundation
| Dep | Version | Declared in | Imports | Notes |
|---|---|---|---|---|
tailwindcss |
^4.1.18 | packages/ui (dev) |
1 (via @import in globals.css) |
Tailwind v4. CSS-only consumption. |
@tailwindcss/postcss |
^4.1.18 | packages/ui, apps/web, apps/community (dev) |
1 (postcss config) | Compiles Tailwind v4 directives. Each Next app must declare it for PostCSS resolution. |
class-variance-authority |
^0.7.1 | packages/ui |
10 (toggle, toggle-group, sidebar, select, button-variants, etc.) | Typed variant APIs for Tailwind class strings. ~2KB gz. |
clsx |
^2.1.1 | packages/ui |
1 direct (utils.ts) / 108 indirect via cn() |
Conditional class composition. |
tailwind-merge |
^3.5.0 | packages/ui |
1 direct / 108 indirect via cn() |
De-duplicates conflicting Tailwind classes inside cn(). |
tw-animate-css |
^1.4.0 | packages/ui |
1 (@import) |
Tailwind v4 animation utilities (fade/slide/zoom). CSS-only. |
prettier-plugin-tailwindcss |
^0.7.2 | root (dev) | 0 (tooling) | Sorts Tailwind classes on prettier --write. |
Base UI library
| Dep | Version | Declared in | Imports | Notes |
|---|---|---|---|---|
@base-ui/react |
^1.4.1 | packages/ui |
66 statements / 44 files | Foundation for ~44 of ~54 design system components. Top: drawer (6), sheet (3), select (3), dialog (3). |
Icons
| Dep | Version | Declared in | Imports | Notes |
|---|---|---|---|---|
@tabler/icons-react |
^3.41.1 | packages/ui, apps/web |
51 / 51 files | Primary icon set. 17 of 51 importers live inside packages/ui/src/components/*. Tree-shaken per-icon. |
@pierre/icons |
^0.5.0 | apps/web |
5 / 5 files | Pierre's icon set shipped with @pierre/diffs. All under apps/web/components/diffs/. |
Auth UI
| Dep | Version | Declared in | Imports | Notes |
|---|---|---|---|---|
@stackframe/stack |
^2.8.85 | apps/web |
18 / 17 files | Drop-in auth (sign-in/up, user button, team/account screens). next.config.mjs adds @stackframe/stack* to transpilePackages. One file (stack-profile-image-editor.tsx) reaches into node_modules/@stackframe/stack/dist/... directly — fragile. |
Theming
| Dep | Version | Declared in | Imports | Notes |
|---|---|---|---|---|
next-themes |
^0.4.6 | apps/web |
2 / 2 files | ThemeProvider (app-wide) + Pierre file tree's light/dark selection. |
Code & diff visualization
| Dep | Version | Declared in | Imports | Notes |
|---|---|---|---|---|
@pierre/diffs |
^1.2.1 | apps/web |
22 / 15 files | High-performance diff renderer (CodeView, parseDiffFromFile, processFile, worker pool). Worker mounted via new Worker(new URL("@pierre/diffs/worker/worker.js", import.meta.url)) in worker-pool-provider.tsx. |
@pierre/trees |
1.0.0-beta.3 | apps/web |
13 / 9 files | File tree component + helpers. Used in both diff sidebar AND repo file browser (repository-file-tree.tsx). Beta version pin — watch for breaking changes. |
@pierre/theme |
1.0.3 (exact) | apps/web |
2 / 1 file | Theme tokens for Pierre components. Pinned to exact version. |
shiki |
^4.0.2 | apps/web |
1 / 1 file (apps/web/lib/highlight-code.ts) |
Syntax highlighter used for blob view + markdown code blocks. Verify languages are lazy-loaded. |
Markdown rendering
The markdown stack is duplicated across
apps/web/lib/markdown.ts,apps/web/lib/repository-docs-markdown.ts, andapps/community/lib/markdown.ts. Community addsrehype-slugandhast-util-sanitize.
| Dep | Version | Declared in | Imports | Notes |
|---|---|---|---|---|
unified |
^11.0.5 | apps/web, apps/community |
3 / 3 files | Pipeline runner. |
remark-parse |
^11.0.0 | apps/web, apps/community |
3 / 3 files | Markdown → mdast parser. |
remark-gfm |
^4.0.1 | apps/web, apps/community |
3 / 3 files | GFM extensions (tables, task lists, strikethrough, autolinks). |
remark-rehype |
^11.1.2 | apps/web, apps/community |
3 / 3 files | mdast → hast bridge. |
rehype-sanitize |
^6.0.0 | apps/web, apps/community |
3 / 3 files | Whitelist HTML sanitizer for user markdown. |
rehype-stringify |
^10.0.1 | apps/web, apps/community |
3 / 3 files | hast → HTML string serialization. |
rehype-slug |
^6.0.0 | apps/community |
1 / 1 file | Adds id attributes to headings for anchors. |
hast-util-sanitize |
^5.0.2 | apps/community |
1 / 1 file | Sanitization schema extending rehype-sanitize defaults. |
github-slugger |
^2.0.0 | apps/community |
1 / 1 file | GitHub-style URL slugs from heading text. |
gray-matter |
^4.0.3 | apps/community |
1 / 1 file | YAML front-matter parser. Pulls js-yaml transitively. |
Date / time
| Dep | Version | Declared in | Imports | Notes |
|---|---|---|---|---|
react-day-picker |
^9.14.0 | packages/ui |
1 / 1 file (packages/ui/src/components/calendar.tsx) |
Powers <Calendar />. Calendar has 0 app-level imports — verify it's actually rendered. |
Animation & 3D
| Dep | Version | Declared in | Imports | Notes |
|---|---|---|---|---|
gsap |
^3.15.0 | apps/web |
1 / 1 file | Single feature: UserIdentityOrb animation. ~70 KB gz. Consider lazy-loading the orb. |
three |
^0.184.0 | apps/web (+ @types/three ^0.184.0 dev) |
1 / 1 file | WebGL renderer for UserIdentityOrb. ~150 KB gz. Imported as import * as THREE — tree-shaking is effectively disabled. Lazy-load this component. |
@react-three/fiber |
^9.6.1 | apps/web |
0 | UNUSED — REMOVE. |
@react-three/drei |
^10.7.7 | apps/web |
0 | UNUSED — REMOVE. |
Misc visual
| Dep | Version | Declared in | Imports | Notes |
|---|---|---|---|---|
qrcode |
^1.5.4 (+ @types/qrcode ^1.5.6 dev) |
apps/web |
1 / 1 file | Used in account settings (likely 2FA / TOTP enrollment). |
agentation |
^3.0.2 | apps/web (dev) |
1 / 1 file (app/layout.tsx) |
Dev-only annotation overlay. Mount is gated by process.env.NODE_ENV === "development". Remove before any commit/PR per project policy — added during this session, present in working tree. |
9. Removal candidates
Confirmed unused (0 source imports)
| Layer | Item | Action |
|---|---|---|
| External | @react-three/fiber ^9.6.1 |
Remove from apps/web/package.json + lockfile. |
| External | @react-three/drei ^10.7.7 |
Remove from apps/web/package.json + lockfile. |
| App-local | apps/web/components/dev-floating-panel.tsx |
Upstream layout no longer mounts it. Delete file + its supporting hook apps/web/hooks/use-dev-mock-onboarding.ts if no other consumer remains. |
packages/ui — 0 external imports, 0 internal cross-references
These 22 components are present in the design system but are not consumed anywhere. Some are likely "kept because shadcn includes them"; decide per-component whether to keep on standby or delete.
accordion.tsxalert-dialog.tsxcalendar.tsx(also dropsreact-day-pickerdependency)checkbox-group.tsxcollapsible.tsxcombobox.tsxcommand.tsxdrawer.tsx(largest file in the library, ~628 lines)empty.tsxfield.tsxfieldset.tsxform.tsxframe.tsxgroup.tsxkbd.tsxmeter.tsxnumber-field.tsxotp-field.tsxpagination.tsxpreview-card.tsxprogress.tsxslider.tsxtable.tsx
packages/ui — 0 external imports, but used internally
| Component | Used by |
|---|---|
autocomplete.tsx |
command.tsx (which is itself unused — both can go together if Command is dropped) |
scroll-area.tsx |
6 internal files (sidebar etc.) — keep |
sheet.tsx |
sidebar.tsx (mobile fallback) — keep |
spinner.tsx |
button.tsx — keep |
Soft flags
| Item | Concern |
|---|---|
three + gsap |
One-component feature (UserIdentityOrb). Combined ~220 KB gz. Ensure the component is dynamically imported / route-split, and replace import * as THREE with named imports for tree-shaking. |
react-day-picker |
<Calendar /> declared but has 0 app-level consumers; if Calendar is dropped the dep can be too. |
shiki |
Single-file consumer. Verify lazy-loading of languages/themes. |
apps/web/hooks/use-mobile.ts vs apps/web/hooks/use-media-query.ts |
Two useIsMobile exports with different breakpoints (768px vs md=800px) and different SSR behavior. Pick one. |
apps/web/components/stack-profile-image-editor.tsx |
Reaches into node_modules/@stackframe/stack/dist/... — fragile across upgrades. Replace with public export when available. |
apps/web/components/diffs/index.ts barrel |
Re-exports only the top-level surface; per-file usage counts via @/components/diffs/<x> will read as 0 for internal files. They're still in use via sibling-relative imports. |
agentation mount in app/layout.tsx |
Dev-only render is correctly gated, but the import still ships in the client bundle unless tree-shaken. Confirm Next.js strips the dynamic side. Either way, remove before committing per project policy. |