Adding a formatter for CSS & JS

Hmm, Biome looks interesting. Thanks for that. I will evaluate it. It seems fairly well established at first glance.

So at this point I’ve been using biome at work quite happily for a few months. I feel like it’s both better and faster than Prettier, generally. I am a bit nervous about using something that isn’t 100% the most used thing, but Prettier seems awkward to use with pre-commit and I feel Biome is used enough that it’s unlikely to go anywhere anytime soon.

The only real issue is that it’s also an ESLint replacement, and some things here may change.

At this point I think the best thing is for me (or someone) to make a draft PR so we can see how it looks.

1 Like

Thanks for keeping this conversation going @tom .

I’ve set up and used Biome on several projects over the last ~1.5 years, and updated my Django DX book to recommend it. It’s great and It think it has solid usage and backing to keep it around for the long term.

Yes, it’s an ESLint replacement. We could disable the linting side, but I think it’s a fine ESLint replacement too. Then we can reduce the tooling we use.

Happy to look at a draft PR if you find the time to look at it!

2 Likes

Interising thread, I missed it in the first place.

I want to add two informations:

  1. we’re already using a working and stable Prettier pre-commit fork in the Django website djangoproject.com/.pre-commit-config.yaml at main · django/djangoproject.com · GitHub and don’t think that the original repo being archived is something that speak against Prettier itself
  2. Prettier support more format than biome (eg: html, y’all, markdown, …) and it can be very useful to have only one tool to format all of them in the future (I know this thread focus is only had and css)

Before choosing a tools it would be also great to check company behind them and check licenses.

I’m not really in favour of using a fork, nor do I think it’s a good argument to use something just because we use it elsewhere. As far as I can tell there’s no company behind biome, and you can choose between the MIT and Apache 2.0 licenses, both of which are fine as far as I know. Certainly Prettier is also MIT.

I’m also not convinced we need all those formats. Indeed I plan to add one format at a time in any case. HTML support we probably do not want to use as HTML formatters will break template tag nesting.

If we do want other formats later, markdown, yaml and HTML are all in progress.

I also think it’s important to think of the planet a bit as biome is much more performant than the alternatives and these workflows will be run a lot, both on CI and people’s own computers.

I’m not really in favour of using a fork, nor do I think it’s a good argument to use something just because we use it elsewhere.

I mentioned the fact that we use Prettier with pre-commit in the Django site code just as a case in point, and to make it known that we haven’t had any problems. Likewise, I don’t think it’s a good argument to reject a solution just because it’s a fork of a previous archived one when it works well, as demonstrated above, after all it’s a repository of few files and active, not a fork of Prettier itself.

As far as I can tell there’s no company behind biome, and you can choose between the MIT and Apache 2.0 licenses, both of which are fine as far as I know. Certainly Prettier is also MIT.

Good. When I was talking about companies and licenses I was raising a general point of attention.

I’m also not convinced we need all those formats. Indeed I plan to add one format at a time in any case. HTML support we probably do not want to use as HTML formatters will break template tag nesting.
If we do want other formats later, markdown, yaml and HTML are all in progress.

As above, I was making a general reflection, as for Python, JS or CSS files it is convenient that other file formats (e.g. Yaml) also have the same formatter for all.

I also think it’s important to think of the planet a bit as biome is much more performant than the alternatives and these workflows will be run a lot, both on CI and people’s own computers.

On this point I totally agree. If you think that its use can reduce linting times and therefore the energy consumed I am in favor of its use, and indeed, we could also consider it for the Django site code if it proved to be sufficiently compatible with Prettier.

Total aside, but since you mentioned it :earth_americas:

There’s a long-standing idea, needing people power, to try to make Django’s CI somewhat more sophisticated about what workflows it runs when.

I’m going to paste something @mrchrisadams said to me:

The best example I know in the public domain is the work Mozilla did when they looked at recoding the time spent in CI on their machine,

Testing Firefox more efficiently with machine learning - Mozilla Hacks - the Web developer blog

Mozilla found something like a 99% percent saving in CI time, when they started using a model to see which tests it might make sense to run when a new patch was introduced. Here’s a choice quote about the approach they have been taking and the newer approach they were experimenting with in 2020:

These methods have served us well for many years, but it turns out they’re still very expensive. Even with all of these optimizations our CI still runs around 10 compute years per day! Part of the problem is that we have been using a naive heuristic to choose which tasks to run on the integration branch. The heuristic ranks tasks based on how frequently they have failed in the past. The ranking is unrelated to the contents of the patch.

We realized that the current implementation of our CI relies heavily on human intervention. What if we could instead correlate patches to tests using historical regression data? Could we use a machine learning algorithm to figure out the optimal set of tests to run? We hypothesized that we could simultaneously save money by running fewer tests, get results faster, and reduce the cognitive burden on developers. In the process, we would build out the infrastructure necessary to keep our CI pipeline running efficiently.

That “something like a 99% percent saving in CI time” result is frankly eye-watering. A 99% percent saving — if we could get even some of that. :star_struck:

That would be a step change. Much more than any tool switch. (Which may or may not be a good idea for other reasons.)

I wonder if we can find folks with capacity to spend energy on such a change?

2 Likes

@carltongibson this is fascinating maybe we can start a thread on the topic here in the forum and see what we get.

1 Like

Hi gang!

I’ve started a thread about the CI thing here. I’ll add a bit more in the coming days.

FWIW, I’d also had a note of recommendation for Biome, I came across it via @adamchainz’s book, and it seems to offer a way to insulate yourself from the churn that people often associate with the js ecosytem.

Biome has sane defaults and it doesn’t require configuration.

Biome aims to support all main languages of modern web development.

Biome doesn’t require Node.js to function.

Biome unifies functionality that has previously been separate tools. Building upon a shared base allows us to provide a cohesive experience for processing code, displaying errors, parallelize work, caching, and configuration.

If the intention is to provide a bunch of safe, relatively config-free defaults for js and css, without requiring people to know too much about Node.js, prettier syntax, ES lint and so-on, then a tool like Biome seems to fit fairly well. I also appreciate how there goal of providing a consistent set of hints and errors for js and html and css - if you don’t work with front end code all day long, having to learn how to read multiple kinds of errors from multiple kinds of all tools feels like overhead I’d happily avoid.

You can see all the languages / syntaxes supported now, and which ones are planned, in their language support page.

Source: biomejs/biome: A toolchain for web projects, aimed to provide functionalities to maintain them. Biome offers formatter and linter, usable via CLI and LSP.

Update: I was curious about whether the Biome binary is really just “node in a trenchcoat” - i.e. a full fat js runtime with a bit of js added to define it’s behaviour. This a fairly common pattern in the js ecosystem for creating binaries - I think Tailwind does this.

From what I can see though, Biome appears to be a ‘real’ Rust binary, if the github release CLI action is anything to go by. This makes me think it might help for making it easier to consume in the Python/Django ecosystem, because wrapping Rust binaries is pretty common pattern for Python projects now.

2 Likes

I realize it is not worth much, but for the bit of JS/CSS I do I also settled on biome due to it’s good pre-commit integration and “sane” defaults. It basically is what black (or ruff) are for me in python.

1 Like

It seems that I was the only one who did not use it already. :sweat_smile:

I want to emphasize that my comments above were aimed at understanding more and not to hinder the adoption of Biome. :slight_smile:

Given the many positive opinions, I am also in favor of adopting it. :+1:

2 Likes

Let’s proceed with biome then, as a formatter for JS and CSS? There is no tooling for CSS in particular, so I assume that’s where it would be the simplest to get going with it. Then we could assess either how to make it work with ESLint, or how to replace the ESLint configuration with the biome equivalent.

In the original post @tom also mentioned the need for CSS linting. Here I’d find Biome better than nothing but probably not good enough for what we need for Django. I listed my linting must-haves in the Biome discussions to see where it might get to. As of now I see 24 CSS linting rules in Biome, but only half of those I’d qualify as actually useful day to day, and there’s very little that’s configurable to encourage a specific style guide beyond formatting.

For Django specifically, we’d want to enforce:

1 Like

I’m happy to go ahead, just that at the moment I’m waiting for Biome 2, which has better .editorconfig support in particular, and nice to avoid any big changes so shortly after integrating it.

2 Likes

Oh nice.

The tracking issue for that is here, for anyone else interested: ☂️ Road to Biome v2.0 · Issue #3727 · biomejs/biome · GitHub

Biome reimplements most of the core rules from ESLint and has opinions of its own, so I don’t think it’s feasible to run the two tools side-by-side. We may able to use the ESLint migration tool to help keep configuration similra.

I think it’s clear we can’t use Biome and ESLint together.

However I think we could use Biome and a small set of stylelint rules for things like logical properties. I don’t see a reason why they would conflict. I plan to follow up with this after. It would certainly be nice if Biome supported these in the future, though.

For the record, we have switched the debug toolbar repository to use biome with the recommended ruleset enabled. A few code changes were necessary, but we could just as well have disabled the rules which were violated by our code. Apart from that we haven’t encountered any problems or obstacles yet.

3 Likes