EthicsComputerCourses
Join training +91 90532 10052

@import Deprecation & Migrating Old Code

Sass · Lesson 11 of 26 Intermediate 8 min read Updated

Most Sass code written before about 2020 uses @import to load files, global functions such as darken(), / for division, and a compiler called node-sass. All four are now deprecated or dead. You will meet this code in older company projects, in Bootstrap 5.3's own source and in many online answers, so you need to recognise it and know how to upgrade it safely.

In this lesson you will see what @import did wrong, read the deprecation warnings, learn the Sass team's published plans for Dart Sass 2 and 3, replace LibSass and node-sass, and run the official Sass migrator on an old project.

Old: @import

Before the module system, files were loaded with @import:

SCSS
// main.scss (old style)
@import "variables";
@import "buttons";
SCSS
// _buttons.scss (old style)
.btn {
  background: darken($brand, 10%);
  width: $sidebar / 2;
  @include rounded;
}

It worked, but it had real problems:

  • Everything was global. $brand in _buttons.scss could come from any file loaded earlier. Nobody could tell where a name was defined, and two libraries could silently overwrite each other's variables.
  • Files were loaded again every time. Importing a partial from three files put its CSS in the output three times.
  • No privacy. A library could not hide its helper functions.
  • Order-dependent bugs. _buttons.scss only worked if _variables.scss happened to be imported first.

@use fixes all four: namespaces show where names come from, modules load once, - names are private, and each file states its own dependencies.

The warnings you will see

Compile that old project with current Dart Sass and you get deprecation warnings (the CSS is still produced):

Terminal
npx sass --no-source-map scss/main.scss
Output
DEPRECATION WARNING [import]: Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0.

More info and automated migrator: https://sass-lang.com/d/import

  ╷
1 │ @import "variables";
  │         ^^^^^^^^^^^
  ╵
    scss/main.scss 1:9  root stylesheet

Each warning has a name in square brackets. The ones you will meet most in old code:

NameWhat triggers itModern replacement
import@import "file"@use and @forward
global-builtindarken(), map-get(), percentage() without a modulecolor.adjust(), map.get(), math.percentage()
color-functionsdarken(), lighten(), saturate(), red() and similarcolor.scale(), color.adjust(), color.channel()
slash-div$a / 2math.div($a, 2) or calc()
if-functionif($cond, a, b)if(sass($cond): a; else: b)

You can try one in the editor. This single file uses a deprecated global function:

SCSSTry it yourself
$brand: #cc6699;

.btn {
  background: darken($brand, 10%);
  border-color: lighten($brand, 20%);
}
Output
WARNING: Global built-in functions are deprecated and will be removed in Dart Sass 3.0.0.
Use color.adjust instead.

More info and automated migrator: https://sass-lang.com/d/import
    line 4
WARNING: darken() is deprecated. Suggestions:

color.scale($color, $lightness: -16.6666666667%)
color.adjust($color, $lightness: -10%)

More info: https://sass-lang.com/d/color-functions
    line 4
WARNING: Global built-in functions are deprecated and will be removed in Dart Sass 3.0.0.
Use color.adjust instead.

More info and automated migrator: https://sass-lang.com/d/import
    line 5
WARNING: lighten() is deprecated. Suggestions:

color.scale($color, $lightness: 50%)
color.adjust($color, $lightness: 20%)

More info: https://sass-lang.com/d/color-functions
    line 5
.btn {
  background: rgb(75%, 25%, 50%);
  border-color: rgb(90%, 70%, 80%);
}

The road to Dart Sass 2 and 3

The Sass team has published its plans (sass-lang.com blog, September 2026):

  • Dart Sass 2.0.0 is hoped for in December 2026. Most things that warn in 1.x become errors. / outside calc() becomes a list separator instead of division.
  • @import, global built-in functions and the old if() syntax are not removed in 2.0. They keep warning until Dart Sass 3.0.0, which will come no sooner than two years after Dart Sass 1.80.0 (the October 2024 release that deprecated @import).

So an old project will keep compiling for a while, but slash division will start giving wrong results in 2.0. To find everything that will break, you can turn warnings into errors. Dart Sass 1.107 adds a shortcut for exactly the set that becomes fatal in 2.0:

Terminal
npx sass --fatal-deprecation=dart-sass-2 scss/main.scss css/main.css

On older 1.x versions, name them one by one, for example --fatal-deprecation=slash-div. The opposite flag, --silence-deprecation=import, hides a warning you have decided to live with for now, and --quiet-deps hides warnings that come from third-party files loaded through load paths, such as a framework in node_modules.

LibSass and node-sass: old compilers

Two compilers you will see in old package.json files:

  • LibSass was a C/C++ implementation of Sass, and node-sass was the npm package that wrapped it. Both were deprecated in October 2020, and in October 2025 the Sass team declared LibSass end-of-life: it receives no more updates.
  • LibSass only understands @import, uses / for division and has never supported @use, math.div() or the new colour spaces.

Moving to Dart Sass is a package swap, followed by fixing whatever the warnings point out:

Terminal
npm uninstall node-sass
npm install --save-dev sass

The command-line flags are mostly the same (sass in.scss out.css). If a build tool such as an old webpack sass-loader config names node-sass, change it to sass or sass-embedded. After switching, compare the old and new CSS visually: LibSass had bugs that Dart Sass fixed, and some pages may change slightly.

Running the Sass migrator

You do not have to fix hundreds of files by hand. The Sass migrator is an official tool that rewrites source files. Install it and run the module migration on your entry file; --migrate-deps follows every file it loads:

Terminal
npm install --save-dev sass-migrator
npx sass-migrator module --migrate-deps scss/main.scss
npx sass-migrator division --migrate-deps scss/main.scss

Commit your work to Git first, or add --dry-run --verbose to preview the changes. After those two commands, the old project from the start of this lesson looks like this:

SCSS
// main.scss (migrated)
@use "variables";
@use "buttons";

// _buttons.scss (migrated)
@use "sass:color";
@use "variables";

.btn {
  background: color.adjust(variables.$brand, $lightness: -10%);
  width: variables.$sidebar * 0.5;
  @include variables.rounded;
}

The migrator added namespaces, loaded sass:color for the colour function and replaced the division with an equivalent multiplication. The compiled CSS is identical, and there are no warnings:

CSS
.btn {
  background: rgb(75%, 25%, 50%);
  width: 120px;
  border-radius: 6px;
}

Other migrations include color (old colour functions), if-function (the old if() function), calc-interpolation (removes #{} inside calc()) and namespace (renaming namespaces). If you only want to replace global functions and keep @import for now, add --built-in-only to the module migration.

Common mistakes

  • Silencing every warning and forgetting. --silence-deprecation is a short-term tool. Plan the migration, or Dart Sass 2 and 3 will break the build later.
  • Mixing @import and @use for the same files. Pick one per project; the migrator converts all of it.
  • Keeping node-sass because "it still installs". It is end-of-life and cannot compile modern Sass.
  • Running the migrator on node_modules. Dependencies loaded through load paths are not migrated, and should not be; upgrade the library instead.

Key points

  • @import made everything global, loaded files repeatedly and had no privacy; @use and @forward replace it.
  • @import and global built-in functions were deprecated in Dart Sass 1.80.0 and will be removed in Dart Sass 3.0.0.
  • Dart Sass 2 (planned for around December 2026) turns most other deprecations into errors and makes / a separator.
  • LibSass and node-sass are end-of-life; replace them with the sass or sass-embedded package.
  • sass-migrator module and sass-migrator division (with --migrate-deps) upgrade a whole project automatically.

Exercise

An old Kochi restaurant project has main.scss with @import "settings"; @import "menu";. _settings.scss holds $spice: #b91c1c; and $gap: 24px;. _menu.scss contains .dish { color: darken($spice, 5%); margin-bottom: $gap / 3; }. Write by hand what the three files should look like after migrating to the module system with sass:color and sass:math, without any deprecated features. Then write the two migrator commands that would do it automatically.

Show solution
SCSS
// main.scss
@use "settings";
@use "menu";

// _settings.scss
$spice: #b91c1c;
$gap: 24px;

// _menu.scss
@use "sass:color";
@use "sass:math";
@use "settings";

.dish {
  color: color.adjust(settings.$spice, $lightness: -5%);
  margin-bottom: math.div(settings.$gap, 3);
}
Terminal
npx sass-migrator module --migrate-deps scss/main.scss
npx sass-migrator division --migrate-deps scss/main.scss

Each partial now declares what it needs, so _menu.scss works no matter which file loads it. The division migrator may write math.div() or, for simple cases like halving, a multiplication; both give the same CSS.

Quick Quiz

1. In which major version is Sass @import planned to be removed?

2. What changes about / in Dart Sass 2?

3. What should replace node-sass in a project?

4. What does --migrate-deps tell the migrator?

Learn Sass with a mentor

Free lessons get you started. Our Full Stack Web Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call