Textorium is live on the App Store
Textorium is now available on the Mac App Store. It’s a native editor for people who write content for static site generators—Hugo, Jekyll, Eleventy. You point it at your project folder, it shows you all your posts in a table, and you can edit frontmatter and content without opening VS Code or remembering YAML syntax.
Here’s why this exists, what I learned building it, and where it’s going.
The problem: static sites are great until you have 600 posts
Static site generators solved a real problem. No database, no server logic, just markdown files and a build step. Hugo is fast. Jekyll has been reliable for years. Eleventy gives you control. If you’re technical, this model works.
But here’s what happens after you’ve been writing for a few years: you have 600 posts scattered across categories, dozens of tags you’ve used inconsistently, draft status flags you set and forgot about, and dates that reflect when you started writing something, not when you published it. Finding anything requires grep or opening files one by one in a text editor.
VS Code works if you treat your blog like a codebase. You get syntax highlighting, fuzzy search, Git integration. But the file tree on the left shows directory structure, not content metadata. There’s no table view sorted by date. No way to see “show me drafts published in 2024 tagged with ‘AI’ in the philosophy category.” You can script that with find and awk, or you could just admit that content management isn’t the same as code editing.
Web-based CMSs solve the wrong problem. They want to be the source of truth. Import your markdown, they’ll store it in their database, maybe sync it back to Git if you’re lucky. But the whole point of static sites is that files are the source of truth. You can grep them, version them, script against them, move them between machines without a sync process. A CMS that demands import/export breaks that model.
So: native Mac app, folder-based, file-first. That’s Textorium.
What it does
You open Textorium, point it at your Hugo or Jekyll project, and it shows you a table of all your posts. Each row: title, date, draft status, categories, word count. Click a post, the detail view loads. Left pane: frontmatter fields (editable). Right pane: content (editable in a WYSIWYG editor or raw markdown). Change the date, toggle draft, add a tag, edit the title. Hit Cmd+S. It writes the changes back to the markdown file.
No import. No database. The app doesn’t “manage” your content, it just gives you a better way to see and edit the files that are already there.
The table view is where this gets useful. You can sort by date (ascending or descending), title, or content type. Filter to show only drafts. Search across titles and content. Customize which columns are visible. The point is: you’re looking at your content as content, not as a directory tree.
The metadata panel is the other half. Hugo frontmatter can get complicated—dates, taxonomies, custom fields for layouts or archetypes. Textorium parses all of it, shows it as editable fields, and lets you add custom fields inline without touching YAML. You’re still editing markdown files, but you’re not thinking about YAML syntax.
Why native, why SwiftUI
I could have built this as an Electron app. Works on Mac, Windows, Linux. But Electron means shipping a Chromium runtime and a Node.js process to render a table and some text fields. That’s 200MB for a download and memory usage that climbs as you scroll.
SwiftUI gave me table views, split panes, file system access, and markdown rendering for about 8MB. The app launches instantly. It uses macOS’s native controls, so keyboard shortcuts work the way Mac users expect. Window management is automatic. Dark mode is free.
The tradeoff: macOS only. I’m fine with that. The people who run static sites on Macs deserve tools that feel like Mac apps. If there’s demand for Windows or Linux, the Rust TUI (more on that below) will handle that.
The sandboxing problem
Apple requires App Store apps to run in a sandbox. You can’t just read files from anywhere on disk—you have to ask for permission using security-scoped bookmarks. This is good security design. It’s also a pain if your entire app model is “point me at a folder and let me read all the markdown files.”
Here’s how it works: user picks a folder with the file picker. That interaction grants the app a security-scoped bookmark. The app saves that bookmark. Every time it needs to read files in that folder, it calls startAccessingSecurityScopedResource() first. When it’s done, it calls stopAccessingSecurityScopedResource().
Forget to call start, the app crashes. Forget to call stop, you leak resources. Nest the calls wrong, things break in subtle ways.
The other constraint: you can’t watch file changes using FSEvents directly inside a sandbox. So if you edit a post in Textorium, then edit the same file in another editor, Textorium won’t know unless you manually refresh. I added a refresh button. It’s not elegant, but it’s honest about what’s possible inside the sandbox.
I could have distributed outside the App Store (no sandbox, more freedom), but App Store distribution is how most people discover Mac apps now. The sandbox constraints are annoying but manageable.
The Rust TUI
While working on the Mac app, I kept thinking: what about people who live in the terminal? The Mac app is great for browsing and editing, but if you’re already in a terminal running hugo server, opening a GUI feels like context switching.
So I started building a Rust TUI. Same idea—shows you all your posts in a table, lets you edit metadata inline, saves back to disk—but in a terminal interface using ratatui and crossterm. No mouse, all keyboard. Vim-style navigation (j/k to move, Enter to edit, Ctrl+S to save).
The Rust version scans a Hugo site with 621 posts in 28 milliseconds. The original Python prototype took 1.2 seconds. That’s a 40x speedup, which matters when you’re running textorium as a quick check before committing changes.
I added search mode last week. Press /, type a query, posts filter in real-time as you type. Searches title, content, and categories. Press Enter or Esc to exit. It’s instant because Rust is fast, but also because the filtering logic is trivial—just substring matching on three fields.
Browser preview came next. Press o on any post, it constructs the preview URL based on your SSG type (Hugo uses localhost:1313, Jekyll uses 4000, Eleventy uses 8080), and opens it in your default browser. Assumes you’re running the dev server. Shows the URL in the status bar so you know if it’s wrong.
The TUI is in active development on GitHub, but it’s not yet distributed. Right now you need the Rust toolchain to build it (cargo install --path .), which means it’s only useful for developers comfortable with that workflow. That’s not sustainable for a general release.
The plan is to bundle the TUI binary inside the Mac app. Download Textorium from the App Store, you get both the GUI and the CLI. A menu item (“Tools → Install Command Line Tool”) would copy the binary to your PATH and handle setup. One download, both interfaces. That’s coming in a future version.
What’s interesting is that the Mac app and the Rust TUI solve slightly different problems. The Mac app is for browsing and editing when you want a visual interface. The TUI is for quick lookups and edits when you’re already in the terminal. They don’t compete—they complement. But only when the TUI is actually easy to install, which it isn’t yet.
What I learned
Files as source of truth is freeing. Every time I thought about adding a feature, I asked: does this require storing state outside the markdown files? If yes, I didn’t build it. No database. No cache files. No “sync” logic. The app reads what’s on disk, shows it, lets you change it, writes it back. That constraint kept the architecture simple.
Sandboxing is tedious but worth it. Yes, the security-scoped bookmark API is annoying. Yes, I spent hours debugging resource leaks. But the result is an app that Apple approved for the App Store without friction. And users get the confidence that the app isn’t doing anything weird with their files.
Speed matters for tools you use constantly. The Rust TUI is fast enough that I don’t think about its performance. It just responds. That’s the bar: if the tool is faster than your thought, it disappears. If it’s slower, you notice.
Building two versions in parallel surfaced tradeoffs. The Mac app has a nicer editing experience (WYSIWYG markdown, visual metadata panel). The TUI is faster to launch and more convenient if you’re already in the terminal. Neither is “better”—they’re optimized for different contexts. Building both clarified what each tool should prioritize.
Where this goes
The Mac app is v1.0. It does what I wanted: browse posts, edit frontmatter, edit content, save to disk. No Git integration yet, no multi-document tabs, no export to PDF. Those are possible future features, but I’m waiting to see what people actually need.
The Rust TUI needs distribution first. Right now it’s in the repo but requires Rust to build, which limits it to developers. The plan is to bundle the binary in the Mac app—download Textorium, get both GUI and CLI. Maybe as simple as a menu item that installs the command-line tool to your PATH. That makes it actually useful for terminal-first workflows.
After distribution is sorted, CLI commands are next. textorium new "Post Title" should create a new post with correct frontmatter for your SSG type. textorium publish should toggle the draft flag and update the date. textorium serve should spawn the dev server. Those are straightforward—most of the logic is already in the TUI, just needs to be wired up to CLI flags.
Notion integration is on the list too. The Python prototype had a quick-capture workflow: press a key, type an idea, it goes straight to a Notion database. That’s useful for “I just thought of something” moments when you don’t want to create a full post yet. Port that to Rust, maybe add it to the Mac app as well.
The bigger question is whether to expand to Jekyll and Eleventy more fully. Right now the app detects Hugo, Jekyll, and Eleventy based on config files, but the SSG-specific features (URL construction for preview, frontmatter archetypes) are mostly Hugo-focused. If Jekyll and Eleventy users want first-class support, that’s doable, just needs research into how those tools handle URLs and templates.
Also curious about iOS. The Mac app uses SwiftUI, which means the UI code could port to iPad with some adaptation. An iPad app for editing posts while traveling seems useful. But that’s a different product question: do people want to write long-form content on an iPad, or is that still laptop territory?
So: it’s out there
Textorium is on the App Store. You can download it, point it at your Hugo site, and see all your posts in a table. Edit frontmatter without touching YAML. Sort by date, filter by draft status, search by title. It’s fast, it’s native, and it doesn’t want to replace your filesystem.
The Rust TUI is being built alongside it—real-time search, browser preview, metadata editing, same core features but in a terminal interface. It’s not distributed yet (requires Rust to build), but the plan is to bundle it with the Mac app so one download gets you both. Terminal users shouldn’t have to choose between good UX and their preferred workflow.
I built this because I wanted it. I have hundreds of posts across several sites. VS Code is fine for editing one post, but terrible for browsing. Web CMSs want to own my content. File-based workflows feel right, but the tooling was missing.
Now it exists. Try it. If it clicks, great. If it doesn’t, that’s fine too—static sites don’t need another tool unless that tool solves a real problem.
For me, the problem was: “How do I see what I’ve written, navigate it like content, and edit it without leaving the file-based model?” Textorium answers that.
You can find it at textorium.app or on the Mac App Store.
That’s it. Go write something.
Featured writing
When your brilliant idea meets organizational reality: a survival guide
Transform your brilliant tech ideas into reality by navigating organizational challenges and overcoming hidden resistance with this essential survival guide.
Server-Side Dashboard Architecture: Why Moving Data Fetching Off the Browser Changes Everything
How choosing server-side rendering solved security, CORS, and credential management problems I didn't know I had.
AI as Coach: Transforming Professional and Continuing Education
Transform professional and continuing education with AI-driven coaching, offering personalized support, accountability, and skill mastery at scale.
Books
The Work of Being (in progress)
A book on AI, judgment, and staying human at work.
The Practice of Work (in progress)
Practical essays on how work actually gets done.
Recent writing
Dev reflection - January 25, 2026
I spent part of today watching a game fall apart in my hands. Not because it was broken—technically everything worked fine. It fell apart because I'd confused being clever with being usable.
Dev reflection - January 24, 2026
So here's something I've been sitting with lately. I spent the last couple days working across a bunch of different projects, and I noticed something strange. In almost every single one, the most i...
Notes and related thinking
From 11ty to Hugo: simplifying my blog stack
Simplify your blogging experience by migrating from 11ty to Hugo. Discover the benefits of faster builds and reduced dependencies for your site.
Understanding Redux Middleware '€” Medium
Master Redux Middleware to enhance your React applications and streamline state management with practical insights and tips from an experienced developer.
Shifting Your Development Environment from Ubuntu to OS X
Discover how to seamlessly transition your development environment from Ubuntu to OS X, enhancing productivity with powerful tools and features.