Frontend Masters Boost RSS Feed https://frontendmasters.com/blog Helping Your Journey to Senior Developer Fri, 14 Nov 2025 16:43:20 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.3 225069128 Vite+ https://frontendmasters.com/blog/vite/ https://frontendmasters.com/blog/vite/#respond Fri, 14 Nov 2025 16:43:19 +0000 https://frontendmasters.com/blog/?p=7761 Probably worth keeping an eye on Vite+ (still in “early access”). They say it’s “everything you’ve been duct-taping together” which feels actually kinda fair when you consider this has “dev, build, test, lint, format, monorepo caching & more in a single dependency.” So even if you’re using Vite anyway, perhaps you’d get to ditch Jest for Vitest, ESLint for Oxlint, Prettier for Oxfmt, and whatever monorepo cludge you got (possible Turborepo/Nx/Lerna) for however this thing does it. My favorite part is that the actual parser under the hood would be the same across all the parts, which just feels right.

]]>
https://frontendmasters.com/blog/vite/feed/ 0 7761
Are you nostalgic for a way of building websites gone by? https://frontendmasters.com/blog/are-you-nostalgic-for-a-way-of-building-websites-gone-by/ https://frontendmasters.com/blog/are-you-nostalgic-for-a-way-of-building-websites-gone-by/#comments Mon, 08 Jan 2024 17:23:34 +0000 https://frontendmasters.com/blog/?p=333 You’ll hear people say they miss the Movable Type days. Or that Adobe should have never killed off Fireworks. Or in their heart they are still a MooTools stan. Or that their good ol’ days were Backbone and Lodash. Laying out sprites was their heyday. Table-based layout still makes the most sense to them. Every image should open in a lightbox.

Some people are nostalgic for period of web development gone by.

Has it gone by, though?

I was thinking of this during a recent episode of Jake and Surma’s new show Off The Main Thread where they were talking about build tools. Passingly, they mentioned that if there is some past way of making websites, well, you can actually still do that if you want to.

There are some notable exceptions like Flash, which no longer works in web browsers, but as far as direct web technology is concerned, the web is nearly perfectly backwards compatible, and as long as you’re shipping the browser things it understands. If you’re shipping HTML, CSS, JavaScript, and media formats it understands, it will work now just like it did in whatever period you were nostalgic for. Probably better.

You don’t have to use new frameworks and libraries. You don’t have to use new build tools or bundlers. You don’t have to wire up a fancy CI/CD pipeline. For the record, frontendmasters.com is built in vanilla JavaScript, so arguments that only small and simple sites can be done that way can be suspended.

If you loved Movable Type, that’s still a thing. Need an RSS feed? You can just write one by hand, I remember Jeremy Keith saying that’s what he did for the narration of the Web History series, which he made into a podcast by virtue of hand-crafting the XML file. No tooling needed. Annoyed with Photoshop that makes you have a subscription? Try Acorn, it’s pretty good.

The root point about constructing websites is especially true: if you could do it, then you can do it now.

When I asked around about nostalgic ways of building websites, I got a lot of replies about doing things the vanilla way. Just… write the code. That’s always an option. It’s a good option. It’s the option that isn’t fragile and will break over time as it doesn’t have any dependencies other than a way to edit text. It also has a side effect of being extremely portable. Raw HTML, CSS, and JavaScript can be served by any ol’ web server.

The other thing I found people interestingly nostalgic for is FTP. Changes to a file? You upload them very directly to your server over FTP, File Transfer Protocol, that is. There is something very raw and direct about that that appeals to some people. Perhaps it is that this process can be so heavily abstracted these days that when things go wrong, they miss the old days when almost nothing can go wrong with FTP.

Before you think I’m some new technology eschewing luddite, I actually quite like new technology. For the most part, I think the way we build websites now is largely better. I think source control (likely: Git) is near-vital for teams working on code together. It’s not viable for a team working on a large piece of software to have no idea what is changing. And using that source control as a home base for more detailed communication, testing, deployment, and everything else just makes good sense. Build processes that take our human-authored code and make it better and more efficient for users also makes good sense, so long as we take care to make sure the value tradeoff between increasing complexity and fragility via tooling and providing value to ourselves and users ends up a net benefit.

It’s never “too late” to roll back complexity, knowing that the raw languages that power the web are still essentially viable to author by hand, or at least by less tooling.

There is more to this story though, and I bet some of you, if you’ve made it this far, are frothing at the mouth to tell me. I’ll oblige: jobs.

If you aren’t a top-decision maker at your place of employ, or perhaps are looking for that place of employ, you may not get to make choices about what technology you use to build websites at all. Whatever you are nostalgic for, or deeply wish for, might be entirely off the table. You can always make your case. Paint a picture of what value might come from a simpler approach. But there is no guarantee that you’ll win — and in fact — you might not even be right. I’ve made the mistake of having too much bravado in my rightness of opinion when, looking back, I wasn’t even right.

So you might have to build websites based how you’re told to build websites. That’s just the way of the world. So if you need to build a website using React, a package.json with 90 dependencies, a 90-minute deploy processes, and god knows what else, well, that’s just what’s up right now, and the next step on your journey might be different, especially if you want it to be. I’d even advocate that you learn whatever you need to learn to get and stay employed, as your life and stability is worth a hell of a lot more then some theoretical purity of website construction.

That all said, I have also always thought there was room in the world for an agency that produces entirely vanilla websites. So many agencies ultimately produce one-off pages. A landing page for a marketing campaign, for instance. I think it would be rad to always make those sites with zero dependencies, making that part of your marketing. Simple, fast, secure, easily portable, etc. Just a thought!

Good luck — and embrace the best parts of your nostalgia!

Maximiliano Firtman’s course Vanilla JS: You Might Not Need a Framework is regularly in the top 10 courses on Frontend Masters. Just saying.

]]>
https://frontendmasters.com/blog/are-you-nostalgic-for-a-way-of-building-websites-gone-by/feed/ 2 333
PostCSS Alternative https://frontendmasters.com/blog/postcss-alternative/ https://frontendmasters.com/blog/postcss-alternative/#respond Sun, 07 Jan 2024 20:30:19 +0000 https://frontendmasters.com/blog/?p=374 After I wrote up my Basic CSS Processing Setup that used Lightning CSS, Michael Bishop responded saying he uses PostCSS for essentially the same thing, with a forked repo demonstrating. I think Michael has a good point that PostCSS has a built-in watcher which simplifies the setup nicely. And postcss-preset-env is very similar in spirit, but you don’t get the bundling without another plugin, and you don’t get the minification. So like all things development: it’s a trade-off.

]]>
https://frontendmasters.com/blog/postcss-alternative/feed/ 0 374
Fine, I’ll Use a Super Basic CSS Processing Setup. https://frontendmasters.com/blog/fine-ill-use-a-super-basic-css-processing-setup/ https://frontendmasters.com/blog/fine-ill-use-a-super-basic-css-processing-setup/#comments Wed, 06 Dec 2023 16:30:46 +0000 http://fem.flywheelsites.com/?p=126 If you’d like, you can jump straight to the setup, but I’d like to lay down my thinking first. Here goes.


These days I try to use just CSS. You don’t need a CSS processor these days like you used to, thanks to native CSS getting so much better over the years.

I used to reach for Sass like seconds on Thanksgiving. Of course I’m going for it. There was so much value there! Nesting, loops, mixins, includes, variables, math, just a cornucopia of value. Most of that stuff is in CSS now, and better.

Except includes. Dammit.

Good ones, anyway. Native CSS has @import which is technically an include. I suppose it predates ESM imports by gotta be somewhere near 2 decades. But all it does is trigger another HTTP Request for another stylesheet. It doesn’t concatenate them together which is generally what you want with CSS. Bundle, as it were.

So Sass made @import do bundling. That was a weird call, actually, since it trampled over a native CSS feature in a way that Sass was usually very good about not doing.

And I’d usually lump on PostCSS too, mostly because Autoprefixer had a real hay day of usefulness. These days, there is only precious few things left that even need it anymore (looking at you, mask).

So, between Sass and PostCSS (and probably a specialized minifier), that was getting to be a rather complex CSS processing pipeline. Plus, you’d always have to figure out how to wire it up with whatever other site-building dance you were doing. Maybe you had your own favorites. I know there are Less and Stylus people out there, not to mention a soup of potential PostCSS plugins, specialty tools like CSS modules, and the rest of the iceberg of CSS-in-JS machines.

That fatigued me, and so again: these days I try to use just CSS.

But there are still growing pains as a single CSS file gets bigger. The length of the file can get annoying. The odd CSS property or value that still needs prefixing. The desire to use some new CSS feature that would be easier with a sprinkle of processing.

SO FINE:

Let’s wire up a modern CSS processing setup.

We’re going to use Lightning CSS. It has one job: processing CSS. But offers a compelling set of features:

  1. Bundling
  2. Syntax Lowering
  3. Vendor prefixing
  4. Minification

I’ll get to the details of those as we go.

First, let’s get it installed. Here’s both the core and the CLI because that’s where we want to use it:

npm install lightningcss lightningcss-cli --save-dev

Lightning CSS is from the Parcel project, but here we’re not using it via Parcel, we’re using it directly. It’s now ready to be called at the command line.

Say we have a style.css file and we’re going to process it into a style-min.css file:

lightningcss --bundle --targets '>= 0.25%' --minifystyle.css -o style-min.css

Sweet, done.

Notice we’re specifically asking for the features we want via flags.

We’re going to want a file watcher.

We could make this script easier to run by putting it in our package.json like:

  "scripts": {
    "process": "lightningcss --bundle --targets '>= 0.25%' --minifystyle.css -o style-min.css"
  },

But that’s no fun.

Now every time we write some CSS we have to come back to the command line, run npm run process and then head over to the browser and refresh it to see the changes? We’ve made the choice opt-in to some extra technology here, so let’s get the DX right.

Let’s use Turbowatch to:

  1. Watch our CSS file(s)
  2. Run the command to process the CSS when the files change

I’m no Turbowatch expert but I found it straightforward to set up.

npm install turbowatch --save-dev

Let’s make our npm script run Turbowatch instead:

  "scripts": {
    "dev": "turbowatch ./turbowatch.ts"
  },

So we’ll need that turbowatch.ts file. Fortunately, it’s straightforward:

import { defineConfig } from "turbowatch";

export default defineConfig({
  project: __dirname,
  triggers: [
    {
      expression: ["match", "*.css", "basename"],
      name: "build",
      onChange: async ({ spawn }) => {
        await spawn`lightningcss --minify --bundle style.css -o style-min.css`;
      },
    },
  ],
});

Match files that end in *.css, when they change, run the command.

Cool.

Let’s add a live reloader.

Fair warning, this is extremely old school and definitely not the only option, but I like how easy it is: Live.js.

It’s a script you link up and it monitors the resources on the page and refreshes when they change. So now…

  1. We update our CSS file
  2. Turbowatcher sees the changes
  3. Lightning CSS runs and makes a new CSS file
  4. Live.js sees the change and refreshes the page

That’s the complete DX we’re after here.

Case closed. Lightweight CSS build process complete.

About those Lighting CSS features

Bundling

Like Sass, it’s slightly weird that the concatenation/bundling feature uses @import, which is the native CSS syntax. I sort of don’t blame them as otherwise Lightning CSS doesn’t invent any CSS syntax, which is a pretty special line to cross, and would probably mean they’d have to stop using .css and use .lightning instead or something.

I say that, but the conditional syntax for imports actually is an invented syntax. Strange. Probably would have went with @bundle or something then, so that the native @import behavior would be preserved. As it is, if you try to use the bundling feature and, say try to use Open Props via @import "https://unpkg.com/open-props"; or the like, it will error.

I still think bundling is a crucial feature here and probably wouldn’t use Lightning CSS at all if it didn’t have it.

I can do:

/project/
  /css/
    footer.css
    header.css
    layout.css
    reset.css
  style.css

And style.css can bundle those all together during processing as long as they are referenced:

@import "footer.css";
@import "header.css";
@import "layout.css";
@import "reset.css";

The order is preserved.

Syntax Lowering

Lightning CSS makes the choices on what CSS to process down to code that older browsers understand based on what browsers you actually want to support, ala Browserslist.

Say I want to take advantage of the OKLCH color model (and I do!). I could write…

html {
  --color-dark-purple: oklch(15.96% 0.079 316);
  --color-bright-purple: oklch(45.08% 0.24 308);
  --color-light-purple: #dabbe0;
}

And, as I write, with Browserslist set to defaults, the output will be:

html {
  --color-dark-purple: #190023;
  --color-bright-purple: #7900b5;
  --color-light-purple: #dabbe0;
}

@supports (color: lab(0% 0 0)) {
  html {
    --color-dark-purple: lab(2.88618% 14.7006 -16.436);
    --color-bright-purple: lab(31.5834% 65.0634 -67.2974);
  }
}

Notice the HEX color was left alone, and the OKLCH values were set into lab() instead. I’m not even 100% sure why, but it must be that I’ll get the best cross-browser support of that. That’s nice to not have to think intensely about.

It’s not just colors, it’s lots of features of “modern CSS”. Take, for instance, CSS nesting. I can now write:

div {
  div {
    border-block-start: 1px solid red;
  }
}

We’re close, but not all browsers are supporting native nesting yet. And some browsers right now will choke on that nested selector not “starting with a symbol”. So Lightning CSS will process that to:

div div {
  border-block-start: 1px solid red;
}

That’s supported everywhere, so fine with me! But notice it left the logical property alone. The browsers you get from the default setting all support that, so it’s left alone.

Vendor Prefixing

There isn’t terribly much to be said here, but it does what it says on the box.

.mask {
  mask: url(mask.png);
}

Turns into:

.mask {
  -webkit-mask: url("mask.png");
  mask: url("mask.png");
}

Minification

This is a great feature of Lightning CSS, because it saves us from needing a separate tool for this. Plus, they say it’s the best tool on the market for squeezing the size of that CSS down, so bonus. Sass always had a “compressed” option for output, but nobody trusted it to truly minify CSS. Lightning CSS will do the job nicely.

CSS Modules

I figured I’d point out that Lightning CSS can do CSS Modules. I’m a fan of CSS Modules, the way it does scoped styles is very useful, but generally only in the context of React where I’m in a position to import the styles and apply the proper className. For a very simple CSS processing like this, which doesn’t involve the HTML or templates in any way, we don’t need CSS modules.

Example Project

Wanna see all this functional on a project so you can copy the bits you need like we all do every day? Heck yes, you do:

]]>
https://frontendmasters.com/blog/fine-ill-use-a-super-basic-css-processing-setup/feed/ 1 126