mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2026-08-24 10:14:12 -05:00
docs(blog): studio, native git and a leaner binary
Entire-Checkpoint: 69141334755a
This commit is contained in:
committed by
Jan De Dobbeleer
parent
7351cfcc31
commit
7e084f18de
@@ -0,0 +1,124 @@
|
||||
---
|
||||
date: 2026-08-03
|
||||
description: Studio now hands off to the Configurator, git status runs natively for a 10x speedup, and steady dependency cuts shrank the binary by nearly a third.
|
||||
tags:
|
||||
- studio
|
||||
- configurator
|
||||
- git
|
||||
- performance
|
||||
- streaming
|
||||
- binary-size
|
||||
title: "Studio, Native Git, and a Leaner Binary"
|
||||
slug: studio-native-git-and-a-leaner-binary
|
||||
authors:
|
||||
- name: Jan De Dobbeleer
|
||||
title: Maintainer
|
||||
url: https://github.com/jandedobbeleer
|
||||
image_url: https://avatars.githubusercontent.com/u/2492783?v=4
|
||||
---
|
||||
|
||||
A few changes landed recently that make Oh My Posh faster to run and easier to configure.
|
||||
Here's what's new: a live theme editor with a bridge to the Configurator, a native git
|
||||
integration, a background daemon that keeps your prompt warm, and a binary that keeps getting
|
||||
smaller.
|
||||
|
||||
<!--truncate-->
|
||||
|
||||
## Studio: edit your theme, live, in the browser
|
||||
|
||||
[`/docs/studio`](/docs/studio) now runs an actual build of Oh My Posh directly in your browser
|
||||
through WebAssembly. Change your config and the rendered prompt updates immediately. It renders
|
||||
against recorded sample data to make rendering every segment possible. There's no installation, no
|
||||
local config file, and no shell restart needed to see what a change looks like.
|
||||
|
||||
The editor understands your config the way an IDE understands code. It offers schema-aware
|
||||
autocomplete for every segment option, in both JSON and YAML, with inline documentation as you
|
||||
type. Config editing changes from "look up the docs, guess the property name, reload the prompt"
|
||||
into something closer to writing code with a linter looking over your shoulder.
|
||||
|
||||
If you're looking for a more drag and drop experience, **Open in Configurator** hands your config
|
||||
straight off to the full Configurator app. Shout out to [James Montemagno] for maintaining that
|
||||
awesome tool!
|
||||
|
||||
Studio and the Configurator aren't a linear path where one replaces the other. They're two
|
||||
different ways of working, and now you can move between them freely. If you want a fast,
|
||||
code-first way to tweak a theme, Studio's live text editing gets you there fastest. If you want
|
||||
a more visual experience, dragging segments around and arranging blocks instead of typing, the
|
||||
Configurator fits better.
|
||||
|
||||
## Shrinking the binary, release after release
|
||||
|
||||
A few versions ago, the Windows binary was a 19.6 MB download. The latest release is 14.0 MB, a
|
||||
28% drop. That didn't come from one big rewrite. It came from steadily replacing general-purpose
|
||||
third-party libraries with small, purpose-built internal code wherever the project only used a
|
||||
sliver of what a dependency offered. _This isn't a verdict on those libraries_: they're solid,
|
||||
popular projects. It's about matching the code shipped to the code actually used, since every
|
||||
user downloads them and loads all of it on every run.
|
||||
|
||||
Here's what that looked like in practice, measured on the same stripped linux/amd64 build each
|
||||
time:
|
||||
|
||||
| Dependency replaced | What it did here | Binary size saved |
|
||||
| --- | --- | --- |
|
||||
| `hashicorp/hcl/v2` + `zclconf/go-cty` | Parsed a Terraform block to read one attribute | -1.80 MB |
|
||||
| `bubbletea` + `bubbles` + `lipgloss` + `go-runewidth` | Font picker UI and Unicode width lookup | -1.32 MB (-7.8%) |
|
||||
| `spf13/cobra` + `spf13/pflag` | Command parsing and flag handling for the CLI | -586 KB |
|
||||
| `ini.v1`, `x/mod`, `jsonutil`, `google/uuid` | Config reads, a `go.mod` field, comments, ID generation | -266 KB |
|
||||
|
||||
Each of these libraries did its job well. It's just that they
|
||||
were general-purpose tools solving problems narrow enough to write directly, without carrying
|
||||
their surrounding framework along for the ride. A scanner that reads one field doesn't need a
|
||||
full HCL parser, and a numbered list doesn't need a terminal UI framework (even when it looks pretty).
|
||||
|
||||
Every pull request now gets an automated report comparing its release build against the latest
|
||||
published binary, per OS. The next dependency that quietly adds a few hundred kilobytes gets
|
||||
caught before it ships instead of accumulating unnoticed release after release.
|
||||
|
||||
## Native git status: what building our own integration buys you
|
||||
|
||||
The git segment traditionally works by spawning `git status --porcelain=2` and parsing its
|
||||
output. On Windows in particular, just spawning that process costs 22-25ms before git has even
|
||||
looked at a single file: roughly 70% of the segment's total render time.
|
||||
|
||||
The new `native_status` option skips the subprocess entirely. It reads the index, refs,
|
||||
gitignore rules, and object store directly, in-process, and computes the same status counts git
|
||||
would. Benchmarked head-to-head against the exec path, on real repositories:
|
||||
|
||||
| Platform | Repository | Native | `git status` (exec) |
|
||||
| --- | --- | --- | --- |
|
||||
| Windows | 1.1k files | 3.4 ms | 38 ms |
|
||||
| Windows | 12.5k files, 2k ignored | 12 ms | 47 ms |
|
||||
| Linux (ext4) | 1k files | 1.0 ms | 4.0 ms |
|
||||
| Linux (ext4) | 10k files, packed | 10 ms | 21 ms |
|
||||
|
||||
That's roughly a 10x speedup on Windows and a 2-4x speedup on Linux, on both small and large
|
||||
repositories. In practice, it's the difference between a git segment that's instant and one you
|
||||
can feel lag behind your typing, without changing anything about how you use git.
|
||||
|
||||
## A background daemon that keeps your prompt warm
|
||||
|
||||
The other big cost on every prompt render isn't rendering itself: it's the process start. Every
|
||||
prompt has, until now, meant launching a fresh `oh-my-posh` process from scratch. Streaming mode
|
||||
attacks that cost directly.
|
||||
|
||||
When you enable `streaming`, your shell starts a single background `oh-my-posh serve` process
|
||||
once, when the session opens, not once per prompt. That process stays alive for the life of your
|
||||
shell. It accepts render requests over a lightweight local channel and answers them without
|
||||
ever paying process-startup cost again. Segment caches stay warm in memory between prompts
|
||||
instead of being rebuilt from scratch, so the second prompt in a session is often faster than the
|
||||
first. On top of that, the prompt itself streams: segments that resolve quickly show
|
||||
immediately, and slower segments show a placeholder and repaint in place the moment their data
|
||||
lands, instead of the whole prompt waiting on the slowest segment.
|
||||
|
||||
Support today spans `powershell`, `zsh`, `fish`, and `cmd` (through Clink), each wired into that
|
||||
shell's own idioms for talking to a background process. Full docs are up at
|
||||
[Streaming][streaming].
|
||||
|
||||
## Why this matters
|
||||
|
||||
Together, these changes make the prompt itself lighter to download, faster to render, and easier
|
||||
to configure, with the tooling in place, like the binary size report on every PR, to keep it that
|
||||
way going forward.
|
||||
|
||||
[streaming]: /docs/configuration/streaming
|
||||
[James Montemagno]: https://montemagno.com
|
||||
Reference in New Issue
Block a user