# How to Sort a Slice in Go 1.21: The Modern Generic Approach

> Learn the modern Go 1.21 way to sort slices using generic slices.Sort and slices.SortFunc with cmp.Compare for efficient and flexible data ordering.

- Repository: [JetBrains/go-modern-guidelines](https://github.com/jetbrains/go-modern-guidelines)
- Tags: how-to-guide
- Published: 2026-08-29

---

**Use the `slices.Sort` function for ordered types and `slices.SortFunc` with `cmp.Compare` for custom ordering logic, both introduced in the Go 1.21 standard library.**

The JetBrains/go-modern-guidelines repository establishes that code targeting Go 1.21+ should migrate from the legacy `sort` package to the generic `slices` package. This shift eliminates reflection overhead and provides compile-time type safety for sorting operations.

## Sorting Ordered Types with `slices.Sort`

For slices of **ordered types**—including `int`, `float64`, `string`, and their aliases—use **`slices.Sort`**. This replaces the type-specific functions `sort.Ints`, `sort.Strings`, and `sort.Float64s` with a single generic implementation.

According to [`internal/guidelines/guidelines.json`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/guidelines/guidelines.json) at line 828, the guideline states: *"Use `slices.Sort` for slices of ordered values."* The function accepts any type satisfying the `constraints.Ordered` interface, unifying sorting syntax across primitive types.

```go
package main

import (
    "fmt"
    "slices"
)

func main() {
    // Integer sorting
    ints := []int{5, 2, 9, 1}
    slices.Sort(ints)
    fmt.Println(ints) // [1 2 5 9]

    // String sorting
    words := []string{"banana", "apple", "cherry"}
    slices.Sort(words)
    fmt.Println(words) // [apple banana cherry]
}

```

## Custom Comparators with `slices.SortFunc`

When sorting by custom criteria or complex structs, use **`slices.SortFunc`** combined with **`cmp.Compare`**. This pattern supersedes `sort.Slice`, which required fragile index-based closures.

The guideline at line 808 of [`internal/guidelines/guidelines.json`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/guidelines/guidelines.json) recommends: *"Use `slices.SortFunc` with `cmp.Compare` instead of `sort.Slice` for typed comparisons."* The comparator function receives the actual elements rather than indices, preventing off-by-one errors and eliminating type assertions.

```go
package main

import (
    "cmp"
    "fmt"
    "slices"
)

type Person struct {
    Name string
    Age  int
}

func main() {
    people := []Person{
        {"Alice", 30},
        {"Bob", 25},
        {"Carol", 35},
    }

    // Sort by Age ascending
    slices.SortFunc(people, func(a, b Person) int {
        return cmp.Compare(a.Age, b.Age)
    })
    
    fmt.Println(people) // [{Bob 25} {Alice 30} {Carol 35}]
}

```

The `cmp.Compare` helper returns `-1`, `0`, or `1` based on the comparison, making the sort order explicit and consistent across your codebase.

## Source Code Guidelines

The JetBrains/go-modern-guidelines project encodes these rules in [`internal/guidelines/guidelines.json`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/guidelines/guidelines.json), which is loaded at compile-time by [`internal/guidelines/guidelines.go`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/guidelines/guidelines.go). The helper functions `ListText` and `ExplainText` expose these guidelines to CLI tools, ensuring the recommendations remain synchronized with the repository's analysis logic.

Unlike the pre-generics `sort` package that relied on `interface{}` and reflection, the `slices` implementation generates optimized code for your specific type at compile time.

## Summary

- **Replace `sort.Ints` and `sort.Strings`** with **`slices.Sort`** for primitive types.
- **Replace `sort.Slice`** with **`slices.SortFunc`** and **`cmp.Compare`** for custom ordering.
- **Import `slices`** from the standard library (available since Go 1.21) to avoid third-party dependencies.
- **Reference [`internal/guidelines/guidelines.json`](https://github.com/JetBrains/go-modern-guidelines/blob/main/internal/guidelines/guidelines.json)** in the JetBrains repository for authoritative guidance on modern sorting patterns.

## Frequently Asked Questions

### What replaced `sort.Slice` in Go 1.21?

**`slices.SortFunc`** replaced `sort.Slice` for custom sorting logic. Where `sort.Slice` required a function comparing indices (`func(i, j int) bool`), `slices.SortFunc` uses typed element comparison (`func(a, b T) int`), eliminating index boundary errors and reflection overhead as documented in the JetBrains guidelines.

### Do I need to import `constraints` to use `slices.Sort`?

No. While `slices.Sort` internally requires types satisfying `constraints.Ordered`, you do not need to import `golang.org/x/exp/constraints`. Simply pass slices of built-in ordered types (int, float64, string) directly to the function.

### How do I sort a slice in descending order using modern Go?

Use `slices.SortFunc` with an inverted comparator. Swap the arguments passed to `cmp.Compare` (e.g., `return cmp.Compare(b.Age, a.Age)` for descending age sort), or sort ascending then call `slices.Reverse` on the slice.

### Is `slices.Sort` faster than the old `sort.Ints`?

**Yes.** The `slices.Sort` function avoids the interface conversion and reflection costs present in `sort.Ints`. By using generics, the compiler generates monomorphized sorting code specific to your element type, resulting in better CPU cache utilization and fewer allocations.