npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

create-atomic-resources

v4.4.3

Published

Creates a scss framework for use with atomic-bomb & Storybook templates

Readme

Creates a reusable SCSS resources setup for projects that use atomic design, Storybook, and optionally atomic-bomb.

Rust Neovim

Usage

Run the package from the root of the project that should receive the resources:

npx create-atomic-resources ./src

The command expects one argument:

npx create-atomic-resources <destination-dir>

Example:

npx create-atomic-resources ./src

Updating Existing Resources

Run the latest release against the same destination to update the bundled resource files:

npx create-atomic-resources@latest ./src

If src/resources/design/tokens.json already exists, the installer asks before replacing it. Press Enter or answer n to keep the existing project tokens; the default is no. Answer y or yes to replace it with the latest bundled token file. Other resource files are updated either way.

For web projects, this creates or updates:

src/
└── resources/
    ├── design/
    │   ├── tokens.example.json
    │   └── tokens.json
    ├── fonts/
    └── styles/
        ├── fonts/
        ├── functions/
        ├── headings/
        ├── page/
        ├── reset/
        ├── root/
        ├── tokens/
        ├── utility/
        ├── vars/
        └── main.scss

For Expo or React Native projects, the installer detects expo or react-native in package.json and creates a native-only resource tree instead:

src/
├── hooks/
│   └── useFont/
└── resources/
    ├── design/
    │   └── tokens.json
    ├── fonts/
    │   └── arial.ttf
    ├── scripts/
    │   └── tokens-to-native.mjs
    └── styles/
        ├── colors.ts
        ├── fonts.ts
        ├── index.ts
        └── main.ts

What It Does

The installer:

  • copies the bundled resources directory into the destination directory
  • installs json-to-scss, sass, and prettier as dev dependencies for web projects
  • installs only prettier as a dev dependency for Expo or React Native projects
  • detects pnpm-lock.yaml, yarn.lock, or package-lock.json to choose the package manager
  • defaults to npm when no lockfile exists
  • retries npm installs with --legacy-peer-deps when npm reports an ERESOLVE peer dependency conflict
  • preserves an existing destination tokens.json unless replacement is explicitly confirmed
  • adds resource scripts to the project package.json

The generated web scripts are:

{
  "token": "json-to-scss ./src/resources/design/tokens.json ./src/resources/styles/tokens/_tokens.scss",
  "scss": "sass --quiet ./src/resources/styles/main.scss ./src/resources/styles/main.css",
  "nice": "prettier -w ./src/**"
}

The generated Expo or React Native scripts are:

{
  "token:native": "node ./src/resources/scripts/tokens-to-native.mjs",
  "token-to-native": "node ./src/resources/scripts/tokens-to-native.mjs",
  "nice": "prettier -w ./src/**"
}

The Design Token

The design token file is the source of truth for the generated SCSS token map:

src/resources/design/tokens.json

The token script converts that JSON file into:

src/resources/styles/tokens/_tokens.scss

The generated _tokens.scss file exports a $tokens map. src/resources/styles/tokens/_config.scss reads that map and exposes typed SCSS variables such as $colors, $fonts, $headings, $theme, $spacing, $font-sizes, $border-radius, $box-shadow, $semantic-colors, $z-index, $opacity, and $forms.

Token File Shape

The token file is plain JSON. Keys use the names that the bundled SCSS expects, so keep the top-level names stable unless you also update the SCSS modules that read them.

{
  "unit": "rem",
  "page": {},
  "colors": [],
  "theme": {},
  "fonts": [],
  "headings": {},
  "spacing": {},
  "fontSizes": { "generic": {}, "semantic": {} },
  "borderRadius": {},
  "boxShadow": {},
  "semanticColors": {},
  "zIndex": {},
  "opacity": {},
  "forms": {}
}

Top-level token groups:

  • unit: the base unit label used by the design system. The bundled file uses rem.
  • page: page-level defaults. backgroundColor, margin, and padding are used by the root/page styles.
  • colors: an array of named color entries. Each entry has a type, a CSS color value in color, and an optional shades array.
  • theme: descriptive component or content styling groups. Group keys and item keys are flexible, and all item options are optional.
  • fonts: an array of named font entries. Each entry has a type, a font file uri, and supported sizes.
  • headings: heading font metadata. It contains a shared type, a font uri, and a variant array with h1 through h6 size values.
  • spacing: named spacing scale values.
  • fontSizes: generic size values and semantic aliases that reference the generic scale.
  • borderRadius: named radius values. The generated SCSS exposes this group as $border-radius.
  • boxShadow: named CSS shadow values.
  • semanticColors: named intent colors for UI states such as success, warning, danger, and info.
  • zIndex: named stacking values for layers such as dropdowns, sticky elements, modals, and toasts.
  • opacity: named opacity values for disabled, muted, and overlay states.
  • forms: form-control tokens split into input, focus, disabled, and error groups.

Colors

Color tokens are an array so the SCSS can generate utility classes from each entry:

{
  "type": "bright-green-100",
  "color": "rgb(146, 191, 48)",
  "shades": [20, 30]
}

For every color entry, src/resources/styles/tokens/_config.scss generates:

.bg-{type}
.fg-{type}

For example, a color with "type": "bright-green-100" creates .bg-bright-green-100 and .fg-bright-green-100.

Theme

Theme tokens describe reusable visual recipes that reference the color and spacing scales:

{
  "theme": {
    "buttons": {
      "primary": {
        "backgroundColor": "bright-green-100",
        "foregroundColor": "black",
        "iconColor": "black",
        "paddingHorizontal": "medium",
        "paddingVertical": "small",
        "gap": "small",
        "fontName": "label-text",
        "fontSize": "label",
        "borderRadius": "medium",
        "cursor": "pointer",
        "width": "fit-content"
      }
    },
    "links": {},
    "headings": {}
  }
}

Theme group keys and item keys are flexible. The example above generates a .theme-buttons-primary class and can also be used as a mixin:

@use './src/resources/styles/utility' as utility;

.button {
  @include utility.theme(buttons, primary);
}

Supported item options are optional:

backgroundColor
hoverColor
foregroundColor
textColor
iconColor
paddingHorizontal
paddingVertical
gap
fontName
fontSize
borderRadius
cursor
width

Color options should use names from colors. hoverColor may also use a generated shade name such as bright-green-100-dark-20; when it is omitted and backgroundColor has a configured 20 shade, the hover background uses that shade's CSS variable. Otherwise it falls back to a computed 20% darker color. Spacing options should use names from spacing. fontName accepts a name from fonts, or a direct CSS font-family value. fontSize accepts generic or semantic names from fontSizes, or a direct CSS font-size value. borderRadius accepts a name from borderRadius, or a direct CSS radius. cursor accepts any CSS cursor value.

Font Sizes

Generic font sizes hold reusable values. Semantic font sizes alias that generic scale for usage-based names:

{
  "fontSizes": {
    "generic": {
      "small": "0.875rem",
      "medium": "1rem",
      "large": "1.25rem"
    },
    "semantic": {
      "caption": "small",
      "label": "small",
      "body": "medium",
      "title": "large"
    }
  }
}

These generate CSS custom properties such as --font-size-small and --font-size-body. Semantic custom properties reference their generic counterparts.

Fonts

Font tokens describe available text families and sizes:

{
  "type": "main-text-regular",
  "uri": "'../fonts/freesans'",
  "sizes": ["0.75rem", "0.875rem", "1rem", "1.125rem", "1.25rem"]
}

The uri points to the generated resources font path from the compiled CSS. Keep the quotes inside the JSON string when the value should be emitted as a Sass string.

Headings

Heading tokens define the heading font and the size for each heading level:

{
  "type": "heading",
  "uri": "'../fonts/freesansbold'",
  "variant": [
    { "h1": "2.625rem" },
    { "h2": "2rem" },
    { "h3": "1.75rem" },
    { "h4": "1.625rem" },
    { "h5": "1.5rem" },
    { "h6": "1.375rem" }
  ]
}

Forms

Form tokens keep the default, focus, disabled, and error styles together:

{
  "forms": {
    "input": {
      "height": "2.5rem",
      "padding-x": "0.75rem",
      "padding-y": "0.5rem",
      "border": "1px solid #d0d0d0",
      "border-radius": "0.5rem",
      "background-color": "#fff",
      "text-color": "#161616",
      "placeholder-color": "rgba(0, 0, 0, 0.45)"
    },
    "focus": {
      "border": "1px solid #0288d1",
      "outline-color": "rgba(2, 136, 209, 0.32)",
      "outline-width": "0.1875rem"
    },
    "disabled": {},
    "error": {}
  }
}

Use the same hyphenated keys that appear in the bundled example when a CSS property name needs to be represented directly.

Example Token File

A complete example token file is included at:

src/resources/design/tokens.example.json

Use it as a reference when changing tokens.json, or copy it over tokens.json in a generated project before running the token build.

Requirements

  • Node.js
  • npm, pnpm, or Yarn
  • a package.json in the directory where the command is run

The command should be run from the application root, not from inside the destination folder.

Storybook

Import the generated stylesheet in .storybook/preview.[js|ts]:

import "../src/resources/styles/main.css"

If you install into a different destination directory, adjust the import path to match that directory.

Design Tokens

The design token file should live in:

src/resources/design/tokens.json

After changing tokens.json, rebuild the SCSS token file:

npm run token

This runs the json-to-scss tooling that converts tokens.json into src/resources/styles/tokens/_tokens.scss. To run it directly:

npx json-to-scss ./src/resources/design/tokens.json ./src/resources/styles/tokens/_tokens.scss

Then rebuild the compiled stylesheet:

npm run scss

SCSS

The main SCSS entrypoint is:

src/resources/styles/main.scss

The compiled CSS output is:

src/resources/styles/main.css

The bundled SCSS uses Dart Sass modules with @use and avoids deprecated global Sass APIs.

Flex Mixins

The utility module exposes flex positioning mixins for common layout alignment:

@use './src/resources/styles/utility' as utility;

.toolbar {
  @include utility.flex-center-center;
}

.actions {
  @include utility.flex-top-right;
}

Available named mixins:

flex-top-left
flex-top-center
flex-top-right
flex-center-left
flex-center-center
flex-center-right
flex-bottom-left
flex-bottom-center
flex-bottom-right

Button Mixins

The utility module exposes a base button mixin for clickable div-based controls that should size to their text. It only sets layout and pointer behavior; add padding, gap, color, radius, and other visual treatment separately.

@use './src/resources/styles/utility' as utility;

.button {
  @include utility.theme(buttons, primary);
  @include utility.button;
}

Output from the base button mixin:

display: inline-flex;
width: fit-content;
cursor: pointer;

Additional button helpers:

.nativeButton {
  @include utility.button-reset;
}

.disabledButton {
  @include utility.button-disabled;
}

.fullWidthButton {
  @include utility.button-full-width;
}

.buttonIcon {
  @include utility.button-icon(1.25rem);
}

Interaction And Focus Mixins

Use shared interaction helpers for consistent transitions and keyboard focus states:

.control {
  @include utility.interactive-transition;
  @include utility.focus-ring-visible;
}

.control:focus {
  @include utility.focus-ring;
}

Layout Mixins

Use stack and cluster helpers for common component layout:

.stack {
  @include utility.stack(small);
}

.actions {
  @include utility.cluster(medium);
}

Spacing arguments may be spacing token names such as small, medium, and large, or direct CSS lengths.

Text And Media Mixins

.label {
  @include utility.truncate;
}

.screenReaderOnly {
  @include utility.visually-hidden;
}

.icon {
  @include utility.icon-size(small);
}

Surface Mixins

.panel {
  @include utility.surface;
}

Form Mixins

Form helpers use the generated --form-* variables:

.field {
  @include utility.form-field;
}

.field:focus {
  @include utility.form-field-focus;
}

.field:disabled {
  @include utility.form-field-disabled;
}

.field[aria-invalid='true'] {
  @include utility.form-field-error;
}

Theme Mixins

The utility module also exposes a generic theme recipe mixin backed by theme tokens from tokens.json:

@use './src/resources/styles/utility' as utility;

.button {
  @include utility.theme(buttons, primary);
}

Theme classes are generated with the same group and item names:

.theme-{group}-{name}

For example:

.theme-buttons-primary
.theme-buttons-secondary
.theme-buttons-tertiary

Use the mixin when component Sass owns the selector. Use generated classes when templates can consume utility classes directly.

With atomic-bomb

When using the generated resources together with atomic-bomb, uncomment the component imports in src/resources/styles/main.scss:

/* Uncomment when using atomic-bomb */
//@use '../../components/atoms';
//@use '../../components/molecules';
//@use '../../components/organisms';
//@use '../../components/templates';
//@use '../../components/pages';

Those imports point at the Sass barrel files that atomic-bomb creates in each component folder:

src/components/atoms/_index.scss
src/components/molecules/_index.scss
src/components/organisms/_index.scss
src/components/templates/_index.scss
src/components/pages/_index.scss

When atomic-bomb creates a component, it appends that component to the matching _index.scss barrel. When a generated component is removed with atomic-bomb --remove [NAME], the matching Sass barrel entry is removed as well, so the resource imports in main.scss can stay stable.

Manual Installation

You can also clone the repository with degit:

degit https://github.com/ReneKrewinkel/create-atomic-resources.git <destination-dir>

The npx workflow is preferred because it also installs dependencies and updates package.json scripts.

Troubleshooting

npm peer dependency conflicts

If npm reports an ERESOLVE peer dependency conflict while installing the helper packages, the installer retries automatically with:

npm install --save-dev --legacy-peer-deps json-to-scss [email protected] prettier

This is useful in projects with strict or outdated peer dependency ranges.

Sass requires a newer Node version

Recent Sass releases may require a newer Node.js version than your project uses. The installer pins Sass to a Node 18-compatible version:

npm install --save-dev json-to-scss [email protected] prettier

If you install helper packages manually on Node 18, use the same Sass version pin.

No lockfile detected

When no pnpm-lock.yaml, yarn.lock, or package-lock.json is found, the installer uses npm.

Custom destination directories

The copied resources follow the destination directory you pass to the CLI. The generated package scripts currently target ./src/resources, so if you install into another directory, update the generated token, scss, and nice scripts in your project package.json.

Development

Check the CLI syntax:

npm test

Format the CLI:

npm run nice

Publish workflow:

npm run deploy

deploy runs predeploy, which checks the CLI and bumps the package patch version before pushing commits and tags.