Skip to content

Preprocessor Project — Complete Guide

DodaTech Updated 2026-06-28 6 min read

In this tutorial, you will learn about Preprocessor Project. We cover key concepts, practical examples, and best practices to help you master this topic.

Build a complete design system component library using Sass with the 7-1 architecture, BEM naming, responsive mixins, theming, and automated build pipeline.

What You'll Learn

  • Planning a design system architecture
  • Implementing all preprocessor techniques
  • Building a component library
  • Setting up the build pipeline
  • Documentation generation
  • Publishing and distribution

Why It Matters

  • A portfolio project demonstrates all your Sass skills
  • Design systems are in high demand
  • Component libraries are reusable across projects
  • Automated pipelines are production-ready

Real-World Use

  • A design team ships a component library with Sass
  • A startup creates a UI kit for multiple products
  • A developer includes a component library in their portfolio
  • An enterprise standardizes on a shared design system
flowchart LR
  A[Design System] --> B[Design Tokens]
  A --> C[Components]
  A --> D[Utilities]
  A --> E[Build Pipeline]
  B --> F[_variables.scss]
  C --> G[Button, Card, Form...]
  D --> H[Spacing, Typography]
  E --> I[Vite + PostCSS]

Project Overview

Build a complete design system component library with the following components and features:

Components

  • Button (5 variants, 3 sizes, icon support)
  • Card (with image, body, footer, featured modifier)
  • Form elements (input, select, textarea, checkbox, radio)
  • Navigation (horizontal, vertical, dropdown, mobile off-canvas)
  • Alert (4 variants: success, error, warning, info)
  • Badge (with position modifier)
  • Modal (with overlay, animations, focus trap)
  • Grid (responsive grid system)

Features

  • Design tokens (colors, spacing, typography, breakpoints)
  • Responsive mixins (respond-to, respond-until, respond-between)
  • Theme support (light, dark)
  • BEM naming convention
  • 7-1 architecture
  • Vite build with PostCSS
  • Stylelint configuration
  • Documentation generation

Code Example: Project Structure

design-system/
    src/
        scss/
            abstracts/
                _variables.scss      // Design tokens
                _mixins.scss         // Responsive, variants
                _functions.scss      // Fluid-type, contrast
                _placeholders.scss   // %focus-ring, %sr-only
            base/
                _reset.scss          // CSS reset
                _typography.scss     // Type scale
            components/
                _button.scss         // Button system
                _card.scss           // Card component
                _form.scss           // Form elements
                _nav.scss            // Navigation
                _alert.scss          // Alert variants
                _badge.scss          // Badge component
                _modal.scss          // Modal dialog
            layout/
                _grid.scss           // Grid system
                _container.scss      // Container
            utilities/
                _spacing.scss        // Spacing classes
                _display.scss        // Display classes
            themes/
                _light.scss          // Light theme
                _dark.scss           // Dark theme
            main.scss                // Entry point
    dist/
        css/
            design-system.css        // Expanded (dev)
            design-system.min.css    // Compressed (prod)
    docs/                            // Documentation
    package.json
    vite.config.js
    postcss.config.js
    .stylelintrc.json

Code Example: Entry Point

// main.scss - Design System Entry Point
// 1. Abstracts (no CSS output)
@use 'abstracts/variables';
@use 'abstracts/mixins';
@use 'abstracts/functions';
@use 'abstracts/placeholders';

// 2. Base styles
@use 'base/reset';
@use 'base/typography';

// 3. Layout
@use 'layout/container';
@use 'layout/grid';

// 4. Components
@use 'components/button';
@use 'components/card';
@use 'components/form';
@use 'components/nav';
@use 'components/alert';
@use 'components/badge';
@use 'components/modal';

// 5. Utilities
@use 'utilities/spacing';
@use 'utilities/display';

// 6. Themes
@use 'themes/light';
@use 'themes/dark';

Code Example: Button Component

// components/_button.scss
@use '../abstracts/variables' as v;
@use '../abstracts/mixins' as m;

.button {
    $block: &;

    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.75rem 1.5rem;
    border: 2px solid transparent;
    border-radius: 4px;
    font-size: 1rem;
    font-weight: 500;
    line-height: 1;
    cursor: pointer;
    min-height: 44px;
    text-decoration: none;
    transition: all 0.2s ease;

    &:focus-visible {
        @extend %focus-ring;
    }

    &:disabled {
        opacity: 0.5;
        cursor: not-allowed;
        pointer-events: none;
    }

    &--primary {
        background: v.$color-primary;
        color: #fff;
        border-color: v.$color-primary;

        &:hover {
            background: v.$color-primary-hover;
            border-color: v.$color-primary-hover;
        }
    }

    &--secondary {
        background: transparent;
        color: v.$color-primary;
        border-color: v.$color-primary;

        &:hover {
            background: v.$color-primary;
            color: #fff;
        }
    }

    &--small {
        padding: 0.5rem 1rem;
        font-size: 0.875rem;
        min-height: 36px;
    }

    &--large {
        padding: 1rem 2rem;
        font-size: 1.125rem;
        min-height: 52px;
    }

    &--full {
        width: 100%;
    }

    &__icon {
        width: 1em;
        height: 1em;
        flex-shrink: 0;
    }

    &__text {
        order: 1;
    }

    &--icon-right {
        #{$block}__icon {
            order: 2;
        }
        #{$block}__text {
            order: 1;
        }
    }

    @include m.respond-to('md') {
        &--full\@md {
            width: 100%;
        }
    }
}

Code Example: Build Configuration

// vite.config.js
import { defineConfig } from 'vite';

export default defineConfig({
    build: {
        lib: {
            entry: 'src/scss/main.scss',
            formats: ['css'],
            name: 'design-system'
        },
        outDir: 'dist/css',
        cssMinify: true,
        sourcemap: true
    },
    css: {
        preprocessorOptions: {
            scss: {
                api: 'modern-compiler',
                silenceDeprecations: ['import']
            }
        },
        postcss: {
            plugins: [
                require('autoprefixer'),
                require('cssnano')({
                    preset: ['default', {
                        discardComments: { removeAll: true }
                    }]
                })
            ]
        }
    }
});
// package.json
{
    "name": "design-system",
    "version": "1.0.0",
    "scripts": {
        "dev": "vite",
        "build": "vite build",
        "build:css": "sass src/scss/main.scss dist/css/design-system.css --style expanded --source-map",
        "build:css:min": "sass src/scss/main.scss dist/css/design-system.min.css --style compressed --no-source-map",
        "lint": "stylelint 'src/**/*.scss'",
        "lint:fix": "stylelint 'src/**/*.scss' --fix",
        "prepublish": "npm run build"
    },
    "devDependencies": {
        "sass": "^1.77.0",
        "vite": "^5.4.0",
        "autoprefixer": "^10.4.0",
        "cssnano": "^6.0.0",
        "postcss": "^8.4.0",
        "stylelint": "^16.0.0",
        "stylelint-config-standard-scss": "^13.0.0"
    }
}
// .stylelintrc.json
{
    "extends": "stylelint-config-standard-scss",
    "rules": {
        "max-nesting-depth": 3,
        "selector-max-specificity": "0,3,0",
        "scss/at-mixin-pattern": "^[a-z]+([a-z0-9]-?[a-z0-9]+)*$",
        "scss/dollar-variable-pattern": "^[a-z]+([a-z0-9]-?[a-z0-9]+)*$",
        "selector-class-pattern": "^[a-z][a-zA-Z0-9]*(-[a-zA-Z0-9]+)*(__[a-zA-Z0-9]+)*(--[a-zA-Z0-9]+)*$"
    }
}

Common Mistakes

  1. Skipping the planning phase — Define your component API, token names, and file structure before writing code.
  2. Not testing compiled output — Verify that scoped variables, extends, and mixins compile correctly.
  3. Ignoring Accessibility — All components must include focus indicators, aria attributes, and keyboard support.
  4. No size budget — Without monitoring output size, component libraries bloat. Set and enforce a budget.
  5. Inconsistent naming — Use the same patterns across all components. BEM + kebab-case is reliable.
  6. Not publishing documentation — A component library without usage docs is unusable. Include examples for each component.
  7. Locking into a specific build tool — Write portable Sass that works with any build tool (Vite, Webpack, Gulp).

Practice Questions

  1. What is the first step in building a design system? Define design tokens (colors, spacing, typography) before building components.
  2. Why use the 7-1 architecture for a component library? It separates concerns logically, scales with component count, and follows community conventions.
  3. How do you ensure components are accessible? Include focus indicators, proper aria attributes, keyboard support, 44px touch targets, and color contrast.
  4. What should be included in component documentation? Usage examples, code snippets, variant previews, configuration options, and accessibility notes.

FAQ

How do I version a Sass component library?

Use semantic versioning. Major version for breaking CSS changes. Tag releases in git. Publish to npm.

Should I include compiled CSS in the npm package?

Yes. Include both expanded (for development) and compressed (for production) CSS. Also include source SCSS for consumers who want to customize.

How do I handle breaking changes?

Deprecate old APIs with @warn. Document migration paths. Bump the major version. Provide codemods if possible.

Mini Project

This lesson is the final project. Build the complete design system component library as described above. Include all 7 components with BEM naming, responsive mixins, light/dark theme support, 7-1 architecture, Stylelint configuration, Vite build with PostCSS (autoprefixer + cssnano), and npm scripts for dev/build/lint. Create an HTML demo page that showcases every component in all variants. Verify: (1) linting passes, (2) production CSS is under 50KB compressed, (3) all components are responsive, (4) dark theme works via data-theme attribute, (5) source maps work in development, (6) focus indicators are visible on all interactive elements.

What's Next

You have completed all 30 lessons of the CSS Preprocessors module. Continue with What Is Mobile-First Design in the next topic.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro