This guide provides instructions and context for AI agents working with the Backpack Design System codebase.
Backpack is Skyscanner's design system - a collection of design resources, reusable components, and guidelines for creating consistent user interfaces across Skyscanner's products.
- Repository: Skyscanner/backpack
- Language: TypeScript/JavaScript (React components)
- Package Manager: pnpm
- Build System: Webpack, Gulp + custom scripts
- Styling: SCSS with BEM methodology
- Documentation: skyscanner.design
- Each component lives in
packages/backpack-web/src/bpk-component-{name}/ - Components follow the pattern:
BpkComponentName - All components are prefixed with
Bpk - Examples:
BpkButton,BpkCard,BpkChip
packages/
├── bpk-component-{name}/ # Individual React components
├── bpk-mixins/ # SCSS mixins and utilities
├── bpk-stylesheets/ # Compiled CSS
└── bpk-tokens/ # Design tokens
- React components: PascalCase (e.g.,
BpkButton.tsx) - SCSS files: PascalCase (e.g.,
BpkButton.module.scss) - Test files:
{ComponentName}.test.tsx - Story files:
{ComponentName}.stories.tsx
- TypeScript: All new components must be written in TypeScript
- Props Interface: Define clear TypeScript interfaces for all component props
- Default Props: Use default parameters for optional props
- Accessibility: All components must meet WCAG 2.2 AA standards
- Testing: Jest + React Testing Library for unit tests
- Storybook: All components must have corresponding stories
- Use BEM methodology for CSS class naming
- All classes prefixed with
bpk- - Example:
.bpk-button,.bpk-button--large,.bpk-button__icon - Import design tokens from
bpk-tokens - Use SCSS mixins from
bpk-mixins
// Standard prop patterns
interface BpkComponentProps {
children?: React.ReactNode;
className?: string;
onClick?: (event: React.MouseEvent) => void;
// ... component-specific props
}
// Common prop naming
- size: 'small' | 'default' | 'large'
- variant: 'primary' | 'secondary' | 'destructive'
- disabled: boolean
- loading: boolean# Install dependencies
pnpm install
# Build all packages
pnpm run build
# Run tests
pnpm test
# Run Storybook
pnpm run storybook
# Lint code
pnpm run lint
# Type check
pnpm run typecheck-
Create Component Package
- Follow existing package structure in
packages/backpack-web/src/bpk-component-{name}/ - Include: component file, tests, stories, SCSS, and package.json
- Follow existing package structure in
-
Component Implementation
- Write TypeScript React component with proper props interface
- Include proper JSDoc comments
- Implement accessibility features (ARIA labels, keyboard navigation)
- Follow existing component patterns
-
Styling
- Create SCSS file with BEM naming
- Use design tokens from
bpk-tokens - Follow responsive design principles
- Support RTL languages
-
Testing
- Unit tests with React Testing Library
- Accessibility tests
- Visual regression tests (if applicable)
-
Documentation
- Storybook stories showing all variants
- Comprehensive prop documentation
- Usage examples
Backpack uses design tokens and typography mixins for consistent styling across all components. The token system is built on top of @skyscanner/bpk-foundations-web and provides access to all design system values.
Design tokens are centralized in packages/bpk-mixins/_tokens.scss which forwards all tokens from the foundations package:
@forward '@skyscanner/bpk-foundations-web/tokens/base.default';Always import both tokens and typography at the top of your SCSS files:
@use '../../bpk-mixins/tokens';
@use '../../bpk-mixins/typography';Backpack provides a comprehensive set of typography mixins for consistent text styling. Use these instead of setting font properties manually. There are more options available in bpk-mixins/typography.
.my-component {
// Size-based typography
&__small-text {
@include typography.bpk-text-xs; // Extra small
@include typography.bpk-text-sm; // Small
@include typography.bpk-text-base; // Base/default
@include typography.bpk-text-lg; // Large
@include typography.bpk-text-xl; // Extra large
@include typography.bpk-text-xxl; // 2x large
@include typography.bpk-text-xxxl; // 3x large
}
}.my-component {
// Text colors
color: tokens.$bpk-text-primary-day;
color: tokens.$bpk-text-secondary-day;
color: tokens.$bpk-text-disabled-day;
color: tokens.$bpk-text-on-dark-day;
// Background colors
background-color: tokens.$bpk-canvas-day;
background-color: tokens.$bpk-canvas-contrast-day;
background-color: tokens.$bpk-surface-highlight-day;
// Brand colors
background-color: tokens.$bpk-core-primary-day;
background-color: tokens.$bpk-core-accent-day;
// Border colors
border-color: tokens.$bpk-line-day;
border-color: tokens.$bpk-line-on-dark-day;
}.my-component {
// Spacing functions return values in rem
padding: tokens.bpk-spacing-base(); // 1rem (16px)
margin: tokens.bpk-spacing-lg(); // 1.5rem (24px)
gap: tokens.bpk-spacing-sm(); // 0.5rem (8px)
// Multiple values
padding: tokens.bpk-spacing-sm() tokens.bpk-spacing-base();
margin: tokens.bpk-spacing-md() 0;
// Full spacing scale
padding: tokens.bpk-spacing-none(); // 0
padding: tokens.bpk-spacing-sm(); // 0.5rem
padding: tokens.bpk-spacing-base(); // 1rem
padding: tokens.bpk-spacing-md(); // 1.25rem
padding: tokens.bpk-spacing-lg(); // 1.5rem
padding: tokens.bpk-spacing-xl(); // 2rem
}-
Prefer Typography Mixins: Use semantic typography mixins like
bpk-body-defaultinstead of size-based ones likebpk-text-base -
Use Spacing Functions: Always use
tokens.bpk-spacing-base()instead of direct values -
Semantic Color Naming: Use semantic color tokens that describe purpose, not appearance
-
Consistent Patterns: Follow established patterns for similar UI elements
@use '../../bpk-mixins/tokens';
@use '../../bpk-mixins/typography';
.bpk-my-component {
display: flex;
flex-direction: column;
padding: tokens.bpk-spacing-base();
background-color: tokens.$bpk-canvas-day;
border-radius: tokens.bpk-border-radius-md();
border: tokens.$bpk-border-size-sm solid tokens.$bpk-line-day;
box-shadow: tokens.bpk-box-shadow-sm();
&__title {
@include typography.bpk-heading-3;
color: tokens.$bpk-text-primary-day;
margin-bottom: tokens.bpk-spacing-sm();
}
&__body {
@include typography.bpk-body-default;
color: tokens.$bpk-text-secondary-day;
margin-bottom: tokens.bpk-spacing-base();
}
&__link {
@include typography.bpk-link;
@include typography.bpk-link-underlined;
}
&--compact {
padding: tokens.bpk-spacing-sm();
.bpk-my-component__title {
@include typography.bpk-heading-4;
}
.bpk-my-component__body {
@include typography.bpk-caption;
}
}
}- Always include proper ARIA labels on interactive components
- Support keyboard navigation
- Ensure color contrast meets WCAG standards
- Test with screen readers
- Use semantic HTML elements
- Use React.memo for expensive components
- Implement proper tree shaking
- Minimize bundle size impact
- Lazy load heavy components when possible
- Support RTL languages
- Use semantic markup that works across languages
- Consider text expansion in different locales
- Test with longer text strings
- Check if all required props are provided
- Verify imports are correct
- Ensure SCSS is properly imported
- Check for TypeScript errors
- Verify SCSS compilation
- Check class name conflicts
- Ensure design tokens are imported
- Validate BEM naming conventions
- Check TypeScript compilation errors
- Verify all dependencies are installed
- Ensure tests are passing
- Check linting errors
- Components may have Figma mappings for design-to-code workflows
- Check for existing Code Connect mappings
- Follow Figma component naming conventions
- All packages are published to npm under
@skyscanner/scope - Follow semantic versioning
- Update changelogs for releases
- Coordinate with design team for major changes
Check the decisions/ directory for architectural decisions and guidelines:
- Component naming conventions
- API design patterns
- Accessibility requirements
- Testing strategies
- Build system choices
- Documentation: skyscanner.design
- Contributing: See CONTRIBUTING.md
- Code Review: See CODE_REVIEW_GUIDELINES.md
- Issues: File GitHub issues for bugs or feature requests
packages/backpack-web/src/bpk-component-example/
├── src/
│ ├── BpkExample.tsx # Main component
│ ├── BpkExample.module.scss # Styles
│ ├── BpkExample.test.tsx # Tests
│ └── BpkExample.stories.tsx # Storybook stories (colocated)
├── README.md # Component documentation
// Component imports
import BpkButton from '@skyscanner/backpack-web/bpk-component-button';
// Token imports
@use '@skyscanner/backpack-web/bpk-mixins/tokens';This guide should help AI agents understand the structure, patterns, and conventions used in the Backpack Design System codebase.
See .claude/guidelines/bpk-component-reuse.md for the full rule, search instructions, component mapping table, and BpkButton / BpkText API reference.
See .claude/guidelines/bpk-layout-components.md for when to use BpkFlex / BpkStack / BpkGrid and when to fall back to SCSS.
See .claude/guidelines/bpk-token-value-lookup.md for the lookup workflow, naming conventions, TSX usage pattern, and common mistakes.
See .claude/guidelines/bpk-icon-usage.md for icon import pattern, withButtonAlignment usage, className restrictions, and size guidance.
See .claude/guidelines/bpk-new-component-workflow.md when scaffolding a new component package, wrapping an Ark UI primitive, or creating a new *.module.scss file. Covers the ESLint allowlist for Ark wrappers, the SCSS → .module.css compile step, prop-naming pitfalls (style/className), and the per-package scaffolding checklist.