This is a valid RSS feed.
This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.
line 81, column 244: (12 occurrences) [help]
... umentation is great</a>.</p></description><pubDate>Mon, 03 N ...
^
<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Peterbe.com</title><link>http://www.peterbe.com/rss.xml</link><description>Stuff in Peter's head</description><atom:link href="http://www.peterbe.com/rss.xml" rel="self"/><language>en-us</language><lastBuildDate>Mon, 03 Nov 2025 16:40:49 +0000</lastBuildDate><item><title>Hosting your static web site with Firebase Hosting</title><link>http://www.peterbe.com/plog/hosting-your-static-web-site-with-firebase-hosting</link><description><p><a href="https://firebase.google.com/docs/hosting">Firebase Hosting</a> is a part of <a href="https://firebase.google.com/">Firebase platform</a>, the integrated real-time database, cloud functions, app auth, etc. But you can use just the Hosting feature.</p><p>Suppose you have a single-page app that builds a complete site with <code>index.html</code> and <code>index-63gsxn38.css</code> etc. All the files you need for static hosting. There are many options for hosting and exposing these via CDN such as Netlify, AWS S3 + CloudFront, Vercel, or your own Nginx server. But this guide is focussing on Firebase Hosting.</p><p>In my case, I can run <code>bun run build</code> and then the <code>./dist/</code> directory has everything. It has a <code>/index.html</code>, some <code>.css</code>, some <code>.js</code>, some <code>favicon.svg</code>, etc.</p><p>You can create the project in the <a href="https://console.firebase.google.com/">Firebase Console</a>, first, but you can leave that to the CLI. To get started, position yourself in the projects <code>git</code> repository root. Not inside the <code>./dist/</code> directory. It's going to ask you about adding GitHub workflow files, which I'm going to accept.</p><pre>bunx firebase --versionbunx firebase init hosting</pre> <p>It will ask serveral questions. In my case, it picked a default name for the project ID (and project name) to be that of the directory that the git repository root is in. So if you did <code>cd ~/myprojects/that-webapp &amp;&amp; bunx firebase init hosting</code> it's going to suggest to call the project <code>that-webapp</code> for the project ID.</p><p>Next question is going to be the name of the project. It defaults to be the same as the project ID. But this is where you might, for example, call it "That WebApp". Unlike the project ID, this name does not have to be globally unique.</p><p>In my example, I get this lovely output:</p><p><a href="/cache/03/04/03041e25d47cc7463c00714a94091603.png"><img src="/cache/03/04/03041e25d47cc7463c00714a94091603.png" class="fullsize" style="width:70%"></a></p><p>The next step is specifically for Hosting. It'll ask you some details such as what is the "public directory". In my case, I had to replace the default suggestion (<code>public/</code>) for what my output directory is called; <code>dist/</code>.</p><p>Next, it's going to ask you about setting up the relevant files for GitHub Workflows to auto-deploy. You can say yes to all the GitHub deployment related questions, and tune the code it generates, later.</p><p>When it's done, it'll have generated these files:</p><ul><li><code>.firebaserc</code>: information about the Firebase project</li><li><code>firebase.json</code>: configuration for the hosting</li><li><code>.github/workflows/firebase-hosting-pull-request.yml</code>: so each PR gets its own temporary site</li><li><code>.github/workflows/firebase-hosting-merge.yml</code>: for pushing the deployed site into production when you merge pull requests</li></ul><p>Now, create a PR with all these new files. <a href="https://github.com/peterbe/hylite-demo/pull/4">Here's one such example PR</a>.</p><p>What you should be aware of, with the CLI, it will authenticate to your GitHub account so that it can go in to your repository settings and <em>add</em> the necessary credentials as repo secrets.</p><p>Note, it's likely not going to work at first. In my case, the initialization CLI asked for the instructions for building the site. But what's missing from the GitHub Action workflow, is how do you get the runtime. I had to make this change manually:</p><pre><code class="hljs"><span class="hljs-comment">diff --git a/.github/workflows/firebase-hosting-pull-request.yml b/.github/workflows/firebase-hosting-pull-request.yml</span><span class="hljs-comment">index 8cd1813..0479a03 100644</span><span class="hljs-comment">--- a/.github/workflows/firebase-hosting-pull-request.yml</span><span class="hljs-comment">+++ b/.github/workflows/firebase-hosting-pull-request.yml</span><span class="hljs-meta">@@ -12,7 +12,9 @@</span> jobs: if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} runs-on: ubuntu-latest steps:<span class="hljs-deletion">- - uses: actions/checkout@v4</span><span class="hljs-addition">+ - uses: actions/checkout@v5</span><span class="hljs-addition">+ - uses: oven-sh/setup-bun@v2</span><span class="hljs-addition">+ - run: bun install</span> - run: bun run build - uses: FirebaseExtended/action-hosting-deploy@v0 with:</code></pre> <p>Once your "Deploy to Firebase Hosting on PR" workflow works and passes, you'll see a comment on the PR, like this:</p><!--<a href="/cache/21/c3/21c3282558d1d0ca691ab7c477df22ab.png"><img src="/cache/a9/5c/a95c1500cad896d1003722025a02abaf.png" alt="PR comment" width="370" height="164"></a>--> <p><a href="/cache/21/c3/21c3282558d1d0ca691ab7c477df22ab.png"><img src="/cache/21/c3/21c3282558d1d0ca691ab7c477df22ab.png" alt="PR comment" class="fullsize" style="width:70%" /></a></p><h3 id="domain-name"><a class="toclink" href="#domain-name">Domain name</a></h3><p>By default, it will deploy your site to a domain that is <code>https://your-project-id.web.app/</code>. <a href="https://hylite-demo.web.app/">https://hylite-demo.web.app/ for example</a>.</p><p>Suppose you want your own domain there instead of <code>web.app</code>. You can accomplish this by adding a <code>CNAME</code> for your domain name. To get started, start within the Hosting portion of the Firebase project's Build settings. Find Hosting, and look for this button:</p><p><a href="/cache/01/31/0131872164378564eeeb6149a863608c.png"><img src="/cache/01/31/0131872164378564eeeb6149a863608c.png" class="fullsize" style="width:60%"></a></p><p>Follow the steps and when you get the last modal, copy that into your DNS provider. After you've done that, come back to the Firebase hosting setup and press "Verify"</p><p>That's it. All you have to do now is wait for a cert to be generated and propagate to DNS.</p><p>In my example, when all is done I have a custom domain name pointing to a kick-butt CDN that is as easy to deploy to as merging a PR: <a href="https://hylite-demo.peterbe.com/">https://hylite-demo.peterbe.com/</a></p><h3 id="optimizations"><a class="toclink" href="#optimizations">Optimizations</a></h3><p>One thing I often like to do is to inform Firebase Hosting, which URLs can be cached aggressively. Here's a great example of an addition to the <code>firebase.json</code> file:</p><pre><code class="hljs"><span class="hljs-comment">diff --git a/firebase.json b/firebase.json</span><span class="hljs-comment">index 6564edd..533e3e6 100644</span><span class="hljs-comment">--- a/firebase.json</span><span class="hljs-comment">+++ b/firebase.json</span><span class="hljs-meta">@@ -7,6 +7,17 @@</span> &quot;source&quot;: &quot;**&quot;, &quot;destination&quot;: &quot;/index.html&quot; }<span class="hljs-addition">+ ],</span><span class="hljs-addition">+ &quot;headers&quot;: [</span><span class="hljs-addition">+ {</span><span class="hljs-addition">+ &quot;source&quot;: &quot;/assets/**/*.*&quot;,</span><span class="hljs-addition">+ &quot;headers&quot;: [</span><span class="hljs-addition">+ {</span><span class="hljs-addition">+ &quot;key&quot;: &quot;Cache-Control&quot;,</span><span class="hljs-addition">+ &quot;value&quot;: &quot;public,max-age=315360000&quot;</span><span class="hljs-addition">+ }</span><span class="hljs-addition">+ ]</span><span class="hljs-addition">+ }</span> ] } }</code></pre> <p>I think it's self explanatory what it does. It can be a smidge tricky to get all of these right but thankfully <a href="https://firebase.google.com/docs/hosting/full-config#headers">the documentation is great</a>.</p></description><pubDate>Mon, 03 Nov 2025 16:40:49 +0000</pubDate><guid>http://www.peterbe.com/plog/hosting-your-static-web-site-with-firebase-hosting</guid></item><item><title>Bun vs. Go for a basic web server benchmark</title><link>http://www.peterbe.com/plog/bun-go-basic-web-server-benchmark</link><description><p><strong>tl;dr; Bun is plenty fast to serve as a basic web server that does no I/O. It's even faster than Go using <code>fasthttp</code>.</strong></p><p>Doing a "Hello World" benchmark comparison is rather contrived because it's so unrealistic. No server does no I/O. However, it's good to know that if you do need something as simple as this, and need raw performance, you don't need as statically compiled language like Go. Bun is fast enough.</p><p>Inspired by <a href="https://medium.com/deno-the-complete-reference/bun-v-s-go-hello-world-performance-comparison-1f5418945112">this blog post</a> from 2023, I wanted to retry it using Bun 1.3 that <a href="https://bun.com/blog/bun-v1.3">came out the other day</a>. Honestly, I was nerdily curious how it would fly on my M4 MacBook Pro.</p><p>Check out the code on: <a href="https://github.com/peterbe/go-bun-compare">https://github.com/peterbe/go-bun-compare</a></p><p><strong>Gist: Bun is slightly faster than Go.</strong> <a href="https://github.com/peterbe/go-bun-compare?tab=readme-ov-file#my-current-results">By about 15%</a>.</p><p>Take it with a pinch of salt. These kinds of benchmarks have flaws because the unrealistic scenario, the lack of logging, and lack of other features such as middleware.</p><h4 id="bonuses"><a class="toclink" href="#bonuses">Bonuses</a></h4><p>The <a href="https://github.com/peterbe/go-bun-compare/blob/main/README.md">README</a> has a couple of interesting bonuses such as throwing in Python into the mix.</p><p>One that peaked my interest was; how does running a compiled executable, from Bun, compare to running it directly with <code>bun run ...</code>. I ran it a bunch of times and noticed that executing it as a single binary made it <strong>about 3% faster</strong>. Curious!</p></description><pubDate>Fri, 24 Oct 2025 01:23:26 +0000</pubDate><guid>http://www.peterbe.com/plog/bun-go-basic-web-server-benchmark</guid></item><item><title>hylite as an executable</title><link>http://www.peterbe.com/plog/hylite-as-an-executable</link><description>github.com/peterbe/hylite is now available as downloadable single-file executables</description><pubDate>Wed, 15 Oct 2025 23:23:33 +0000</pubDate><guid>http://www.peterbe.com/plog/hylite-as-an-executable</guid></item><item><title>In Python, you have to specify the type and not rely on inference</title><link>http://www.peterbe.com/plog/in-python-you-have-to-specify-the-type-and-not-rely-on-inference</link><description>Unlike TypeScript, if you give a variable a default, which has a type, that variable is implied to always have the type of the default. That's not the case with mypy and ty.</description><pubDate>Fri, 10 Oct 2025 13:07:37 +0000</pubDate><guid>http://www.peterbe.com/plog/in-python-you-have-to-specify-the-type-and-not-rely-on-inference</guid></item><item><title>Find the source of an alias in bash</title><link>http://www.peterbe.com/plog/find-the-source-of-an-alias-in-bash</link><description><p>This is borderline embarrassing but by blogging about it, at least there's hope that <em>I</em> will not forget this.</p><p>If you have an executable, you can type <code>which</code> to find out its full path. For example:</p><pre><code class="hljs">$ which fdfind/usr/bin/fdfind</code></pre> <p>then you can do something with that. But if the executable is an alias? E.g. I have set up <code>alias fd='fdfind'</code> and suppose I don't remember that. I have this executable, <code>gbranch</code>, but you can't use <code>which</code> on it:</p><pre><code class="hljs">$ which fd</code></pre> <p>It outputs nothing and you get an exit code of 1.</p><p>Lo and behold, it's so basic, run the <code>alias</code> command on it:</p><pre><code class="hljs">$ alias fdalias fd=&#x27;fdfind&#x27;</code></pre></description><pubDate>Mon, 29 Sep 2025 19:04:01 +0000</pubDate><guid>http://www.peterbe.com/plog/find-the-source-of-an-alias-in-bash</guid></item><item><title>From @monaco-editor/react to prism-react-editor</title><link>http://www.peterbe.com/plog/from-monaco-to-prism-react-editor</link><description>Switching from @monaco-editor/react to prism-react-editor means a less powerful in-browser editor but it's much lighter.</description><pubDate>Thu, 25 Sep 2025 21:18:29 +0000</pubDate><guid>http://www.peterbe.com/plog/from-monaco-to-prism-react-editor</guid></item><item><title>How I end-to-end test my Bun CLI app</title><link>http://www.peterbe.com/plog/how-i-end-to-end-test-my-bun-cli-app</link><description>Bun $ Shell makes it easy to write end-to-end tests that tests command line scripts.</description><pubDate>Thu, 18 Sep 2025 18:48:16 +0000</pubDate><guid>http://www.peterbe.com/plog/how-i-end-to-end-test-my-bun-cli-app</guid></item><item><title>How to count the number of non-blank lines with Bash</title><link>http://www.peterbe.com/plog/how-to-count-the-number-of-non-blank-lines-with-bash</link><description>You can use `awk 'NF > 0'` to filter blank lines before piping to `wc` to filter out blank lines.</description><pubDate>Wed, 03 Sep 2025 15:08:07 +0000</pubDate><guid>http://www.peterbe.com/plog/how-to-count-the-number-of-non-blank-lines-with-bash</guid></item><item><title>gg commit with suggested --no-verify</title><link>http://www.peterbe.com/plog/gg-commit-with-suggested-no-verify</link><description><p>In version <a href="https://github.com/peterbe/gg2/releases/tag/v0.0.11">0.0.11</a> of <a href="https://github.com/peterbe/gg2">gg</a> you can now type <code>gg commit Bla bla</code> and it will try to commit but if that fails, it will ask you one more time, if you want to re-attempt to commit but with <code>--no-verify</code>.</p><p>For example:</p><pre><code class="hljs">$ gg commit This is my commit message❌ file has formatting problemsCommit failed and you did not use --no-verify.? Try again but with --no-verify? (y/N)</code></pre> <p>(<em>see screenshots below where color makes these things more intuitive</em>)</p><p>This is handy when you know that the <code>.git/hooks/pre-commit</code> might be failing for a reason that is actually not a problem <em>after</em> you've committed.</p><p>In a sample repo I have:</p><pre><code class="hljs">$ <span class="hljs-built_in">cat</span> .git/hooks/pre-commit<span class="hljs-comment">#!/bin/sh</span> <span class="hljs-built_in">echo</span> <span class="hljs-string">&quot;❌ Rejecting all commits like an angry troll&quot;</span><span class="hljs-built_in">exit</span> 1</code></pre> <p>And when I use <code>gg commit ...</code> this happens:</p><p><a href="/cache/5a/45/5a45eeb1b7d7baebdc9d07e6eb652fc8.png"><img src="/cache/ff/ff/ffff529524b78fb3a84267679f8519ee.png" alt="Prompt" width="370" height="90"></a></p><p><a href="/cache/67/10/671041199ffb99018237b945e483c761.png"><img src="/cache/87/0e/870e49b633d6cddde804121623bd08e1.png" alt="Said y for Yes" width="370" height="147"></a></p></description><pubDate>Fri, 29 Aug 2025 18:37:45 +0000</pubDate><guid>http://www.peterbe.com/plog/gg-commit-with-suggested-no-verify</guid></item><item><title>Faster way to sum an integer series in Python</title><link>http://www.peterbe.com/plog/faster-way-to-sum-an-integer-series-in-python</link><description>You can sum a simple series with `n(n+1)/2`</description><pubDate>Thu, 28 Aug 2025 12:11:22 +0000</pubDate><guid>http://www.peterbe.com/plog/faster-way-to-sum-an-integer-series-in-python</guid></item></channel></rss>If you would like to create a banner that links to this page (i.e. this validation result), do the following:
Download the "valid RSS" banner.
Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)
Add this HTML to your page (change the image src attribute if necessary):
If you would like to create a text link instead, here is the URL you can use:
http://www.feedvalidator.org/check.cgi?url=http%3A//www.peterbe.com/rss.xml