Self-Host Your Color Schemes

Edward Wibowo,

theme repo preview

🌈 Theme Repo is a self-hosted repository for color schemes.

Theme Repo, a self-hosted application I recently developed, allows users to maintain a personal repository of color schemes. Color schemes are stored locally as TOML files on a server and fetched through a provided API. This API is also accessible through a provided web frontend.

I made Theme Repo out of a vain need to have a consistent color scheme among the applications I use daily. Whether that be my terminal emulator, browser, or status bar, I find it pleasing to see the same colors across different software. So, with Theme Repo, I can fetch my favorite themes to style applications on the fly.

Deploy Theme Repo

Theme Repo can be deployed using Docker. The latest images are on Docker Hub.

Using Docker-Compose:

version: "2.1"

services:
  theme-repo:
    image: claby2/theme-repo:v0.0.2
    container_name: theme-repo
    ports:
      - "3000:80"
    volumes:
      - ./themes:/usr/src/backend/themes
      - ./templates:/usr/src/backend/templates
    restart: unless-stopped

Run the container using:

docker-compose up -d

Features

Independent API

Theme Repo makes a clear distinction between the frontend and backend:

theme repo architecture

Due to having a separate backend, the provided frontend is purely optional; all of Theme Repo’s functionality is accessible through the backend API. Consequently, themes are retrievable by making API calls. Themes are just a curl away:

curl "https://themerepo.example.com/themes/a-very-cool-theme?template=json"

Themes are sourced from the themes/ directory on the server. Each theme is stored as a TOML file.

Theme TOML File

The following is an example of a color scheme file stored in TOML format:

background = "#000000"
cursor = "#ffa500"
foreground = "#ffffff"
color0 = "#000000"
color1 = "#800000"
color2 = "#008000"
color3 = "#808000"
color4 = "#000080"
color5 = "#800080"
color6 = "#008080"
color7 = "#c0c0c0"
color8 = "#808080"
color9 = "#ff0000"
color10 = "#00ff00"
color11 = "#ffff00"
color12 = "#0000ff"
color13 = "#ff00ff"
color14 = "#00ffff"
color15 = "#ffffff"
colorBD = "#ffffff"

Users can use the API to create custom frontends with custom logic. A frontend could range from a full-blown web application to a minimal shell script. The power is in the user’s hands.

For example, I currently use the Theme Repo API to query and change my Xresources theme using a simple shell script (xtheme):

#!/bin/sh

file="$HOME/.config/Xresources-theme" # location of Xresources file

theme="$1"
# NOTE: the following link is purely for example purposes
link="https://themerepo.example.com/themes/${theme}?template=xresources"

content=$(curl -f "$link") # call API

echo "$content" >"$file" # set contents of file to output of API call

Changing my Xresources theme is as simple as calling:

xtheme "name-of-the-theme"

Custom scheme formats

The backend not only serves themes but also converts themes into different file formats.

An annoyance I came across was that different applications had different ways of defining color schemes. For example, Alacritty stores themes as .yml, while kitty stores themes in a .conf format.

To solve this problem, Theme Repo’s templating system allows users to define custom scheme formats.

Templates are stored as files in the templates/ directory, where each template represents a custom file format. For example, an Xresources template (templates/xresources) might look like this:

! Generated with theme-repo
! Theme: {name}
*.foreground:  {foreground}
*.background:  {background}
*.cursorColor: {cursor}
*.color0:      {color0}
*.color8:      {color8}
*.color1:      {color1}
*.color9:      {color9}
*.color2:      {color2}
*.color10:     {color10}
*.color3:      {color3}
*.color11:     {color11}
*.color4:      {color4}
*.color12:     {color12}
*.color5:      {color5}
*.color13:     {color13}
*.color6:      {color6}
*.color14:     {color14}
*.color7:      {color7}
*.color15:     {color15}

By appending ?template=xresources to the API call, the color scheme will be automatically converted to Xresources format; {name} will be replaced with the theme’s name, {foreground} will be replaced with the theme’s foreground color, and so on…

So whatever the application is, Theme Repo can theme it.

Concluding Thoughts

Theme Repo was my first foray into building a full-stack, self-hosted application from start to finish. I learned how to write multi-stage Dockerfiles, publish images on Docker Hub, and integrate a React frontend with a Rust backend.

I thoroughly enjoy self-hosting various software, so I decided to contribute to the self-hosting community by making Theme Repo. I hope you like it! 🙂