The Tiling Window Manager for Windows
The Tiling Window Manager for Windows
One of the great things about building your own tools is that you get to have your desired workflow and user experience with very few compromises. I built Notado because I wanted an archiving and highlighting workflow which treated online comments as first class citizens. I built Kullish because I wanted to be able to quickly aggregate comments about links from a variety of different online communities. I built komorebi because I wanted a tiling window manager for Windows. Since starting to build komorebi in 2020, the project has grown beyond my wildest expectations, with over 200k downloads and a thriving online community today. Komorebi came from a desire to improve my Windows experience as a macOS + yabai user. Now, from a desire to improve my macOS experience to match the experience of using Windows + komorebi, I am building komorebi for Mac. I aim to be able to share a single komorebi configuration file across both Windows and macOS and have a virtually indistinguishable tiling w…
When you have software out in the wild being used by lots of people, it's inevitable that there will be pretty large spread across the versions of your software being used. If that software is aimed towards technical folks and power users, or if you publish nightly releases, in addition to the spread across official version releases, you will also have many people running on any number of commit hashes. It has been very valuable for me to have commit information available when a user runs my software on Windows with the --version flag as this allows me to quickly narrow down if a reported issue has already been addressed in the current stable or nightly release. I have done this using the excellent shadow-rs crate, which queries various git information at build time, and provides a convenient CLAP_LONG_VERSION which can be used when building a CLI with clap to provide detailed build information. komorebi 0.1.38 branch:master commit_hash:21cb5e1e build_time:2025-06-10 00:26:27 +02:00 b…
LGUG2Z
I made $901.49 in my first month selling commercial use software licenses. This $901.49 came from 14 customers, 6 of whom purchased monthly license subscriptions and 8 of whom purchased annual license subscriptions. January 2025 sales overview My most popular piece of software, komorebi, is a tiling window manager for Windows, published under an educational source license which does not permit any kind of commercial use. At the beginning of 2025, I started offering dedicated individual commercial use licenses for people who want to use it at work. These are the main steps that I took in January to disseminate information about the new license: I run a community Discord server centered around komorebi with almost 2000 members - I pinged @everyone with a launch announcement, which was positively received In the release overview video for komorebi v0.1.32 I dedicated a section to introduce the license to …
If you dual-license your software in such a way that it requires a paid license for commercial use, here are two code blobs for you. macOS pub fn mdm_enrollment() -> eyre::Result<(bool, Option<String>)> { let mut command = Command::new("/usr/bin/profiles"); command.args(["status", "-type", "enrollment"]); let stdout = command.output()?.stdout; let output = std::str::from_utf8(&stdout)?; if output.contains("MDM enrollment: No") { return Ok((false, None)); } let mut server = None; for line in output.lines() { if line.starts_with("MDM server") { server = Some(line.trim_start_matches("MDM server: ").to_string()) } } Ok((true, server)) } Windows pub fn mdm_enrollment() -> eyre::Result<(bool, Option<String>)> { let mut command = Command::new("dsregcmd"); command.args(["/status"]); …
Building for macOS has been... interesting. After falling into the trap of Microsoft's 10x price gouging for macOS runners on GitHub Actions and ultimately switching to using the Mac Mini under my television as a self-hosted runner, the next thing I wanted to do was distribute my build artifacts. I'm trying a different approach to building a new project this time around. Maintaining a popular piece of software is very draining, and working on a much-requested port of a popular piece of software to another operating system was not something I wanted to do in public. So I'm building in private until I'm ready for an initial public release, and as a bonus, I finally have something concrete to offer to people who sponsor me on GitHub (early access). Homebrew is, for better or worse, the most popular package manager on macOS and it can only be avoided for so long. After setting up nightly builds on GitHub Actions, I wanted to create a Homebrew Tap and Formula for people who sponsor me on G…
Last year I read the excellent article
There are a number of different approaches available for NixOS users to handle secrets. The most popular tend to be git-crypt, agenix and sops-nix. But which one should you use? To hopefully help you in answering this question for yourself, here is an overview of a few common use cases and what I think is most appropriate for each. Managing Your Own Physical Machines Maybe you have a desktop, a Macbook and a Raspberry Pi which you are managing from a single NixOS flake repo. Maybe you even have a NixOS dedicated server somewhere running in a datacenter which functions as your media server running Plex or Jellyfin. If you are primarily using NixOS on your own physical machines, used exclusively by you, and you want to be able to publish your flake repo publicly, I think you can get pretty far with git-crypt. I have been a happy user of git-crypt for a long time, even before I started using NixOS, and naturally it was my first instinct to use when setting up my own configuration flake re…
I have a confession to make. Until yesterday, I did not have any form of dotfiles management or versioning for my Windows 11 machine. Yes, I, the person who wrote an entire tiling window manager for Windows from scratch in Rust, did not manage my dots. I had to sheepishly admit this on more than one occasion in the project Discord server when people would watch my live programming videos and then ask if I could share my Windows dotfiles repo. I became a full time NixOS user earlier this year. I tried running it as my main OS for a few months, but the Linux desktop experience still leaves a lot to be desired, and one of the downsides of writing a tiling window manager that does everything that you want it to do exactly the way you want it to do it, is that going back to other tiling wms that you thought were great before becomes harder. So I settled on running Windows 11 with komorebi as my
I came across an interesting thread on the NixOS subreddit today that helped me fix a problem that I didn't even know I had with my NixOS system configuration. Every now and then, I'll try to quickly do nix-shell -p somepackage, and it will fail, because somepackage couldn't be found. I go and check https://search.nixos.org and it's there. Huh. Weird. So I just go and add it to my environment.systemPackages to install it, and remove it if it turns out I don't really need it. This alternative step works because my system configuration flake is pointing to a different version of nixpkgs than the nix-shell command. So what's the solution? Let's make nix-shell use the same version of nixpkgs as the system configuration flake! {inputs, ...}: { nix = { registry = { nixpkgs = { flake = inputs.nixpkgs; }; }; nixPath = [ "nixpkgs=${inputs.nixpkgs.outPath}" "nixos-config=/etc/nixos/configuration.nix" "/nix/var/nix/prof…
Last October, Plex started blocking access to instances running on servers hosted by Hetzner. I have a Hetzner Auction server that I renew every year or so to make use of newer hardware, which I use to run various workloads, from web services, to scheduled jobs and self-hosted instances of privacy-friendly alternative web frontends like Nitter. Another one of those workloads, until recently, was Plex. I didn't have the time to put too much effort into getting around the Hetzner network ban when it was first implemented, so I just started running Jellyfin instead. I even made a video demonstrating how easy it was to get Jellyfin up and running on a VPS. The Initial View from Europe Since getting laid off I finally had some time to try and think about how to get Plex working again. My circumstances have changed since I first started hosting Plex back in the early 2010s: I no longer travel for work (previously, I was an ICRC field delegate and later, for a time, a software development co…
Before this week, it had been a long time since I visited the Plex subreddit. I shared my last article there, which was a technical write-up of moving my Plex instance from a Hetzner auction server to a virtual machine running on hardware in my home network, and the considerations that influenced the migration. It didn't take long for me to realize that a culture of hostility towards even the mention of Hetzner or other cloud hosting providers has strongly taken root since Plex announced it's blanket network ban on IP ranges associated with Hetzner data centers. I saw many posts and comments of users asking about issues with their Plex instances that had for years been working without issue on Hetzner servers until this past October when Plex enacted their very poorly communicated network ban, which hit a significant number of customers like myself who had paid for a lifetime Plex Pass. Although I myself am not pursuing this option for reasons outlined in my last article, I wanted to s…
For the most part I feel very much at home on the Hachyderm Mastodon server; it's probably the best social media experience that I can remember having and I have had the pleasure of interacting with so many cool and impassioned people there. Hachyderm implements the default 500 character post limit which is hard-coded into the Mastodon codebase and as of writing these, seems unlikely to ever be made configurable. Every now and then, especially when adding summaries to long (1hr+) live programming videos that I share across the Fediverse, I come up against that limit. At the end of last year, I had an idea: Why don't I just self-host my own Mastodon instance that allows for posts that are longer than 500 chars, make longer posts on that account, and then boost them from my main account on Hachyderm? Sounds easy, right? Well... Using my domain I wanted to be able to use my current domain so that I could be looked up as @jeezy@lgug2z.com. This is actually quite well documented and can be …
I have tried running the Attic Nix Binary Cache on my Hetzner dedicated server in Germany a few times in the past, but the peering issues and the latency to Xfinity in Seattle have always made me throw my hands up in frustration. This morning I noticed a comment by Zhaofeng on the repo issue tracker. As a NixOS aficionado myself, I begrudgingly admit that I've been running my instance on fly.io 😛 I'm not sure if this is comment is still current, but hey, if Zhaofeng is/was running his binary cache on fly.io, there's no reason why we can't too, right? Storage While Attic does support local storage, I figured I'd use Cloudflare's R2 as a storage backend, both as an excuse to try out the free tier (10GB), and because it'll be easy enough to lift-and-shift if I ever decide to move the server from fly.io. It's easy enough to create a new R2 bucket and grab a read-write API token scoped to the bucket on the Cloudflare Dashboard. Server Configuration Once we have our credentials, we can put…
In the previous article we walked through how to set up our very own Nix binary cache. It's great being able to run attic push system /run/current-system on whichever machine we are currently using, but the the chances are that if you use Nix to manage your system configurations, you have a system configuration monorepo, and depending on how many machines and architectures you are targeting, it can quickly become tiresome to manually push to the cache from each of them. My configuration repo presently has 4 targets: NixOS VM that runs on WSL (x86_64) Bare metal Hetzner server (x86_64) Raspberry Pi running in my home network (aarch64) Production instance of https://notado.app (x86_64) Building NixOS system configurations NixOS system configurations are essentially build artifacts. Since they are build artifacts, it makes sense to build, cache and push them in CI pipelines, right? Right! Although GitHub Actions is awful, it can be made siginificantly less awful by installing Nix immedi…
A few weeks ago I ran nix flake update to get the latest versions of CLI tools that I regularly use from nixos-unstable. atuin is one of those tools which I started using relatively recently and quickly became a huge fan of. I run it on all of my machines, and I can't overstate how amazing it is to have all of my shell history across all of my machines synced. I also self-host the atuin server, because why not? While I typically install my CLI tools from nixos-unstable, with services that I self-host I tend to be a little more conservative and run them from the latest stable release, which is currenly nixos-23.11. The atuin CLI tool had some database migrations as part of the v18 release that made it incompatible with servers running v17, which is what my self-hosted atuin server is running from nixos-23.11. Usually this would be a non-issue since most service modules in Nixpkgs have a package option that lets you override the package used for a service. However, unfortunately for the …
Certainly, no contributors get into projects with the sole purpose to get a financial gain out of them. Open source has never been about money either. But for you as an author, the lack of funds to sustain your ideas and pay for even a small portion of the time you're spending on them is—I'm not going to lie—devastating. It may not be your concern at first but it will inevitably become one when your ideas gain popularity, demanding significantly more time than there are hours in a day. Source In 2023 I received $593.02 in sponsorships via GitHub Sponsors for my work on komorebi, the tiling window manager for Windows, which has continued to grow beyond my wildest dreams; it currently has 6.5k stars on GitHub, 57k downloads and almost 1000 members in the community Discord. Below is the monthly breakdown of the sponsorships received last year: MonthPayout January$27.61 February$26.77 March$35.71 April$81.00 May$46.00 June$32.00 July$31.00 August$33.32 September$52.83 October$66.37 Nove…
Earlier this week I saw an Ask HN post titled
The big mistake Using Tailwind CSS for Notado is the single biggest mistake I have ever made in my career as a developer. I cannot overstate the amount of technical debt that this has introduced, and how it has compounded over the years since this decision was taken. Never use this for a one-man SaaS project. One of the biggest consequences of this mistake was that introducing dark mode immediately became a non-trivial task, especially when compared to Kullish, where I had the good sense to use Bulma, and adding dark mode was the simple case of adding a single link element to my existing base HTML template: <link href="https://unpkg.com/bulma-prefers-dark" rel="stylesheet" type="text/css"/> I'm not really interested in LLMs to help me write code I personally have not had much use for LLMs while writing code, and I definitely don't want LLM-powered code suggestions integrated into my text editor. This would remove a significant part of the
In 2024 I received $1861.88 in sponsorships via GitHub Sponsors for my work on komorebi, the tiling window manager for Windows, which has continued to grow beyond my wildest dreams; it currently has 10k stars on GitHub, 106k downloads and almost 2000 members in the community Discord. Below is the monthly breakdown of the sponsorship payouts received in 2024: MonthPayout January$92.35 February$115.48 March$143.03 April$150.30 May$188.39 June$158.49 July$122.83 August$144.12 September$179.28 October$116.09 November$229.00 December$222.52 In the post covering 2023, I wrote: It's unlikely that I'll hit the $100 minimum payout threshold on the channel in 2024, but technically, the work I put into the YouTube channel in 2023 has opened the possibility for users to financially support the project in a passive way by subscribing to the channel and watching videos. In February 2024 my YouTube channel became monetized. I have continued posting live development and release overview videos to …
After reaching my limit with Hugo's constant breaking changes, I switched to Zola. As part of that migration, I decided to stop writing and fixing shortcodes for other websites, and instead just wrote a single shortcode to reference comments, highlights and quotes directly from my knowledge base
XML namespaces in RSS feeds might not be getting deserialized the way you think they are...
Don't you hate it when you can't publish a new blog post because something is wrong with another website?
In which the same code produces frustratingly different results on macOS Sequoia and macOS Tahoe.
Cross-compilation is just the tip of the iceberg
For the past two years (2023, 2024) I have been sharing annual sponsorship breakdowns for komorebi. komorebi is published under the Komorebi License (building on the foundation laid by the PolyForm Project), an educational source license which does not permit any kind of commercial use. In January 2025 I introduced the long-requested Individual Commercial Use License (ICUL), which will also be factored in to this year's financial breakdown. The Numbers In 2025 I received $12,070 for my work on komorebi. SourceTotalSubscribers (EOY) ICUL$787795 GitHub Sponsors$362967 Ko-Fi$3584 YouTube$2066328 GitHub Sponsors Within a couple of months of the availability of the ICUL, the number of license holders had surpassed the number of GitHub Sponsors, and this trend shows no sign of reversing. Generally I am happy with this because I would much rather that the majority of funding for komorebi come from corporate expense reimbursements than the salaries of workers. In the last quarter of 2025 I st…
In which I give you yet another reason to ignore the naysayers