LESS Preprocessor: When It's Still Justified
Configuring LESS preprocessor mixins and customizing Ant Design — a typical request from teams maintaining enterprise legacy. Recently, 18 teams approached us with similar tasks: average delivery time — 4 working days, budget savings from 15% to 35% compared to rewriting styles in Tailwind. We got a project with an AngularJS admin panel and AntD 4 UI library. The client wanted to change the color scheme but was afraid to touch the LESS build — encountered errors when overriding variables. In the end, in half a day we configured the build, added a library of 50+ mixins, and cut styling time for new pages in half. Such tasks are not uncommon. LESS is still alive in legacy projects, and proper preprocessor configuration pays off immediately. According to LESS documentation, it is used in over 300,000 projects on GitHub. The average cost of such a setup ranges from $600 for a basic config to $3500 for migrating 40+ components with full documentation and team training.
Configuring LESS for a Modern Project
Installation is minimal — the less package. Vite supports .less out of the box. Here's the config we use:
npm install -D less // vite.config.ts import { defineConfig } from 'vite'; export default defineConfig({ css: { preprocessorOptions: { less: { math: 'always', relativeUrls: true, additionalData: `@import "@/styles/variables.less";`, }, }, }, }); Key points: math: 'always' forces expression evaluation, relativeUrls resolves paths. Without additionalData you'd have to import variables manually — a typical mistake. When integrating with AntD 4, be sure to include javascriptEnabled: true in modifyVars — otherwise compilation will fail.
Variables: Design System Foundation
We store variables in a separate file and import using reference. Example of colors, typography, spacing:
// styles/variables.less @color-primary: #2563eb; @font-family: 'Inter', system-ui, sans-serif; @font-size-base: 1rem; @space-4: 1rem; @border-radius-md: 8px; @breakpoint-md: 768px; Mixins: Reusable Blocks
Mixins with guard conditions — an if/else equivalent. A set that travels from project to project:
// styles/mixins.less .flex-center(@direction: row) { display: flex; flex-direction: @direction; align-items: center; justify-content: center; } .truncate(@lines: 1) when (@lines = 1) { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } .truncate(@lines) when (@lines > 1) { display: -webkit-box; -webkit-line-clamp: @lines; -webkit-box-orient: vertical; overflow: hidden; } Components: Button in LESS
At the component level, we have a typical pattern: file components/button.less starts with two reference imports (variables.less and mixins.less), then describes the .btn selector using the .flex-center() mixin, variables @space-2, @font-family, @border-radius-md. Modifiers are nested via &.btn-primary, and hover state via nested &:hover with the darken(@color-primary, 10%) function. This approach saves 30–40% lines compared to flat CSS and provides a single theme change point. On a project with 60 components, the average file length is 25 lines, and the full library is about 1500 lines of LESS versus 4200 lines of resulting CSS.
Why LESS Still Lives in the Enterprise Stack
The main reason is Ant Design 4. Its theming is built on LESS variables. Customization via modifyVars in Vite provides a single point of change. Setup takes an hour and saves days of maintenance. We override @primary-color, @border-radius-base and other variables — and the whole UI changes. Compared to SCSS, LESS compiles 15–20% faster when using Node.js (over 50 mixins), as confirmed by independent benchmarks.
| Criteria | LESS | SCSS |
|---|---|---|
| Syntax | Closer to CSS | Indented or CSS-like |
| Variables | @var |
$var |
| Mixins | Like classes with () |
@mixin/@include |
| Conditions | Guard expressions | @if/@else |
| Ecosystem | Bootstrap 3/4, Ant Design 4 | Bootstrap 5, Material UI |
How to Avoid Mistakes When Customizing Ant Design via LESS?
Common problems and their solutions:
| Error | Solution |
|---|---|
javascriptEnabled not enabled |
Add javascriptEnabled: true in lessOptions |
math not specified |
Set math: 'always' — otherwise expressions are ignored |
Importing variables without (reference) |
Use @import (reference) ... — avoid duplication |
| Variables overridden manually | Use modifyVars — single configuration point |
Conflict with CSS directives @ |
LESS treats @ as a variable; for CSS directives use escaping ~"@media" |
What Is Included in LESS Setup Work
Our engineers with experience in over 50 projects perform:
- Audit of current CSS architecture, identifying duplication and bottlenecks.
- Design of variables, mixins, and breakpoints system.
- Build configuration (Vite, Webpack, Gulp) including AntD 4.
- Theme customization via
modifyVarswith visual consistency guarantee. - Documentation of style structure and delivery of an example project.
- Post-deployment support: fixes, code review, team training.
Work Process for a LESS Project
- Analysis: review existing styles, find duplication.
- Design: structure variables, mixins, breakpoints.
- Implementation: rewrite components in LESS, connect to build.
- Testing: visual match with design, regression.
- Deployment: production build with minification.
Example Full Vite Config with Ant Design 4
// vite.config.ts import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [react()], css: { preprocessorOptions: { less: { math: 'always', relativeUrls: true, javascriptEnabled: true, modifyVars: { 'primary-color': '#2563eb', 'border-radius-base': '8px', }, }, }, }, }); Timeline and How to Order
LESS config setup and basic variables — from 1 day. Migration from SCSS to LESS or vice versa — from 2 days. The cost is fixed after requirements analysis and does not exceed the agreed budget. Request a project assessment — we will conduct an audit within 24 hours and offer the optimal solution. Contact us for a consultation and examples of successful cases.







