Last updated Dec 3, 2024

Less transformer removal

What is the Less transformer?

The Less web-resource transformer (key="less-transformer") was provided by the "Atlassian less Transformer Plugin" and compiled .less files in web-resources to CSS at runtime. It used the Less v1.7.0 pre-processor running in a JS engine for the JVM.

It allowed for reusing styles code across files, particularly variables which is what the "Look and Feel" customisation in DC products was built on.

It also provided style nesting, color manipulation, and language syntax not available in CSS at the time it was introduced to Server and Data Center products.

Removal from DC products

Motivations

  • Security
    • Eliminate a path for potential remote code execution vulnerabilities by removing the runtime processing of user-generated content processing.
    • Reduce the exposure to vulnerabilities in Less, Rhino, and their transitive dependencies.
  • Performance
    • Boost runtime performance by compiling styles at build-time rather than when served.
    • Boost startup times by removing the Less cache warmup system (Jira only).
  • Developer experience
    • Removal of bugs stemming from the use of the Rhino compatibility layer and Atlassian patches to Less.
    • See the resulting styles without launching the product.
    • Removal of bugs stemming from the use of the Rhino compatibility layer and Atlassian patches to Less.
    • Allow for greater flexibility in choosing CSS pre/post-processors.

Timeline

The Less web-resource transformer and Less Maven plugin are deprecated and will only receive critical security patches until the end of life of Jira Software 10.3 (LTS), Jira Service Management 10.3 (LTS), Confluence 9.2 (LTS), Bitbucket 9.4 (LTS), Bamboo 10.2 (LTS) and Crowd 6. Bamboo 10.2 (at the time of writing) is the last to reach end of life on 2026-12-20

By the end of 2025, we're removing the Less web-resource transformer from all Data Center products in their next major versions: Jira Software 11, Jira Service Management 11, Confluence 10, Bitbucket 10, Bamboo 11, and Crowd 7.

Migration

We recommend you migrate in parts (especially with large codebases) starting by moving to build-time Less (v1.7.0) and then [optionally] to either a newer version of Less and/or vanilla CSS. If you also wish to move to another pre/post-processor, we recommend doing that last.

At each step, check changes into your source control and test the plugin styles are working.

1. Migrating to build-time Less compilation

1.1 Replace Less with CSS variables

Media queries do not support CSS variables in their conditions.

If you introduce CSS variables, prefix them with the plugin name to avoid name clashes.

All Less variables provided by Atlassian products will need to be replaced by CSS variables. All variables coming from imports handled by less-tranformer (containing dynamic://, webstatic://, or plugin:// in the path) need to be replaced by CSS variables or a build-time system. If you continue to use Less or another build-time tool it's possible to continue defining your own variables and sharing them across files.

Start by replacing "Look and Feel" and "Color scheme" Less variables with CSS variables listed in the CSS API.

All other colours should be replaced with Atlassian design tokens to feel cohesive with the rest of the product, to support Dark Mode, and support any other plugin or future themes.

1.2 Replace mixins

All Less mixins coming from imports handled by less-tranformer (containing dynamic://, webstatic://, or plugin:// in the path) need to be replaced. Some options are:

  • Inline usages for infrequently used mixins
  • Move the mixin to regularly imported Less file, it will be resolved and processed at build time
  • Make the mixin a style and add classes to the affected elements
  • Request the product source code and import Less files. Warning: not recommended because product source code is not API and will change between versions (potentially to CSS or another pre/post-processor)

Mixins can normally be spotted by starting with . or # and usually look like function calls ending with brackets () which can even take parameters, e.g. .selected(@ak-color-Y500). Mixins without the brackets are the hardest to spot.

1.3 Replace style dependencies with web-resource dependencies

All imports handled by less-tranformer (containing dynamic://, webstatic://, or plugin:// in the path) for the purposes of applying styles inside the product (but not directly referencing code inside) need to be replaced with web-resource dependencies. If you're using atlassian-webresource-webpack-plugin, see the README.

1.3 Replace custom Less transformer functions

There are some custom functions provided only by less-transformer.

For inline images with inlineimage/inlineimageunoptim or data-uri, either using a bundler addon (e.g. Webpack plugin) or no longer inlining will work (i.e. using url()). Only very small images should be inlined to avoid blocking rendering of the page. To use url() in CSS:

  1. Add the image in the resources folder of the plugin
  2. Add the image as a resource to the web-resource
    1
    2
    + <resource type="download" name="images/logo.png" location="/images/logo.png" />
    
  3. Modify the stylesheet to use url()
    1
    2
    - background-image: inlineimage("images/logo.png");
    + background-image: url("images/logo.png");
    

For other use cases, data URIs are also supported in CSS.

For encodeuri and encodeuricomponent there is no direct equivalent, but modern browsers support encodeURI and encodeURIComponent in JavaScript.

If you're retaining a pre/post-processing step or bundler, the tool you're using may already have a replacement or have a similar plugin, or you could write your own replacement function.

1.5 Add a Less build step

To compile the Less files we recommend using build tools like Webpack which supports Less compilation with less-loader. Atlassian webpack plugin also makes it easy to integrate your plugin into Web Resource ecosystem.

1.6 Remove Less Maven plugin

Find and remove all usages of lesscss-maven-plugin from your pom.xml files.

This was a partial ahead-of-time compiler plugin that is no longer needed once you have a Less build step setup.

1.7 Set up CSS minification

When using modern CSS features, you might find that the minifier provided in AMPS (yui-compressor) introduces bugs. There are multiple open issues which is no longer actively maintained. We recommend to replace it with build tools like Webpack which supports CSS minification with modern syntax.

To disable CSS minification, set compressCss to false in your root pom.xml like so:

1
2
<pluginManagement>
    <plugin>
        <groupId>com.atlassian.maven.plugins</groupId>
        <artifactId>amps-maven-plugin</artifactId>
        <configuration>
            <compressCss>false</compressCss>
        </configuration>
    </plugin>
</pluginManagement>

1.8 Remove Less web-resource transformer

If you are using Webpack 5, upgrade atlassian-webresource-webpack-plugin to at least 7.0.0, which doesn’t automatically add the less-transformer to web-resources. For Webpack 4, you can override default transformers to not include less-transformer by overriding the transformationMap:

1
2
// webpack.config.js
new WRMPlugin({
    transformationMap: {
      'js': ['jsI18n'],
      'soy': ['soyTransformer', 'jsI18n']
    },
    // ...continued
})

For all web-resources defined in atlassian-plugin.xml files, search for and remove the following elements:

1
2
<transformation extension="less">
    <transformer key="less-transformer" />
    <transformer key="lessTransformer" /> <!-- The key could also be lessTransformer -->
</transformation>

e.g.

1
2
<web-resource key="example-styles" name="Example Styles">
    <transformation extension="less">
        <transformer key="less-transformer"/>
    </transformation>
    <resource type="download" name="example.css" location="/example.less" />
</web-resource>

would become:

1
2
<web-resource key="example-styles" name="Example Styles">
    <resource type="download" name="example.css" location="/example.css" />
</web-resource>

All client-resources defined in atlassian-plugin.xml files need to be replaced with web-resources. They have a few features that need to be explicitly defined.

  1. Add default web-resource transformers
    1. For all web-resources with .js files, add the jsI18n transformer
    2. For all web-resources with .soy files, add the jsI18n and soyTransformer transformers
  2. Ensure all <resource elements for .soy files have a name attribute the same as location but ending with .soy.js
  3. Replace any directory elements with resource elements for all files inside the directory excluding ones matching the following patterns:
    • /**/*-min*.*
    • /**/*.min*.*
    • /**/*.less.css
    • /**/*-less.css
    • /**/*-test.js
    • /**/*-tests.js
  4. For all SVG resource elements, add a child element of: <param name="content-type" value="image/svg+xml" />

e.g.

1
2
<client-resource key="lib-example">
    <directory location="/lib/example"/>
</client-resource>

would become:

1
2
<web-resource>
    <transformation extension="js">
        <transformer key="jsI18n"/>
    </transformation>
    <transformation extension="soy">
        <transformer key="soyTransformer"/>
        <transformer key="jsI18n"/>
    </transformation>
    <resource type="download" name="/lib/example/foo.js" location="/lib/example/foo.js" />
    <resource type="download" name="/lib/example/bar.soy.js" location="/lib/example/bar.soy" />
    <resource type="download" name="/lib/example/baz.svg" location="/lib/example/baz.svg">
        <param name="content-type" value="image/svg+xml"/>
    </resource>
</web-resource>

2. Migrate from Less to vanilla CSS

Check the browser versions used in your tests are new enough to support the modern CSS syntax used. In case they haven't been updated in a while, we recommend updating them first to match the supported browsers of each Data Center product.

2.1 Replace all inline comments

Inline comments are done with block-style syntax in CSS, e.g.

1
2
- // Comment in Less
+ /* Comment in CSS */  

2.2 Replace Less functions with CSS calculations

Remove usage of any Less functions. For color manipulation we recommend using oklch instead of hsl, even if Less usd hsl

Less functionCSS replacement
desaturate(@color, 50%)oklch(from var(--color) l c calc(h - 0.5))
lighten(@color, 15%)oklch(from var(--color) calc(l + 0.15) c h)
darken(@color, 20%)oklch(from var(--color) calc(l - 0.2) c h)
@var1 + @var2calc(var(--var-1) + var(--var-2)

2.3 Remove all other Less specific syntax

You can find Less specific syntax in the documentation, but be aware it's not exactly the same as with Less v1.

One of the most common cases is to ensure all imports are now valid CSS imports.

2.4 Rename all files

Rename all files to end with .css instead of .less and check there are no syntax errors reported by your IDE.

3. Upgrading Less

3.1 Prepare for syntax differences

Start by wrapping all math with brackets, this is required newer Less versions. e.g.

1
2
- margin-left: @section-gap / 2;
+ margin-left: (@section-gap / 2);

There might be other breaking changes between Less v1.7 and latest Less v4. You can verify the compilation outputs with online tools: Less v1-3, Less v4

3.2 Upgrade through each major version

  1. Build the plugin
  2. Backup the build output, particularly the .jar file
  3. Upgrade the version of Less to the latest of the next major version
  4. Rebuild the plugin
  5. Compare the outputs, they should be the same
  6. If there are no issues or if all issues are resolved, then repeat by trying the next major version

Testing

Sometimes it's easier to check the built plugin .jar file is the same except for file renames (with matching plugin XML changes) and removal of transformer elements from the plugin XML. This is particularly helpful if there are a lot of styles, but most of them were precompiled. It can be worth temporarily adding the lesscss-maven-plugin to see and compare against the compiled CSS.

Adoption

If the plugin uses any global variables from imports with dynamic:, webstatic: or plugin: URI scheme, and you want to replace them with global CSS variables, you will need to provide the global CSS variables values until they are available from products in EAP releases.

Any other changes should not be blocked by new product versions, they can be completed and tested against existing product versions.

Rate this page: