What Are FSCSS Modules?

An FSCSS module is simply a stylesheet that contains reusable style definitions. Think of them as building blocks for your CSS architecture.

Example Module
@define radius-util(){`
@arr radius[count(200)]

.radius-@arr.radius[]{
  border-radius:@arr.radius[]px;
}
`}

This module defines a reusable utility called radius-util. It doesn't run automatically. Instead, you import it and execute it when you want.

Usage
@import((radius-util) from spacing-utils/fscss)

@radius-util()

This generates all the radius utilities from 1px to 200px.

What is @define? Core Concept

The Foundation of Reusable Code

@define creates a reusable block of FSCSS code. Think of it like:

A Function

Takes parameters, returns generated CSS

A Macro

Expands into multiple CSS rules

A Code Generator

Produces CSS on demand

Simple @define Example
@define card(){`
.card{
  padding:20px;
  border-radius:10px;
}
`}

/* Then run it: */
@card()

/* Outputs the CSS */
.card{
  padding:20px;
  border-radius:10px;
}

Why FSCSS Requires @define

FSCSS does not automatically run imported code. This design has several important benefits:

1. Performance

If every import executed immediately, large libraries would generate thousands of unused styles. With @define, nothing runs unless you call it.

@radius-util()

This keeps styles smaller and more efficient.

2. Control

Developers choose exactly which modules to run.

@import((radius-util, margin-util) from spacing-utils/fscss)

@radius-util()

Only radius utilities are generated.

3. Customization

You can overwrite the array used for the specific function

@arr radius[count(100)]
@radius-util()

Which might generate utilities only up to 100.

Named Imports vs Wildcard *

Why Import by Name Instead of *

Named Import (Recommended)
@import((radius-util) from spacing-utils/fscss)

This imports only that specific definition.

Wildcard Import (Use with Caution)
@import((*) from spacing-utils/fscss)

This imports everything from the module.

Disadvantages of *

  • All utilities are loaded, even if you don't use them
  • Larger compiled CSS output
  • Slower compile time
  • Potential naming conflicts

Example problem: @import((*) from huge-library) might generate 10,000+ unused classes.

Advantages of Named Imports

@import((radius-util, padding-util) from spacing-utils/fscss)
  • Smaller CSS output
  • Faster compilation
  • Better project organization
  • Predictable output

Why FSCSS Libraries Are Usually Remote

Remote Import Example
@import((icon-base, icon-home) from icon-mask_v2)
/* Resolves to: */
https://cdn.jsdelivr.net/gh/fscss-ttr/FSCSS@main/xf/styles/icon-mask_v2.fscss

FSCSS encourages remote modular libraries because:

1. Sharing

Libraries can be reused across multiple projects without copying files.

2. Updates

When the library improves, users automatically get improvements without manual updates.

3. Distribution

Easy distribution through CDNs and package managers.

What FSCSS Does NOT Allow

Direct Style Imports Without @define

FSCSS does NOT allow:

@import(body from module) ❌ Not allowed

If raw styles were imported directly, it would create several problems:

1. No Control Over Execution

Everything would load automatically, whether you need it or not.

2. Name Collisions

Multiple modules could overwrite each other's styles.

3. Large CSS Output

Unused styles would still be generated, bloating your CSS.

Advantages of @define in Your Own Stylesheet

You can build your own reusable components with parameters:

Parameterized Module
@define button(color:#6366f1){`
.btn{
  background:@use(color);
  color:white;
  padding:10px 20px;
  border-radius:6px;
}
`}

/* Usage with default color */
@button()

/* Usage with custom color */
@button(red)

Building Your Own Modular FSCSS System

Organize Your Modules

You can organize files like this:

fscss-modules/utils.fscss

@define spacing-utils(){/*... */} 
@define radius-utils(){/*... */}
@define flex-utils(){/*... */} 
@define grid-utils(){/*... */} 
@define typography-utils(){/*...*/} 

Then import them selectively:

@import((spacing-utils, flex-utils) from "fscss-modules/utils.fscss")

And run them when needed:

@spacing-utils()
@flex-utils()

Module File

Contains @define blocks

Import

Select what you need

Initialize

@module-name()

Is Initializing with @name() Necessary?

Yes, Initialization Is Required

This step executes the defined module. Without it, nothing happens.

@import((radius-util) from spacing-utils/fscss)

If you do not run:

@radius-util()

Then no utilities are generated. The module is imported but not executed.

Why This Design Matters

The FSCSS modular system provides:

Feature Benefit
Better Control Choose exactly which styles to generate
Smaller CSS Output Only generate what you actually use
Reusable Style Generators Build once, use everywhere
Scalable Architecture Grows from small projects to large design systems

FSCSS allows developers to build CSS generators. This makes it possible to create entire utility frameworks using just a few reusable definitions.

How @import and @define communicate

Modules follow a publisher → subscriber contract. @define registers a blueprint; @import extracts it into the current file; a call runs substitution and emits CSS.

1. REGISTRATION  @define mixin(param)   → blueprint only (no CSS yet)
2. EXTRACTION    @import((mixin)…)      → this file’s scope
3. SUBSTITUTION  @mixin(value)          → @use filled → CSS
PhaseWhat happens
Registration@define stores body + parameters; nothing is printed as CSS
Extraction@import binds names (or aliases) in this file only
Substitution@name(args) fills @use(param) and compiles to normal CSS

@import does not “run” the module. CSS appears only when you invoke the mixin.

Rename with as v1.2.6+

  • as fully renames the binding for the current file.
  • The original name is undefined in that file.
  • Other files and the source module are unchanged.
  • No re-@define wrapper is required to pass a name along.
  • A file owns the names it imported (including aliases). Another file can import those owned names from it.
style.fscss — owns m, not mirror
@import((mirror as m) from fscss:micros)
app.fscss — owns mirr
@import((m as mirr) from "style.fscss")
@import((
  ou-root,
  avatar-overlap,
  circle-overlap,
  ou-reduced-motion
) from overlapui)

@arr colors[#1E2783, #8C29B2, #C41348]
@mirr(colors, indices)
exec(_log, "@arr.indices")

@ou-root()
@avatar-overlap(.team-faces)
@circle-overlap(.fab-menu)
@ou-reduced-motion()
fscss:micros   defines  mirror
      │
style.fscss    import mirror as m     → owns m
      │
app.fscss      import m as mirr       → owns mirr
               @mirr(...)             ✅
               @m / @mirror           ❌ in app

Release: v1.2.6 · Prefer fscss@1.2.6 runtime.

Import types

Named

@import((flex-x, flex-center) from flex-control)

.container {
  @flex-center()
}

Alias

@import((circle-progress as cp, progress-range as pr) from circle-progress)

@cp(.progress-circle)
.p75 { @pr(75) }

Everything

@import((*) from "animations.fscss")

Remote (quoted URL)

@import((btn) from "https://cdn.example/buttons.fscss")

Registry library (no quotes)

@import((*) from st-core@v2)
@import((mirror as m) from fscss:micros)

Catalog: /libraries

Local path

@import((card) from "mycomponents/card.fscss")

End-to-end trace

Module theme-pack.fscss

@define elevate(space: 12px) {
  box-shadow: 0 @use(space) 20px rgba(0, 0, 0, 0.1);
  padding: @use(space);
}

Consumer

@import((elevate as shadow) from "theme-pack.fscss")

.card {
  @shadow(16px)
}

CSS output

.card {
  box-shadow: 0 16px 20px rgba(0, 0, 0, 0.1);
  padding: 16px;
}

Import errors

CaseResult
@import((* as all) from "…")Warning: cannot assign * to alias
@import((flex-x as) from "…")Warning: empty / invalid alias
Missing @define nameError: not defined in module
Call original after asError: original name not defined in this file

Quick reference

// Named / alias / star
@import((function1, function2) from "path.fscss")
@import((original as alias) from "path.fscss")
@import((*) from "path.fscss")

// Remote / registry
@import((name) from "https://url/file.fscss")
@import((*) from library-name)
@import((mirror as m) from fscss:micros)

// Chain rename (1.2.6+ — no re-define)
// style.fscss:  @import((mirror as m) from fscss:micros)
// app.fscss:    @import((m as mirr) from "style.fscss")

Runtime: https://cdn.jsdelivr.net/npm/fscss@1.2.6/runtime.min.js

Summary

FSCSS modules allow you to treat styles like reusable building blocks. By combining FSCSS methods, developers can create flexible style systems that scale from small projects to large design systems.

Key Takeaway 1

Use @define to create reusable style generators

Key Takeaway 2

Always initialize modules with @name()

Key Takeaway 3

Use named imports; rename with as (original undefined in this file)

The modular approach keeps code organized, reusable, and efficient.

@define · Libraries