Skip to content

toakleaf/less.go

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3,597 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

less.go

An attempt at a complete Go port of Less.js - the popular CSS preprocessor. This implementation aims to maintain 100% feature parity with Less.js v4.4.2 while providing the performance benefits of a native Go binary.

Status

Current Release - Fully compatible with Less.js v4.4.2

  • 195/195 integration tests passing (100%)
  • 100 perfect CSS matches with Less.js output
  • 91 error handling tests correctly failing as expected
  • All unit tests passing

Installation

Via npm (Recommended)

Install the pre-built binary for your platform:

npm install lessgo

This automatically installs the correct binary for your operating system and architecture.

Via Go

go install github.com/toakleaf/less.go/cmd/lessc-go@latest

Or add the library to your Go project:

go get github.com/toakleaf/less.go/less

CLI Usage

# Basic compilation
npx lessc-go input.less output.css

# With compression
npx lessc-go --compress input.less output.css

# Read from stdin, write to stdout
cat input.less | npx lessc-go -

# With source map
npx lessc-go --source-map input.less output.css

# Include paths for @import resolution
npx lessc-go --include-path=./mixins:./node_modules input.less output.css

CLI Options

Option Description
--compress Minify output CSS
--source-map Generate source map
--include-path=PATHS Colon-separated paths for @import resolution
--global-var='VAR=VALUE' Define global variables
--modify-var='VAR=VALUE' Override variables
--strict-units Enable strict unit checking
--math=MODE Math mode: always, parens, parens-division
--rootpath=PATH Base path for URL rewriting
--rewrite-urls=MODE URL rewriting: off, local, all
--js Enable inline JavaScript evaluation
--plugin Enable JavaScript plugin support

Library Usage (Go)

package main

import (
    "fmt"
    "log"

    less "github.com/toakleaf/less.go/less"
)

func main() {
    source := `
        @primary: #4a90d9;

        .button {
            background: @primary;
            color: white;
            &:hover {
                background: darken(@primary, 10%);
            }
        }
    `

    result, err := less.Compile(source, nil)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(result.CSS)
}

With Options

result, err := less.Compile(source, &less.CompileOptions{
    Filename:    "styles.less",
    Compress:    true,
    StrictUnits: true,
    Math:        less.Math.ParensDivision,
    Paths:       []string{"./imports", "./node_modules"},
    GlobalVars: map[string]any{
        "theme-color": "#ff6600",
    },
})

Performance

less.go provides native binary performance without requiring a JavaScript runtime:

Metric Less.js less.go Difference
Full suite (90 files) 380ms 175ms Go 2.2x faster
Per file average 4.23ms 1.95ms Go 2.2x faster
Memory per file - 0.56 MB Efficient memory usage
  • No JIT warmup required - Consistent performance from first run
  • Native binary - No JavaScript runtime needed for core functionality

Run benchmarks yourself:

pnpm bench:compare:suite  # Recommended: realistic full-suite comparison
pnpm bench:compare        # Per-file comparison (for debugging)

Features

less.go implements 100% feature parity with Less.js v4.4.2:

  • Variables - @primary: #333;
  • Nesting - Nested rules and selectors
  • Mixins - Parametric, guards, closures, recursion
  • Extend - &:extend(.class)
  • Import - Including npm module resolution
  • Functions - All 60+ built-in functions
  • Detached Rulesets - Reusable rule blocks
  • CSS Guards - Conditional CSS
  • Media Query Bubbling - Automatic media query handling
  • Container Queries - @container with size and style queries
  • CSS Layers - @layer at-rule and import with layer()
  • Property Merge - + and +_ operators
  • Compression - CSS minification
  • Source Maps - Full source map support
  • JavaScript Plugins - Custom functions via Node.js bridge

Project Structure

less.go/
├── less/              # Go implementation (core library)
├── cmd/lessc-go/      # CLI tool
├── testdata/          # Test fixtures
├── test/js/           # JavaScript unit tests
├── npm/               # NPM package templates
├── reference/less.js/ # Original Less.js (git submodule, reference only)
├── examples/          # Usage examples
└── scripts/           # Build and test scripts

Development

Prerequisites

  • Go 1.21+
  • Node.js 18+ (for JavaScript plugin support and tests)
  • pnpm

Setup

# Clone with submodules
git clone --recurse-submodules https://github.com/toakleaf/less.go.git
cd less.go

# Or if already cloned, initialize submodules
git submodule update --init --recursive

# Install dependencies
pnpm install

Running Tests

# Run all integration tests
pnpm test:go

# Run Go unit tests
pnpm test:go:unit

# Run JavaScript unit tests
pnpm test:js-unit

# Quick summary (recommended)
LESS_GO_QUIET=1 pnpm test:go 2>&1 | tail -100

Benchmarking

# Compare Go vs JavaScript performance
pnpm bench:compare

# Go benchmarks
pnpm bench:go:suite

Contributing

See CONTRIBUTING.md for guidelines on:

  • Setting up the development environment
  • Running tests
  • Submitting pull requests

Related Projects

License

Apache License 2.0 - See LICENSE


less.go is a complete Go port, not a fork. It shares no code with Less.js but maintains 100% compatibility through comprehensive testing against the original implementation.

About

Less. The dynamic stylesheet language. Ported to go.

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors