Super JSS

October 24, 2025 · View on GitHub

npm version bundle size Storybook license

Super JavaScript Stylesheets (SJSS) is a tiny, runtime styling library for Angular 20. It generates atomic CSS as you use it, supports responsive breakpoints and theming, and gives you a minimal, ergonomic API.

  • ⚡ Angular‑native: built on Signals
  • 🎯 Atomic CSS generation: only what you use
  • 📱 Responsive + theming: xs…xxl breakpoints and palette tokens
  • 🎨 Pseudo‑selectors: &:hover, &:focus, etc.
  • 🧩 Ready‑made building blocks: <sj-paper>, <sj-card>, <sj-button>, <sj-icon>, and <sj-input>

Docs: https://sjss.netlify.app/ Storybook: https://sjss-storybook.netlify.app/ Live StackBlitz (sj root API): https://stackblitz.com/edit/stackblitz-starters-lgwyvmd2?file=src%2Fmain.ts

What's New?

  • <sj-icon>: A versatile icon component with support for Material Icons, SVG, and font-based icons.
  • <sj-input>: A customizable input component with built-in theming and validation styling.

Why SJSS?

Traditional CSS-in-JS libraries ship massive bundles with every possible utility class. SJSS generates only the atomic CSS you use, keeping your bundle tiny while providing full theming and responsiveness.

Install

npm install super-jss

Quick start

This minimal Hero shows inline [sj] styles, a one‑line theme update, and a reactive breakpoint log.

import { Component, effect, inject } from '@angular/core';
import { SJ_BASE_COMPONENTS_IMPORTS, SjThemeService, sj } from 'super-jss';

@Component({
  standalone: true,
  selector: 'app-hero',
  imports: [SJ_BASE_COMPONENTS_IMPORTS],
  template: `
    <sj-host
      [sj]="[
        sj.display(sj.display.options.flex),
        sj.flexDirection({
          xs: sj.flexDirection.options.column,
          md: sj.flexDirection.options.row
        }),
        sj.justifyContent(sj.justifyContent.options.center),
        sj.alignItems(sj.alignItems.options.center),
        sj.gap({ xs: 0.5, md: 1 }),
        sj.p(2),
        sj.bg(sj.bg.options.light.light)
      ]"
    >
      <sj-paper usePaint="primary" usePadding="default" useRounded="default">
        <h1 [sj]="[sj.m(0)]">Hello SJSS</h1>
      </sj-paper>

      <sj-button
        [sj]="[
          sj.p(2),
          sj.bg('primary.main'),
          sj.c('white'),
          sj.hover([ sj.backgroundColor(sj.bg.options.primary.dark) ])
        ]"
        (click)="updatePrimaryColor()"
      >
        Update Primary
      </sj-button>
    </sj-host>
  `,
})
export class HeroComponent {
  readonly theme = inject(SjThemeService);
  readonly sj = sj;

  private _bpLogger = effect(() => {
    console.log('current breakpoint:', this.theme.breakpoint());
  });

  updatePrimaryColor() {
    this.theme.setTheme({
      palette: {
        primary: { ...this.theme.sjTheme().palette.primary, main: '#4e3149ff' },
      } as any,
    });
  }
}

Key concepts:

  • camelCase properties: backgroundColor, justifyContent, borderRadius
  • Responsive objects: { xs: 1, md: 2, lg: 3 } for breakpoint-specific values
  • Theme tokens: 'primary.main', 'neutral.dark' for consistent colors
  • Pseudo-selectors: '&:hover', '&:focus' for interactions

Core Features

🎨 Theming & Tokens

Use semantic palette tokens and responsive objects anywhere:

sj.backgroundColor('primary.main');
sj.color('primary.contrast');
sj.padding({ xs: 1, md: 2 });

🚀 Shorthands

Popular, ergonomic aliases:

sj.bg('primary.main');
sj.p(2);
sj.m({ xs: 1, md: 2 });
sj.c('neutral.dark');
sj.w('100%');
sj.h(200);
sj.brad(0.5);
sj.gap(1);

📐 Layout

Use the root CSS properties and .options:

sj.display(sj.display.options.flex);
sj.flexDirection(sj.flexDirection.options.column);
sj.justifyContent(sj.justifyContent.options.center);
sj.alignItems(sj.alignItems.options.center);

🎯 Pseudo-selectors

sj.hover([ sj.backgroundColor(sj.bg.options.primary.dark) ]);
sj.focus({ outline: '2px solid blue' });
sj.active({ transform: 'scale(0.95)' });

🧩 Components

Pre-built components with variants:

<sj-paper usePadding="default">...</sj-paper>
<sj-card variant="elevated" [sj]="customStyles">...</sj-card>
<sj-button variant="contained">Click me</sj-button>
<sj-typography variant="h2">Heading</sj-typography>

⚡ Performance

  • Atomic CSS: Generates only used styles
  • Bundled classes: Single class per style object
  • Memoized rendering: Avoids redundant computations
  • Signals integration: Reactive updates without overhead

API Overview

import { sj } from 'super-jss';

// CSS properties
sj.backgroundColor('red');
sj.padding(16);
sj.borderRadius('50%');

// Shorthands
sj.bg('primary');
sj.p(2);

// Helpers
sj.hover({ bg: 'dark' });

// Tokens
sj.palette.primary.main;
sj.breakpoints.md;

// Components
import { SJ_BASE_COMPONENTS_IMPORTS } from 'super-jss';

SuperJSS vs. Material-UI for React

FeatureMaterial-UI for ReactSuperJSS
TypeComponent LibraryStyling Library
Design SystemMaterial DesignAgnostic
FrameworkReactAngular
Core ConceptPre-built componentsUtility-first styling
CustomizationTheming systemTheming system, direct style manipulation

💖 Support

If you find Super JSS useful, consider supporting its development:

☕ ☕ ☕ Buy me a coffee 📬 Contact For inquiries, feedback, or issues, reach out at ricardo.santoyo@hotmail.com.

Readme Keywords angularangular 20angular signalscss-in-jsatomic cssutility-firstdesign systemresponsivebreakpointsthemingruntime themingpalettetypographytailwind alternativestyle directiveangular styling