# hellwal: a wallpaper palette generator written in one C file

> Hellwal takes an image, extracts a sixteen colour palette and renders it through a template you control, in the tradition of pywal but as a single C program with no runtime to install. Its most interesting feature is the chain of colour operations that a template can apply, and its most useful documentation is the README itself.

**danihek/hellwal** — Pywal-like color palette generator, but faster and in C

- Repository: https://github.com/danihek/hellwal
- Stars: 856 · Forks: 26
- Language: C++
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/danihek-hellwal

## One C file, no runtime, and a vendored image decoder

Hellwal is described as a Pywal-like colour palette generator, but faster and in C. The project description says the same thing, and the repository listing backs it up: the source is hellwal.c, with two headers, hell_colors.h and hell_parser.h, and a vendored stb_image.h.

That last file is the key to the whole design. stb_image is a single-header image loading library, so the tool has no external image dependency, no image library to install and no configuration for formats. The repository also carries a VERSION file, a Makefile, a templates/ directory, a themes/ directory and an assets/ directory, which is the entire footprint of a program whose job is to read a picture and write a text file.

The Makefile shows how little it takes to build. There is one C source file, the compiler flags are warnings on, extra warnings on and optimisation at level 3, and the only library linked is the maths one. There are targets for a normal build, a debug build with debug symbols, clean, install into /usr/local/bin with the permissions spelled out in a comment, uninstall, and a release target that produces a versioned tarball from the VERSION file.

So the cost of using it is the cost of a compiler, and the cost of running it is the cost of a process that starts and exits. That is the promise the project makes in its description, and the Makefile is where the promise is kept.

The licence is MIT, the default branch is main, and the release history shows 1.0.5 in July 2025, 1.0.7 in September 2025 and 1.0.8 on 2026-09-15, with the last push a month after that tag.

## Three package managers, and a one line build

The installation section covers the three ecosystems a Linux desktop user is likely to be in.

On Arch Linux the package comes from the AUR:

```sh
yay -S hellwal
```

On Mac and Linux the Homebrew route is:

```sh
brew install hellwal
```

And for NixOS, the README points at the unstable channel of nixpkgs, with the package added to the system packages list:

```nix
environment.systemPackages = [
  pkgs.hellwal
];
```

Building from source is described in one sentence, clone the repository, run make, and you are ready, with a C compiler and gnumake as the only requirements:

```sh
git clone https://github.com/danihek/hellwal && cd hellwal && make
```

There is a small but useful note for AUR users, who get the default templates as part of the package documentation, so the examples of the default templates are found in the system documentation directory. Everyone else has the templates folder in the repository, and the README says the examples there look more or less like a specific shape, which is the format the rest of this article describes.

The install paths matter for one practical reason. The tool writes its generated templates to a cache directory under the user's home, and the AUR package also installs template examples to a system location, so a packaged install and a source build give you a slightly different set of files to start from.

## Templates are plain text with typed placeholders

The template format is a set of placeholders in a shell-style file, and the README shows the shape of a default one.

A placeholder is a name between double percent signs, and there are three families of them. There are the semantic names, background, foreground and wallpaper, which resolve to the main colours and the path of the image. There are the numbered colours, color0 through color15, in hex form. And there are the same colours in RGB form, with separate placeholders for the individual channels.

The formats are the detail that makes the system usable. After the colour keyword you specify the format, and the table gives the input and the output: a hex input gives six characters without a hash, an rgb input gives three comma separated numbers, and the r, g and b variants give a single channel value. By default the template output is in hex.

The example template shows all of it, with the main colours, the wallpaper path, the numbered colours, and the RGB variants of the same:

```sh
background='%%background%%'
foreground='%%foreground%%'
wallpaper_path='%%wallpaper%%'
color0='%%color0.hex%%'
color15='%%color15.hex%%'
```

There is one extra variable beyond the colours, alpha, which sets a transparency value and is written inside the placeholder, as in a colour placeholder with an alpha parameter appended. The README notes that alpha is ignored for the single channel variants, which is the only sensible behaviour since a single channel has no alpha of its own.

The result is a file you can source from a shell configuration, which is why the output format is shell syntax with quotes around every value. The whole design assumes you will point it at your terminal emulator, your status bar or your window manager, and the template is the contract between the tool and each of those.

## Colour operations chain left to right on top of the palette

The newest part of the project is the operation syntax, and it is the feature that turns a palette generator into a palette editor.

A placeholder can carry a chain of operations, and the operations apply from left to right. The example in the README takes a colour, saturates it and lightens it and asks for hex, and another takes the background, applies sepia and contrast and asks for rgb with an alpha value. The point of the chain is that the base palette is not changed, only the value written into the template.

The operation set covers both colour spaces. On the HSL side there is saturate and desaturate, lighten and darken, and the absolute setters saturation and lightness, all taking a value between 0 and 1. On the hue side there is rotate by degrees in either direction, wrapping at 360, and complement, which rotates by 180. On the RGB side there is grayscale, which removes saturation while preserving lightness, invert, which subtracts each channel from 255, sepia with an amount, contrast, which scales around mid-gray, and brightness, which multiplies the channels.

The semantics are specified rather than left to guesswork, and three rules matter. Factors must be nonnegative and all arguments must be finite, with results clamped to the valid colour range after each operation. HSL adjustments add percentage points, so lighten with 0.2 adds twenty points of lightness, while the RGB filters work directly on sRGB channels. And a distinction is drawn between the relative operations and the absolute setters, so saturate and saturation are not the same thing.

Failure is quiet by design. An invalid operation expression warns and remains visible in the generated file, so a broken chain shows up as a broken template rather than as a silently missing colour. That is the right trade for a file you then source into your shell.

## Themes, and the careful rules of merging an image into one

A theme is a file of the same placeholder style as a template, but with fixed colours, and it is how you keep a known palette while still using the tool.

The README shows a gruvbox theme file, one line per colour from color0 to color15 with hex values, and you either copy it or take the one from the themes folder. Running the tool with a theme is a single argument:

```sh
hellwal --theme ./themes/gruvbox.hellwal
```

The recommendation is to keep themes in the default theme folder under the user's config directory, so a theme can be named rather than given as a path, and a different folder can be set when you want your own:

```sh
hellwal -t gruvbox.hellwal --theme-folder ~/dotfiles/configs/hellwal/themes
```

The interesting part is what happens when you combine an image with a theme. The override option copies image palette slots into the theme, so an image colour can replace the theme colour of the same name:

```sh
hellwal -i wallpaper.jpg -t gruvbox.hellwal --override-colors color1,color2,background
```

The rules around that are worth reading twice. The selectable slots are color0 through color15, plus background, which is color0, and foreground, cursor and border, which are all color15. Duplicate names are harmless, repeated options combine their selections, and an empty or unknown selector is an error rather than a silent no-op. The image colours are sorted and their bright variants prepared before copying.

Then there is the ordering, which is the subtle part. Without adjustment flags, the theme colours you did not select stay unchanged, and mixed mode does not automatically darken the palette. But the explicit modes, the inversion, the offsets, the grayscale, the static foreground and background and the contrast checks are applied to the whole merged palette afterwards, so they can also change colours you did not select. And the source theme is never rewritten.

Two more constraints: both the image and the theme arguments are required for an override, and with the random option only the image is chosen randomly while the specified theme stays fixed.

## JSON output, and the parts the tool leaves to you

There is a machine-readable mode, and it is a one-liner. The --json argument suppresses any other output and writes the colours to standard output in JSON, and the README shows the intended way to consume it:

```sh
hellwal -i [wallpaper] --json | jq '.'
```

That is the integration point for anything that is not a shell configuration file, and it is worth noting that the JSON contains the colours with the same naming scheme as the templates, including the wallpaper reference.

Beyond that, the scope is deliberately narrow. The tool reads an image, produces sixteen colours, and renders a template or a JSON document. It does not set your wallpaper, it does not talk to a terminal emulator, it does not preview anything, and it does not have a template language beyond the placeholders and the operation chains. Everything else is a shell script or a configuration file that you own.

That narrowness is a virtue for a tool you run from a cron job or a systemd timer, and it is also why the README is as long as it is. The operation semantics, the format table, the override rules and the JSON mode are all of the documentation there is, and they are specified tightly enough to be tested against.

One last detail about the state of the project. The last push came a month after the 1.0.8 release of 2026-09-15, and the release before that was in September 2025, so this is a small project with occasional bursts of work rather than a steady stream. The version lives in a VERSION file that the Makefile reads and stamps into the binary, which is a nice touch for a program that is often installed straight from a source checkout.

## Conclusion

Adopt hellwal if you want a theme that follows your wallpaper and you already work with pywal-style templates, because the sixteen slots, the placeholder syntax and the theme files are the same shape of idea, and the whole thing builds from one C file. Do not adopt it if you need a live preview, wallpaper setting or a template language beyond placeholders, because the tool stops at producing a rendered template file. Before you rely on it, check the placeholder names your existing templates use against the documented ones, and read the ordering rules for merging an image palette into a theme, because the adjustments are applied to the whole merged palette afterwards and can change colours you did not select.

## FAQ

### What is hellwal and how is it different from pywal?

Hellwal is a colour palette generator for wallpapers, described as Pywal-like but faster and written in C. The repository holds a single C source file, two headers and a vendored stb_image.h, and the Makefile builds it with warnings and optimisation on and only the maths library linked.

### How do I install hellwal?

The README lists three package routes, yay -S hellwal for the AUR, brew install hellwal for Mac and Linux, and the unstable channel of nixpkgs for NixOS with pkgs.hellwal in the system packages. From source it is a git clone and a make, with a C compiler and gnumake as the only requirements.

### What colour formats can a hellwal template use?

Placeholders are written between double percent signs, and the colour names can be followed by a format. The documented forms are hex, which outputs six characters without a hash, rgb, which outputs three comma separated numbers, and the r, g and b variants, which output a single channel. An alpha value can be appended and is ignored for the single channel forms.

### What colour operations can I chain in a hellwal template?

The operations apply from left to right without changing the base palette. They include saturate, desaturate, lighten, darken, the absolute setters saturation and lightness, rotate, complement, grayscale, invert, sepia, contrast and brightness, with the chain finished by hex, rgb, r, g or b and optionally an alpha value. Invalid expressions warn and stay visible in the generated file.

### How does hellwal merge an image palette into a theme?

The override option copies image palette slots into the theme by name, with color0 to color15 selectable and background, cursor and foreground treated as specific slots. The explicit adjustment modes are applied to the whole merged palette afterwards, so they can change colours you did not select, and the source theme is never rewritten. Both an image and a theme are required.

## Sources

- [danihek/hellwal on GitHub](https://github.com/danihek/hellwal)
- [Issues](https://github.com/danihek/hellwal/issues)
- [License: MIT](https://github.com/danihek/hellwal/blob/main/LICENSE)
- [README](https://github.com/danihek/hellwal/blob/main/README.md)
- [Releases](https://github.com/danihek/hellwal/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/danihek-hellwal
