Architecture Overview
Integral's turborepo architecture
Turborepo Structure
This design system is built as Turborepo packages, enabling shared code and consistent tooling across all packages and applications.
Directory Structure
.
├── apps/
│ ├── curriculum-app/ # Main application (port 3000)
│ ├── design-system-docs/ # Design system documentation (port 4000)
│ ├── platform-content-app/ # Payload application (port 3001)
│ └── a11y/ # Accessibility report generator cli
├── packages/
│ ├── @im/integral. # Unified design system
│ │ ├── components/
│ │ │ ├── primitives/ # Pure TSX components (i.e. from shadcn/radix)
│ │ │ └── styled/ # CSS/SCSS themed components
│ │ └── styles/
│ │ ├── components/ # Component-level SCSS styles
│ │ │ ├── primitives/ # Styles for primitive components (i.e. from shadcn/radix)
│ │ │ └── styled/ # CSS/SCSS for Styled components
│ │ ├── foundations/ # Foundational SCSS styles
│ │ ├── legacy/ # Legacy SCSS styles
│ │ ├── mixins/ # Mixins, for use within the packages, possibly app level in the future
│ │ ├── tailwind/ # Brand Tailwind Config
│ │ └── whimsical/ # Animation library
│ ├── @im/integral-tokens # Design tokens
│ └── @im/typescript-config # Shared TS configs
└── turbo.json # Turborepo configuration
└── biome.json # Code formatting & lintingKey Design Decisions
Below are the major technical choices that shape the design system’s architecture.
1. Hybrid Styling Architecture
Pure CSS vs SCSS
- Foundations Styles: SCSS for design system styles
- Legacy Styles: Legacy SCSS for application-wide styles
- Mixins: SCSS Mixin utilites for within the design system package
- Styled Component Styles: SCSS with variables, mixins, and nesting (Overrides foundations, legacy, and primitives styles)
- Whimsical Styles: Optional SCSS animations
- Tailwind Config: Applies design token overrides to tailwind config
- Tailwind Utilities: App level tailwind overrides all CSS cascade layers
2. CSS Cascade Layers Architecture
We use CSS Cascade Layers to manage style precedence:
@layer tokens, resets, base, theme, legacy, integral, app, utilities;
@layer integral {
@layer foundations, whimsical, utilities.primitives, utilities.styled;
}Layer Structure:
- tokens: Design tokens (optional layer)
- resets: Global CSS Resets
- base: Fumadocs, Tailwind preflight (optional layer)
- theme: Design tokens, Tailwind theme, Design System theme
- legacy: Global styles for accessim.org
- integral: Design system styles with sub-layers:
integral.foundations: System-wide stylesintegral.whimsical: Animationsintegral.utilities.primitives: Primitive componentsintegral.utilities.styled: Styled components
- app: app level styles (optional layer)
- utilities: Tailwind utility classes
Why Cascade Layers?
- Predictable specificity without !important
- Mix SCSS, CSS, and Tailwind seamlessly
- Clear override hierarchy
- Performance optimizations (tree shaking, lazy loading)
3. Build Configuration
Hybrid Build Process
- Tokens: Compiled to CSS, SCSS, JS via
style-dictionaryCLI - SCSS: Compiled to CSS via
sassCLI, imported to layers at app level - CSS: Exported directly, JIT compilation at app level
- Components: Export raw
.tsxfiles, JIT compilation at app level
Design System Build Pipeline
Design Token Exports
"exports": {
"./css/tokens.css": "./dist/css/tokens.css",
"./scss/_tokens.scss": "./dist/scss/_tokens.scss"
}Design System Exports
"exports": {
"./styles/resets.css": "./src/styles/legacy/b-baseline/b-resets.css",
"./styles/themes.css": "./src/styles/legacy/b-baseline/b-themes.css",
"./styles/legacy.css": "./dist/styles/legacy/styles.css",
"./styles/foundations.css": "./dist/styles/foundations/styles.css",
"./styles/components/primitives.css": "./src/styles/components/primitives/styles.css",
"./styles/components/styled.css": "./dist/styles/components/styled/styles.css",
"./styles/tailwind.css": "./dist/styles/tailwind/styles.css",
"./styles/whimsical.css": "./dist/styles/whimsical/styles.css",
"./components/primitives": "./src/components/primitives/index.ts",
"./components/styled": "./src/components/styled/index.ts"
},Style Dictionary for Tokens
- JSON source → CSS variables + SCSS variables + JS variables
- Automated token generation
- Framework-agnostic output
4. Import Strategies
Component Imports
// Primitives (pure primitive components)
import { Button } from '@im/integral/components/primitives';
// Styled components (Design-aligned components)
import { SampleButton } from '@im/integral/components/styled';Style Imports (in global.css)
/* Import with cascade layers */
@layer tokens, base, theme, legacy, integral, app, utilities;
@import 'tailwindcss/preflight.css' layer(base);
@import 'fumadocs-ui/css/neutral.css';
@import 'fumadocs-ui/css/preset.css';
@import '@im/integral/styles/resets.css' layer(base);
@import '@im/integral/styles/themes.css' layer(theme);
@import 'tailwindcss/theme.css' layer(theme);
@import '@im/integral/styles/tailwind.css' layer(theme);
@import '@im/integral/styles/legacy.css' layer(legacy);
@import '@im/integral/styles/foundations.css' layer(integral.foundations);
@import '@im/integral/styles/whimsical.css' layer(integral.whimsical);
@import '@im/integral/styles/components/primitives.css'
layer(integral.utilities.primitives);
@import '@im/integral/styles/components/styled.css'
layer(integral.utilities.styled);
@import 'tailwindcss/utilities.css' layer(utilities);These @import paths work because the packages use exports
fields in package.json, and
the monorepo is configured with TypeScript path aliases and Next.js's built-in
support for CSS and module resolution.
5. Styling Approach
Tailwind CSS v4
- PostCSS-based configuration
- Design tokens integration
- Component primitive utilities are manually converted via
@apply(required for use in css cascade layer)
SCSS Integration
- Styled components use SCSS features:
- Variables for theming
- Mixins for reusable patterns
- Nesting for component structure
- Functions for calculations
Primitive Components
- Pure CSS only (no SCSS)
- Tailwind utilities via
@apply - Minimal specificity for brand and app level overrides
Development Workflow
Design System Development
For Primitive Components (i.e. from Shadcn)
- Create component in
packages/integral/src/components/primitives/ - Add any included styles in
packages/integral/src/styles/components/primitives/[component].css(i.e. styles that may be from radix or shadcn) - Convert any Tailwind utilities with
@apply - Export from primitives index
For Styled Components (SCSS)
- Create component in
packages/integral/src/components/styled/ - Add styles in
packages/integral/src/styles/components/styled/[component].scss - Use SCSS features for theming
- Export from styled index
Build Process
# Build all apps and packages
turbo build
# or for curriculum-app
turbo build:local# Start all apps and packages in dev mode
turbo devDev Mode
turbo dev will start all apps and packages with watchers or hot module
reloading. Changes to any source file in any package or app should immediately
reflect in the running apps.
# Alias to launch docs app
turbo docs# Build design system
turbo @im/integral#build
# or
turbo build --filter=@im/integral# Build design tokens
turbo @im/integral-tokens#build
# or
turbo build --filter=@im/integral-tokensTurborepo Task Dependencies
Turborepo has all of the packages setup as workspace dependencies, so running
turbo dev, turbo build, turbo docs, or turbo build:local will all
first build any packages listed in the package.json dependencies or the
devDependencies.
Performance Optimizations
Tree Shaking
sideEffects: falsein package.json- Direct imports avoid importing entire libraries
CSS Loading Strategy
- Cascade layers ensure proper specificity
- Split bundles for primitives vs brand components
- PostCSS optimization in production
- Selective imports for smaller bundles or non-branded apps
Development Speed
- Package builds are typically minimized during development
- Turbo caches unchanged packages
- Direct file exports are used for just in time (JIT) compilation at app level
- Hot reload works across package boundaries
Best Practices
Design System Guidelines
- Tokens: Use for all colors/spacing/typography
- Layers: Flexible cascade hierarchy
- Primitives: Pure CSS, no SCSS features, Use to collect styles included from external components like shadcn
- Styled Components: Use SCSS for complex styling
- Utilities: App level overrides using tailwind utilities
App Guidelines
- Import styles in correct layer order
- Use design tokens over hard-coded values
- Prefer local app level overrides with tickets to migrate to shared design system
- Test any package modifications across apps before committing
Summary
This architecture provides:
- Hybrid Styling: Supports CSS, SCSS, and Tailwind all in one ecosystem
- Cascade Control: CSS layers eliminate specificity issues
- Unified System: All design assets in one package
- Performance: Optimized builds with selective compilation
- Developer Experience: Clear patterns and fast iteration
- Flexibility: Mix styling approaches based on needs
The combination of Turborepo, CSS Cascade Layers, Tailwind CSS v4, and our hybrid CSS/SCSS approach creates a modern, performant foundation for building scalable applications with a consistent design language.