This is a pnpm monorepo containing the Venus Design System component library and a demo application.
The Venus component library (@contentstack/venuscn) contains pre-built components that match the Contentstack design system. Using these components helps maintain consistency across the codebase.
// Import Venus components from the package
import { Button, Input, Field, FieldLabel, Tag, Table } from "@contentstack/venuscn"
// These components are built to match the design system
// and include proper styling, accessibility, and behaviorBefore building UI, check what's already available:
- Venus components: See
packages/venuscn/README.mdfor the full component list - shadcn/ui components: Check
apps/demo/src/components/ui/for app-specific components - Grep the codebase for similar patterns and examples
This helps avoid duplicating work and maintains consistency.
Always quote paths containing parentheses:
git add 'apps/demo/src/app/(app)/page.tsx'venus_external/
├── packages/
│ ├── venuscn/ # Venus component library (@contentstack/venuscn)
│ │ ├── README.md # ⭐ COMPONENT DOCUMENTATION
│ │ └── src/components/ # All Venus components
│ │
│ └── venusmui/ # Future MUI version (placeholder)
│
├── apps/
│ └── demo/ # Demo Contentstack application
│ ├── CLAUDE.md # Demo-specific instructions
│ └── src/
│ ├── app/(app)/ # Main app pages
│ ├── app/(galleries)/ # Component galleries
│ └── components/ui/ # shadcn/ui (app-specific only)
│
├── pnpm-workspace.yaml # Workspace configuration
└── tsconfig.base.json # Shared TypeScript config
Run from the root directory:
pnpm dev # Start demo app with hot reload
pnpm build # Build venuscn package + demo appRun from packages/venuscn/:
pnpm build # Build the component library
pnpm dev # Watch mode for component developmentRun from apps/demo/:
pnpm dev # Start demo dev server
pnpm build # Build demo for production
pnpm lint # Run ESLintThe @contentstack/venuscn package contains 66 components matching app.contentstack.com.
Form Controls: Button, Input, Textarea, Checkbox, Radio, Toggle, Switch, Dropdown, Select, Slider, DatePicker, Label, Form
Form Architecture: Field, FieldLabel, HelpText, ValidationMessage
Data Display: Table (+ Header/Body/Row/Cell), TablePagination, DataTable, Chart, Stat, EmptyState, List, Accordion, SimpleAccordion, Collapsible, CodeBlock, Progress, Skeleton, Badge, Search, SearchV3
Navigation/Layout: Tabs, SimpleTabs, PageHeader, PageSearchHeader, PageFormHeader, FormSidebar, Sidebar, Breadcrumb, Pagination, Divider, Separator, Stack, Typography, Icon, Card, AppCard, Avatar, AvatarGroup
UI Elements: Tag, Pill, Pills, CategoryPill, StatusPill, Callout, Toast, Alert, Tooltip, Dialog, Sheet, Popover, DropdownMenu, ContextMenu, Command
Advanced: TargetingRuleBuilder, TargetingCategoryCard, RuleRow, RuleGroup
| Element | Font Size | Weight | Height |
|---|---|---|---|
| Button (regular) | 16px | 600 | 40px |
| Input | 16px | 400 | 40px |
| Field Label | 14px | 600 | - |
| Checkbox/Radio Label | 16px | 400 | - |
Border radius: 4px (not 6px)
For complete API documentation, see: packages/venuscn/README.md
Import Venus styles in your CSS:
@import "@contentstack/venuscn/styles";Key tokens available:
--color-primary(#6C5CE7)--color-border(#E3E8EF)--color-title(#111827)--color-heading(#475161)--color-body(#6B7280)
When adding pages or features to apps/demo/:
// Venus components (primary choice)
import { Button, Input, Field, FieldLabel, PageHeader } from "@contentstack/venuscn"
// shadcn/ui components (for app-specific UI not in Venus)
import { Card, Dialog, Sheet } from "@/components/ui/card"
// Icons
import { Plus, Settings } from "lucide-react"// apps/demo/src/app/(app)/my-page/page.tsx
import { PageHeader, Button } from "@contentstack/venuscn"
import { Plus } from "lucide-react"
export default function MyPage() {
return (
<div className="p-6">
<PageHeader
title="My Page"
actions={[
{ label: "Add New", icon: Plus, variant: "primary", onClick: () => {} }
]}
/>
{/* Page content */}
</div>
)
}import { Field, FieldLabel, Input, Button, HelpText, ValidationMessage } from "@contentstack/venuscn"
<form>
<Field>
<FieldLabel htmlFor="name" required>Name</FieldLabel>
<Input id="name" placeholder="Enter name" />
<HelpText>This will be displayed publicly</HelpText>
</Field>
<Button variant="primary">Submit</Button>
</form>When rebuilding vacuum captures, the workflow will:
- Survey — Analyze zones, detect existing layout, ask what to skip/rebuild
- Integrate — Wire nav items to routes, set active states with
usePathname() - Rebuild — Generate only the content zones, using Venus components where possible
- Verify — Check structure and styles match capture
This app's layout context:
- Header →
TopNavat@/components/top-nav(usually skip header zone) - Main wrapper →
layout-client.tsx(pages render inside{children}) - Components →
@contentstack/venuscnfor Button, Input, Table, etc.
Typical rebuild target: Main zone only → apps/demo/src/app/(app)/{feature}/page.tsx
| What | Where |
|---|---|
| Component documentation | packages/venuscn/README.md |
| Demo app instructions | apps/demo/CLAUDE.md |
| Component source code | packages/venuscn/src/components/ |
| Design tokens | packages/venuscn/src/styles/tokens.css |
| Component galleries | apps/demo/src/app/(galleries)/ |
| shadcn/ui components | apps/demo/src/components/ui/ |
When building UI in this monorepo:
[ ] Check packages/venuscn/README.md for existing Venus components
[ ] Search the codebase for similar patterns
[ ] Import from @contentstack/venuscn for consistency
[ ] Reference the demo app for layout patterns
[ ] Use design tokens when possible (see docs/guides/design-system.md)
Common patterns from the demo:
- Border radius: 4px (use
roundedclass) - Button/Input font: 16px
- Label font: 14px weight 600