You don't need CSS preprocessor

Published: (February 8, 2026 at 04:49 AM EST)
6 min read
Source: Dev.to

Source: Dev.to

CSS Pre‑processors: Are They Still Worth It?

There was a time when CSS preprocessors seemed like a magical elixir for any CSS problems. It was only necessary to learn a new syntax, set up the environment, and add several dependencies to your project. But as time passed, web technologies developed, and preprocessors remained in their own isolated world. So right now I don’t see any reason to use these tools in development.

Let’s take a look at what preprocessors offer us, and how valuable their features are at the moment.

Variables, Nesting, Operations and Scope

Modern CSS has matured significantly compared to its original version. Now you can:

  • Create variables using @property
  • Limit the scope of selectors with @scope
  • Describe complex operations with calc
  • Use nested CSS rules

Therefore, these features are no longer exclusive advantages of preprocessors.

Mixins, Maps and Functions

Complex data structures such as mixins, maps, and functions seem to be a real advantage of preprocessors. But don’t you think there is already a programming language in web development that has been able to do all this for a long time?

The very concept of CSS‑in‑JS carries an important message – don’t invent a new programming language, use JavaScript. Browsers now support a class of CSS constructed StyleSheets:

  • CSSStyleSheet – a constructable stylesheet
  • document.adoptedStyleSheets – can be added to the HTML document
  • shadowRoot.adoptedStyleSheets – can be added to a ShadowRoot

This makes it easier to reuse styles and dynamically change them, radically shifting the balance of power.

Mixin example (Sass)

@mixin theme($theme: DarkGray) {
  background: $theme;
  box-shadow: 0 0 1px rgba($theme, .25);
  color: #fff;
}

.info   { @include theme; }
.alert  { @include theme($theme: DarkRed); }
.success{ @include theme($theme: DarkGreen); }

JS replacement

const DarkGray = '169, 169, 169';
const DarkRed  = '139, 0, 0';
const DarkGreen= '0, 100, 0';

function theme(value = DarkGray) {
  return `
    background: ${value};
    box-shadow: 0 0 1px rgba(${value}, .25);
    color: #fff;
  `;
}

const sheet = new CSSStyleSheet();
sheet.replaceSync(
  `.info   {${theme()}}` +
  `.alert  {${theme(DarkRed)}}` +
  `.success{${theme(DarkGreen)}}`
);

Map example (Less)

#colors() {
  primary:   blue;
  secondary: green;
}

.button {
  color:  #colors[primary];
  border: 1px solid #colors[secondary];
}

JS replacement

const COLORS = {
  primary:   'blue',
  secondary: 'green'
};

const sheet = new CSSStyleSheet();
sheet.replaceSync(
  `.button {
    color: ${COLORS.primary};
    border: 1px solid ${COLORS.secondary};
  }`
);

Function example (Stylus)

add(a, b)
  a + b

sub(a, b)
  a - b

invoke(a, b, fn)
  fn(a, b)

body
  padding invoke(5, 10, add)
  padding invoke(5, 10, sub)

JS replacement

const add   = (a, b) => a + b;
const sub   = (a, b) => a - b;
const invoke= (a, b, fn) => fn(a, b);

const sheet = new CSSStyleSheet();
sheet.replaceSync(
  `body {
    padding: ${invoke(5, 10, add)};
    padding: ${invoke(5, 10, sub)};
  }`
);

All the features of CSS preprocessors can be implemented using pure JavaScript—without extra dependencies and without binding to a specific framework. So what price do you have to pay for using preprocessors?

At What Cost?

Let’s walk through the typical workflow of working with a CSS preprocessor.

1. Install the preprocessor

Below are Package Phobia reports for the three major preprocessors:

PreprocessorReport
SassSass report
LessLess report
StylusStylus report

These libraries are not particularly lightweight, but many developers still install them for the “new experience” factor.

2. Learn the syntax

Mastering a new syntax inevitably costs time and mental effort. Even if you’re quick, you’ll likely need at least a few days to become comfortable.

3. Integrate into the build pipeline

You must add the preprocessor to your bundler (Webpack, Vite, etc.), configure source‑maps, and ensure it works with your CI/CD pipeline. This adds another layer of maintenance.

4. Maintain the codebase

Every time the preprocessor releases a breaking change, you’ll need to update the dependency and possibly refactor your styles.

Bottom Line

  • Modern CSS already provides variables, nesting, calculations, and scoped rules.
  • All “advanced” features (mixins, maps, functions) can be reproduced with plain JavaScript and the native CSSStyleSheet API.
  • Using a preprocessor introduces extra dependencies, learning overhead, and build‑time complexity.

If you already rely on a JavaScript‑centric styling solution (CSS‑in‑JS, design‑tokens, etc.), you may not need a separate preprocessor at all. Conversely, if your team prefers a pure‑CSS workflow and values the ergonomics of Sass/Less/Stylus, the trade‑off might still be acceptable.

Choose the tool that aligns with your project’s architecture and performance goals—don’t adopt a preprocessor just because it once filled a gap that modern CSS has now closed.

Setting Up the Build Tools

It is quite easy (Praise be to Vite!). But then there is an awareness of the problem.

We just moved away from CSS to come back. It was an exciting adventure, but we got the usual static CSS at the output. Is the cost fair?

I’m sure someone will say, “look, you’ve saved so much time compared to writing pure CSS.”
But I spent a lot more effort than I would have writing pure JS.

In addition, the new syntax always imposes its own limitations. The most important limitation is the scope of application. CSS preprocessors solve only one problem, which is now easy to solve without them.

Final Thoughts

In my opinion, using a CSS preprocessor is like flying in a hot‑air balloon. The destination will be reached, but with less comfort than by plane.

The constructed stylesheets have completely changed the balance: now everything that is not implemented in CSS can be done directly using JS. It makes sense to create any CSS‑in‑JS solution only on top of constructed stylesheets. When I started using them, I lacked TypeScript support, server‑side rendering, and selector minification, which is why the idea of EffCSS was born.

It is useful to know about CSS preprocessors—it will look great on your résumé. But it’s hardly worth using them in practice.

Enjoy your Front‑end Development!

0 views
Back to Blog

Related posts

Read more »

DevLaunch

Overview I built a free modern SaaS landing page template using pure HTML, CSS & JS. Open source. - Repository: https://github.com/Haseeb-MernStack/devlaunch-m...