{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "Andrew Embler — Posts",
  "home_page_url": "https://andrewembler.com/posts/",
  "feed_url": "https://andrewembler.com/posts/feed.json",
  "description": "Writing on software, technology, music and more. Published infrequently.",
  "language": "en",
  "authors": [
    {
      "name": "Andrew Embler",
      "url": "https://andrewembler.com"
    }
  ],
  "items": [
    {
      "id": "https://andrewembler.com/posts/the-elephant-in-the-room/",
      "url": "https://andrewembler.com/posts/the-elephant-in-the-room/",
      "title": "The elephant in the room",
      "summary": "In my last post I said I built my own CMS. It's time to fess up.",
      "image": "https://andrewembler.com/_astro/hero.BWFeT6Mf.jpg",
      "content_html": "<p><small>Photo by <a href=\"https://unsplash.com/@iswanto?utm_source=andrewembler_studio&amp;utm_medium=referral\">Iswanto Arif</a> on <a href=\"https://unsplash.com/photos/brown-elephant-cbNVRnlntZ8?utm_source=andrewembler_studio&amp;utm_medium=referral\">Unsplash</a></small></p><p>I have to come clean.</p>\n<p>In <a href=\"https://andrewembler.com/posts/moving-out-of-the-house-i-built/\">the first post in this series</a>, I wrote that the CMS I use now is “one I built myself, for exactly one user.”</p>\n<p>The “one user” part is true. The “built myself” part needs a bit of an asterisk. Almost every line of code behind this site and its editor was written by Claude.</p>\n<h2 id=\"but-why\">But why?!</h2>\n<p>It’s no secret that this personal blog fell into atrophy over the years. Work and life overtook whatever meager ambitions I had to be a blogger or a thought leader. When it came time to reconstitute this thing, I had a pretty strong vision, but I still didn’t have any more time than I used to.</p>\n<p>Claude has nothing but time. The funny part? With Claude involved it turns out I didn’t need much time after all:</p>\n<ul>\n<li><strong>Wednesday, September 30th.</strong> An empty static site, scaffolded on my Linux desktop.</li>\n<li><strong>About an hour later.</strong> A complete Astro blog: Keystatic for editing, search, generated social images, RSS, light and dark modes. It worked. I threw it out the next morning.</li>\n<li><strong>Thursday, October 1st.</strong> A content format spec, based on a design I’d mocked up in Claude Design.</li>\n<li><strong>That evening.</strong> Home page, post pages, thoughts, feeds, an About page, and view transitions that morph the thumbnail into the hero photo.</li>\n<li><strong>Later that night.</strong> Version one of the editor I’m typing into right now.</li>\n<li><strong>Friday, October 2nd.</strong> The first real post, published from that editor.</li>\n</ul>\n<p>So: a couple of days, from nothing to a designed, deployed blog with its own authoring app. The site and the editor are about 10,000 lines of source between them. I didn’t type most of them.</p>\n<p>Somewhere in there, I posted <a href=\"https://andrewembler.com/thoughts/2026-10-02-1908/\">a thought</a> that pretty much sums up the experience: watching a machine churn through your job in seconds really does a number on the ol’ imposter syndrome.</p>\n<h2 id=\"so-what-did-i-do\">So what did I do?</h2>\n<p>Mostly, I decided things. It’s actually not that surprising: as the core team leader of Concrete CMS I have been making decisions around software for many years, especially around code I didn’t write. That turns out to be most of the job.</p>\n<p>I decided the content should be plain Markdown files in folders. I decided each post’s colors should come from its hero photo. I decided the first version wasn’t right, even though it worked, and started over. I decided we also needed a lightweight CMS “Studio” that could help me edit even when a Markdown editor wasn’t handy.</p>\n<p>And I tested. A lot. The Safari bugs alone (a white flash between pages, a stutter after the photo animation) took a few rounds of “no, still broken, here’s what I see” before they were really fixed. None of that is typing. (Which is a pity, because that’s still a skill I’m good at.)</p>\n<h2 id=\"the-editor-has-claude-in-it-too\">The editor has Claude in it, too</h2>\n<p>When I start a post, I can have it draft a title and description. It suggests alt text for photos. It can tighten, expand or rephrase a paragraph. And there’s a little robot in the corner of every post, which I named BeBot, that I can chat with about the draft. It proposes edits as diffs. It’s very good at fixing typos and grammar mistakes that I make when I’m frantically churning through a post.</p>\n<p>And while we’re airing all of our dirtiest laundry: I like this. I like it a lot. It turns out that I really hate the imposing nature of a blank page. If I can have an LLM give me the world’s clunkiest first draft of something, I’ll take it. The earliest, firstest of passes on this topic came from Claude; I gave it the title and one sentence about what the post was about, and it read the first post, dug through the git history, and was off to the races. But what you’re reading now bears little resemblance to it.</p>\n<h2 id=\"does-it-mean-anything\">Does it mean anything?</h2>\n<p>I’m not going to pretend I have this figured out. I lead an open source project whose whole reason to exist is helping people build websites, and I just built one in a day without really writing it.</p>\n<p>What I know is that the site is better than anything I would have built by hand, because I wouldn’t have built <em>anything</em> by hand. I had years to do it and didn’t. The friction was the problem, and that friction is gone.</p>",
      "date_published": "2026-10-03T03:25:00.000Z",
      "tags": [
        "Rebuilding this site"
      ]
    },
    {
      "id": "https://andrewembler.com/posts/im-optimistic-about-the-blazers-anyway/",
      "url": "https://andrewembler.com/posts/im-optimistic-about-the-blazers-anyway/",
      "title": "I'm optimistic about the Blazers anyway",
      "summary": "Tom Dundon has spent his first six months cutting staff, skipping playoff T-shirts and eyeing the exits. I'm not gonna let that bring me down.",
      "image": "https://andrewembler.com/_astro/hero.D1oYUhM5.jpg",
      "content_html": "<p>I can’t help it. I’m excited about this Blazers season.</p>\n<p>Not “excited, but.” Just excited. How can you not be, when we get to experience “Dame Time” again? And <a href=\"https://www.nba.com/blazers/news/portland-trail-blazers-acquire-two-time-nba-all-star-ja-morant\">that’s not even the wildest part about the Blazers’ off-season</a>!</p>\n<h2 id=\"the-dundon-conundrum\">The Dundon Conundrum</h2>\n<p>The Blazers’ sale to Tom Dundon closed this March. Six months in, here are the highlights so far:</p>\n<ul>\n<li>About 70 employees were laid off in May. His explanation was that fewer layers of management means more accountability.</li>\n<li>During the playoffs, the team’s two-way players weren’t allowed to travel for the first two games in San Antonio. He has since called that a mistake.</li>\n<li>There were no free T-shirts for home playoff games, which most playoff teams hand out. His take was that T-shirts don’t have anything to do with winning, and that fans weren’t focused on the right things. (<em>Note: I actually agree with this; please don’t yell at me.</em>)</li>\n<li>The broadcast crew was gutted. It sounds like longtime pro Kevin Calabro was also treated pretty shoddily at the time. Truly cringeworthy stuff.</li>\n<li>Tiago Splitter, who took over as interim coach and got the team into the playoffs, wasn’t brought back. His replacement, Micah Nori, got a three-year deal with only the first year guaranteed.</li>\n<li>And the biggest elephant in the room: Dundon wants roughly $600 million in public money for arena renovations, without committing his own, and moving the team is the unspoken alternative.</li>\n</ul>\n<p>None of that is illegal. But a basketball team isn’t only a business. It’s one of the few things a whole city shares. When the owner treats free T-shirts as waste, he’s telling you how he sees the people wearing them.</p>\n<p>Yes, a lot of this is just how a certain kind of businessman runs things. But I don’t love it.</p>\n<h2 id=\"the-team-on-the-floor\">The team on the floor</h2>\n<p>Here’s the thing, though. Last season the Blazers went 42-40, got through the play-in, and took a game from the Spurs in San Antonio before losing the series in five. That was with <a href=\"https://www.justice.gov/usao-edny/pr/31-defendants-including-members-and-associates-organized-crime-families-and-national\">an unexpected coaching change</a> at the start of the season, Damian Lillard on the sidelines the entire time, rehabbing a torn Achilles, and Scoot Henderson gone for most of the year.</p>\n<p>The people who made that happen are mostly still here:</p>\n<ul>\n<li><strong>Deni Avdija</strong> became the best player on the team. He’s not a prospect anymore.</li>\n<li><strong>Donovan Clingan</strong> led the league in offensive rebounds, at 4.5 a game.</li>\n<li><strong>Toumani Camara</strong> drew more offensive fouls than anyone in the NBA, 106 of them. That stat tells you exactly what kind of player he is.</li>\n<li><strong>Jrue Holiday</strong> is still a pro.</li>\n</ul>\n<p>Then add the backcourt. Lillard is back, healthy, in a Blazers jersey again. And the team traded Jerami Grant and Kris Murray to Memphis for Ja Morant, which is not a sentence I expected to type a year ago.</p>\n<h2 id=\"why-im-not-worried-much\">Why I’m not worried (much)</h2>\n<p>Yes, I am bummed about the loss of Shaedon Sharpe. Yes, the Blazers’ guard rotations are still mysterious and loaded with small defensive liabilities. This is the team’s third head coach in less than twelve months.</p>\n<p>Yahoo Sports projects them at 34-48, which would be a step backward. I’ve watched a lot of Blazers teams that were safe bets to be mediocre. This one isn’t safe. The Nori hire could be great. Portland has a <a href=\"https://www.blazersedge.com/2021/5/1/22414460/ten-time-all-star-carmelo-anthony-shines-bench-role-portland-trail-blazers\">knack for rehabilitating faded stars</a>. The defense might be a problem. The games won’t be boring.</p>\n<h2 id=\"dont-hate-the-players-hate-the-game\">Don’t hate the player(s), hate the game</h2>\n<p>Portland fans are a persnickety bunch. We’re gonna find something to have a problem with. Am I worried about the existential future of the Blazers at the hands of an owner whose relationship with the region is <em>complex</em> at best? Of course. But I can’t do anything about that. What I can do is appreciate the greatest Blazer of all time coming back for one more go-round. Who doesn’t want to see that?</p>",
      "date_published": "2026-10-03T02:02:56.000Z"
    },
    {
      "id": "https://andrewembler.com/posts/moving-out-of-the-house-i-built/",
      "url": "https://andrewembler.com/posts/moving-out-of-the-house-i-built/",
      "title": "Moving out of the house I built",
      "summary": "I co-founded Concrete CMS. I'm still its core team leader. But this blog doesn't run on it anymore. Does that feel strange? You bet.",
      "image": "https://andrewembler.com/_astro/hero.1w0LN6EF.jpg",
      "content_html": "<p><small>Photo by <a href=\"https://unsplash.com/@joshhild?utm_source=andrewembler_studio&amp;utm_medium=referral\">Josh Hild</a> on <a href=\"https://unsplash.com/photos/brown-wooden-house-surrounded-by-green-trees-during-daytime-6kVGxIHriTA?utm_source=andrewembler_studio&amp;utm_medium=referral\">Unsplash</a></small></p><p>This site doesn’t run on Concrete CMS anymore.</p>\n<p>That’s a strange sentence for me to write. When we first open sourced Concrete in 2008, I couldn’t wait to use it on my own website. This blog has run on it in one form or another ever since. (At least for a while: after 2017, I mostly let the place atrophy. For crying out loud – I never even put it behind SSL!)</p>\n<p>It made sense: at its height Concrete CMS (then named concrete5 – yep, that’s right, with a lowercase “c”) powered hundreds of thousands of websites of many sizes, across many verticals. We needed to eat our own dog food! When something broke in Concrete, I often found out here first.</p>\n<p>But today, the site is a folder of Markdown files, built into static HTML and served from Cloudflare. The CMS I write in is one I built myself, for exactly one user.</p>\n<p>It’s bittersweet.</p>\n<h2 id=\"this-isnt-a-breakup\">This isn’t a breakup</h2>\n<p>I want to get this out of the way first: if you’re running a content-heavy site with a bunch of people who need to manage it, Concrete CMS is still the tool I’d reach for. Lots of pages, lots of editors, different people allowed to touch different things: that’s exactly the job it was built to do. The original vision of “see a typo, fix a typo” right from the page? It still delivers on that, and we are privileged to still have a group of extremely passionate, knowledgeable, prolific and talented developers working with our open source project.</p>\n<p>But my blog has none of those problems. It has one author. I’m a developer, and happiest in a <a href=\"https://www.barebones.com/products/bbedit/\">text editor</a>. Most of what Concrete is good at, I wasn’t using. At PortlandLabs we work hard to ensure our tech stack is kept up to date, but I definitely did not apply the same rigor to my personal DigitalOcean droplet: as it became annoying to keep everything updated, I let that friction keep me from posting, and it wasn’t long before my blog was a ghost town.</p>\n<h2 id=\"what-i-wanted-instead\">What I wanted instead</h2>\n<h3 id=\"plain-files\">Plain files</h3>\n<p>Every post is a Markdown file, with its images in the same folder. The whole site lives in git. It sounds small, but it changes what owning the site feels like. I can search the whole archive with BBEdit. And if every tool I use today goes away, I’ve still got a folder of text files that pretty much any computer can open. And metadata can just live in the post alongside the content:</p>\n<figure class=\"code\"><pre class=\"code-body\" data-lang=\"yaml\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:var(--code-fg)\">---</span></span>\n<span class=\"line\"><span style=\"color:var(--code-str)\">title</span><span style=\"color:var(--code-fg)\">: </span><span style=\"color:var(--code-str)\">\"Moving out of the house I built\"</span></span>\n<span class=\"line\"><span style=\"color:var(--code-str)\">date</span><span style=\"color:var(--code-fg)\">: 2026-10-02</span></span>\n<span class=\"line\"><span style=\"color:var(--code-str)\">dek</span><span style=\"color:var(--code-fg)\">: </span><span style=\"color:var(--code-str)\">\"I co-founded Concrete CMS. I'm still its core team leader. But this blog doesn't run on it anymore. Does that feel strange? You bet.\"</span></span>\n<span class=\"line\"><span style=\"color:var(--code-str)\">heroAlt</span><span style=\"color:var(--code-fg)\">: </span><span style=\"color:var(--code-str)\">\"Brown wooden house surrounded by green trees during daytime\"</span></span>\n<span class=\"line\"><span style=\"color:var(--code-str)\">heroCredit</span><span style=\"color:var(--code-fg)\">:</span></span>\n<span class=\"line\"><span style=\"color:var(--code-str)\">  name</span><span style=\"color:var(--code-fg)\">: </span><span style=\"color:var(--code-str)\">\"Josh Hild\"</span></span>\n<span class=\"line\"><span style=\"color:var(--code-str)\">  url</span><span style=\"color:var(--code-fg)\">: </span><span style=\"color:var(--code-str)\">\"https://unsplash.com/@joshhild?utm_source=andrewembler_studio&#x26;utm_mediu></span></span>\n<span class=\"line\"><span style=\"color:var(--code-str)\">  source: \"Unsplash\"</span></span>\n<span class=\"line\"><span style=\"color:var(--code-str)\">  sourceUrl</span><span style=\"color:var(--code-fg)\">: </span><span style=\"color:var(--code-str)\">\"https://unsplash.com/photos/brown-wooden-house-surrounded-by-gree></span></span>\n<span class=\"line\"><span style=\"color:var(--code-str)\">series: \"rebuilding-this-site\"</span></span>\n<span class=\"line\"><span style=\"color:var(--code-str)\">seriesPart</span><span style=\"color:var(--code-fg)\">: 1</span></span>\n<span class=\"line\"><span style=\"color:var(--code-str)\">draft</span><span style=\"color:var(--code-fg)\">: </span><span style=\"color:var(--kw)\">true</span></span></code></pre></figure>\n<h3 id=\"no-server-to-babysit\">No server to babysit</h3>\n<p>A static site has no PHP to update or database to back up. Static HTML will always be the fastest, most secure way to host a website. We employ talented DevOps folks to do this; it was never something I was interested in or particularly skilled at. I’m glad I can now delegate that problem to Cloudflare!</p>\n<h3 id=\"a-modern-elegant-experience\">A modern, elegant experience</h3>\n<p>This last part is the toughest part to admit: my blog had grown stale, and I didn’t really want to improve it. I had ideas about a design that adapted to the colors present in imagery, but I couldn’t justify the amount of time it would take to achieve it. Yes, you can (and always have been able to) build anything in Concrete, but at some point the idea of clicking on images and micro managing content just for a post struck me as just too fiddly. <strong>For a personal blog, it was too much management and not enough content</strong>.</p>\n<h2 id=\"a-cms-built-for-one-person\">A CMS built for one person</h2>\n<p>This is the part I’m most excited about.</p>\n<p>Every general-purpose CMS has to make compromises. Concrete makes them on purpose, and I’ve spent a long time defending those choices. A CMS has to work for a church, for a university, for a law firm, and for someone’s band. Concrete has always been powerful and flexible, because it had to be.</p>\n<p>But mine doesn’t. It does what I want and nothing else. No, it’s <em>definitely</em> not built in a vacuum: this site runs on the great work done by <a href=\"https://astro.build/\">Astro</a>, alongside a custom CMS named… you know what? It doesn’t even have a name! I think we’re finally post-product, here.</p>\n<p>When I want a new feature, I add it. When I stop using one, I delete it. There are no packages to update, and no users dependent on something I must decide I no longer want to support. The only person I have to argue with is me (and I usually lose.)</p>\n<p>For years, I’ve been building software meant to work for everyone. It’s an interesting feeling to build something that only has to work for me.</p>\n<figure class=\"figure\"><img src=\"https://andrewembler.com/_astro/image.BB1ohIrI.png\" alt=\"CMS editor\"><figcaption>Studio, the CMS for one behind this blog.</figcaption></figure>\n<h2 id=\"the-weird-part\">The weird part</h2>\n<p>I’ve spent 20 years telling people that a good CMS lets you focus on content instead of infrastructure. And here I am, having built my own infrastructure so I could focus on content.</p>\n<p>The right tool depends on who’s holding it. For an organization with editors, a CMS like Concrete takes away a pile of problems. For one developer with a blog, some of the problems were the CMS itself. Sometimes all you need is a folder full of files.</p>\n<h2 id=\"whats-next\">What’s next</h2>\n<p>If you’re reading this, you can safely assume that I succeeded!</p>\n<p>If you’re still using Concrete CMS – thank you! Don’t forget to update to 9.5.5 next week! Concrete powered this site for a long time, and I’m grateful for that. It just doesn’t need to anymore.</p>",
      "date_published": "2026-10-02T23:54:00.000Z",
      "tags": [
        "Rebuilding this site"
      ]
    }
  ]
}