Over the past few months, I've been quietly working on a new project. Today I'm ready to announce Dart Sass to the world. It's a totally new implementation of Sass, designed to be fast, easy to install, and easy to hack on. It's not yet complete—I'm steadily working my way through sass-spec—so today I'm just releasing version 1.0.0-alpha.1. But it's solid enough for you to download, play with, and start filing issues.
You can download a standalone archive from the release page—just extract it, add the folder to your path, and run
npm install -g dart-sass. And, if you happen to be a Dart user yourself, you can install it using
pub global install sass.
Why Rewrite Sass?
Each implementation's strengths complement the other's weaknesses. Where LibSass is fast and portable, Ruby Sass is slow and difficult for non-Ruby-users to install. Where Ruby Sass is easy to iterate on, LibSass's low-level language makes it substantially harder to add new features. A complementary relationship can be healthy, but it can also mean that neither solution is as good as it needs to be. That's what we found when, in May, Marcel officially left the LibSass team1.
Without two people's worth of effort, we were no longer sure that LibSass could keep pace with the speed Chris and I wanted to introduce changes into the language. And it had been clear for a long time that Ruby Sass was far too slow for use cases involving large stylesheets. We needed a new implementation, one that could generate CSS quickly and add new features quickly.
The only downside is that there's a speed hit: Dart Sass is about twice as slow running on V8 as it is running on the Dart VM. However, this still puts it solidly 3-4x faster than Ruby Sass. Ultimately we also hope to provide an easy path for users of the JS-compiled version to move to the Dart VM version as little friction as possible.
What Will Happen to The Other Implementations?
Nothing's changing about LibSass's development. Michael's hard at work adding features from Sass 3.5, and we expect that process to continue as new language features are added. The only difference is that LibSass will no longer be required to be strictly compatible with the latest version of the language in order for that version to launch, since it will no longer be the only implementation with reasonable performance.
More flexibility translates into faster LibSass releases that prioritize the features users want most. Strict compatibility meant that important features like CSS custom property support can't be released until all the tiny tricky edge cases that were in the corresponding Ruby Sass release, like
:root unification, are implemented as well. We'll still strive for as much compatibility as possible, but we won't let that stand in the way of velocity.
Ruby Sass, on the other hand, will eventually go away unless a new maintainer appears. We don't want to make the transition sudden and risk fracturing the ecosystem: Chris and I are committed to maintaining it for one year, which includes keeping the language in sync with any new additions in Dart Sass. If anyone is interested in volunteering as a maintainer after that period, we'd be thrilled to mentor them and teach them the codebase over the coming year. But if no one steps up, Ruby Sass will be officially considered deprecated and unmaintained.
I want to emphasize that we aren't making the decision to stop developing Ruby Sass lightly. This is a big change, and it's not an easy one for me—I've worked on Ruby Sass continuously for almost ten years now, and it's difficult to let that history go. But Chris and I have discussed this thoroughly, and we're convinced this is the right move. We only have so much time to devote to Sass, and it no longer makes sense to put that time into an implementation that's so slow as to be infeasible for many of our largest users.
Before we release the first stable version of Dart Sass, there are a few big things on our to-do list:
Full sass-spec compatibility. There are still a bunch of corners of the language where Dart Sass does the wrong thing, especially with respect to
@extend. I don't expect any individual incompatibility to be especially difficult to address, and sass-spec is pretty comprehensive, so it's just a matter of steadily reducing the number of failing specs until it hits zero.
render()compatibility in the npm package. The node-sass
Dart Sass compatibility in Ruby Sass. There are some cases where Dart Sass intentionally differs from Ruby Sass, particularly when Ruby Sass's behavior is considered a bug. We should add deprecation messages in Ruby Sass and, if we can do so with minimal disruption, add support for the new behavior.
There's plenty more we'd like to do eventually, like supporting Sass in the browser and providing a node-sass-compatible wrapper for Sass on the Dart VM, but those aren't blocking the initial release.
Onward Into the Future
The next couple months will see a lot of work go into getting Dart Sass stable and compatible, and getting Sass 3.5 features into LibSass. I think it's likely that early 2017 will see a stable release of Dart Sass and a 3.5 release of LibSass. At that point we'll set our sight on the big features and start working towards Sass 4.0 and its brand new module system.
I say "officially" because he's still contributing to the project when he can, just not in an official maintainer capacity. ↩
Caveats apply: I'm not a benchmarking expert, and these tests were ad hoc and run against non-representative source stylesheets. If anyone is interested in working on more scientific benchmarks, please let me know! ↩