DEV Community

Cover image for Compile FSCSS from Python — CLI, API, Flask & Django
FSCSS tutorial for FSCSS tutorial

Posted on

Compile FSCSS from Python — CLI, API, Flask & Django

FSCSS (Figured Shorthand CSS) usually shows up next to npm, a browser IDE, or a CDN runtime. If your stack is Python-first, you still shouldn’t have to maintain a separate Node app just to turn .fscss into CSS.

The fscss package on PyPI is a thin Python layer around the official compiler. It vendors xfscss (currently 1.2.6) and runs it with Node. Same language as the IDE and npm install fscss — not a second, partial implementation.


What you get

Surface Use
compile_file / compile_string / compile_dir Build scripts & tools
CLI fscss in.fscss out.css Local / CI
--watch Simple recompile loop
init_flask / init_django Static assets on app start

Requirements: Python 3.7+ (tested 3.8–3.12) and Node.js 20+ on PATH. Node is not bundled.

.fscss  →  Python API / CLI  →  node (vendored xfscss)  →  .css
Enter fullscreen mode Exit fullscreen mode

Install

pip install fscss
node --version   # v20+
Enter fullscreen mode Exit fullscreen mode

Minimal example

style.fscss

$accent: #8f6bff;

@define card(sel:.card){`
  @use(sel) {
    px: 16px;
    py: 14px;
    rounded: 12px;
    stack: 12px;
  }
`}

body {
  bg: #0b0a13;
  color: $accent!;
  ff: sans-serif;
}

@card(.panel)
Enter fullscreen mode Exit fullscreen mode

Python

import fscss

fscss.compile_file("style.fscss", "style.css")
Enter fullscreen mode Exit fullscreen mode

CLI

fscss style.fscss style.css
fscss style.fscss --watch
Enter fullscreen mode Exit fullscreen mode

Shorthands like px, rounded, and stack need FSCSS 1.2.5+ in the engine (this package vendors 1.2.6).


API snapshot

import fscss

# In-memory
css = fscss.compile_string("$c: red;\nbody{ color: $c!; }")

# Whole tree → sibling .css files
for src, out in fscss.compile_dir("static"):
    print(f"{src} -> {out}")
Enter fullscreen mode Exit fullscreen mode
Function Notes
compile_file(in, out) Returns compiler stdout/stderr (warnings included). Raises RuntimeError on hard failure.
compile_string(source) Returns CSS when no output_path (warnings not included).
compile_dir(dir) Every .fscss → matching .css
watch_dir(dir) Daemon thread, poll interval

Flask & Django

Flask — compile static folder; watch when debug is on:

from flask import Flask
import fscss

app = Flask(__name__)
fscss.init_flask(app)
Enter fullscreen mode Exit fullscreen mode

Django — e.g. from AppConfig.ready():

import fscss

fscss.init_django()
# or: fscss.init_django("path/to/static")
Enter fullscreen mode Exit fullscreen mode

Ship the compiled .css in production if you want zero Node on the server; use the helper in dev for convenience.


When to use this vs other FSCSS tools

Tool Fit
This package Python apps, pipelines, Flask/Django static
npm fscss Node/CI already in the repo
Browser IDE Learning, multi-file, xfcmds, libck, libon, modules
runtime.min.js / esm.min.js Prototypes in the browser

One language, several front doors — production output is still plain CSS.


Caveats (short)

  • One Node process per compile — fine for builds, not a substitute for a long-lived daemon.
  • Warnings often still exit 0; check return text from compile_file.
  • $variables are order-sensitive; declare them before rules.
  • Engine bugs → Figsh/xfscss; wrapper bugs → fscss-py issues.

Try it

pip install fscss
fscss --version
Enter fullscreen mode Exit fullscreen mode

Compile a real .fscss file and compare with the IDE or npx fscss if you have Node tooling already.

Links

Early package (0.1.x) — reports with minimal input/output and node --version help a lot.

Top comments (0)