<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hacker News: bikeshaving</title><link>https://news.ycombinator.com/user?id=bikeshaving</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Thu, 23 Apr 2026 18:24:09 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=bikeshaving" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by bikeshaving in "Qite.js – Frontend framework for people who hate React and love HTML"]]></title><description><![CDATA[
<p>Manual refresh(). This is something Crank does, and other frameworks like the new Remix one is picking it up as well. Being explicit has its advantages.</p>
]]></description><pubDate>Fri, 27 Mar 2026 15:47:50 +0000</pubDate><link>https://news.ycombinator.com/item?id=47544259</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=47544259</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47544259</guid></item><item><title><![CDATA[New comment by bikeshaving in "Qite.js – Frontend framework for people who hate React and love HTML"]]></title><description><![CDATA[
<p>I’ve written about how Svelte, Vue, and Solid are all reactive and share common pitfalls due to their reactive solutions. My theory is that they all cause worse bugs than they prevent.<p><a href="https://crank.js.org/blog/why-be-reactive/" rel="nofollow">https://crank.js.org/blog/why-be-reactive/</a></p>
]]></description><pubDate>Tue, 24 Mar 2026 20:05:28 +0000</pubDate><link>https://news.ycombinator.com/item?id=47508319</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=47508319</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47508319</guid></item><item><title><![CDATA[New comment by bikeshaving in "Meta's Omnilingual MT for 1,600 Languages"]]></title><description><![CDATA[
<p>I don’t own a car :)</p>
]]></description><pubDate>Sat, 21 Mar 2026 15:41:58 +0000</pubDate><link>https://news.ycombinator.com/item?id=47468023</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=47468023</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47468023</guid></item><item><title><![CDATA[New comment by bikeshaving in "Meta's Omnilingual MT for 1,600 Languages"]]></title><description><![CDATA[
<p>I’m very wary of celebrating Meta’s language work when the company was credibly found to have contributed to the genocide against the Rohingya in Myanmar, and separately, to human rights abuses against Tigrayans during the conflict in northern Ethiopia. Be careful whose sins you’re laundering.<p><a href="https://www.amnesty.org/en/latest/news/2025/02/meta-new-policy-changes/" rel="nofollow">https://www.amnesty.org/en/latest/news/2025/02/meta-new-poli...</a>
<a href="https://www.amnesty.org/en/latest/news/2023/10/meta-failure-contributed-to-abuses-against-tigray-ethiopia/" rel="nofollow">https://www.amnesty.org/en/latest/news/2023/10/meta-failure-...</a></p>
]]></description><pubDate>Sat, 21 Mar 2026 15:35:27 +0000</pubDate><link>https://news.ycombinator.com/item?id=47467958</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=47467958</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47467958</guid></item><item><title><![CDATA[Show HN: Revise.js – Building blocks for contenteditable-based text editors]]></title><description><![CDATA[
<p>Hi HN. I've been working on this since 2018. Revise.js is a set of building blocks for contenteditable: a <content-area> web component that gives you a textarea-like .value for any contenteditable element, an Edit data structure with compose/transform/invert for OT inspired by the Xi editor, and a Crank.js integration for declarative editable components. At 32.8 KB gzipped (including the rendering framework), it's 2–4x smaller than ProseMirror, Slate, or CodeMirror. The trade-off is that those ship complete editors; Revise is foundations you build on. All the demos on the homepage are live and editable: <a href="https://revise.js.org" rel="nofollow">https://revise.js.org</a></p>
<hr>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=47414537">https://news.ycombinator.com/item?id=47414537</a></p>
<p>Points: 5</p>
<p># Comments: 0</p>
]]></description><pubDate>Tue, 17 Mar 2026 16:02:36 +0000</pubDate><link>https://revise.js.org/blog/introducing-revise/</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=47414537</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47414537</guid></item><item><title><![CDATA[Dulce et Decorum Est (1921)]]></title><description><![CDATA[
<p>Article URL: <a href="https://www.poetryfoundation.org/poems/46560/dulce-et-decorum-est">https://www.poetryfoundation.org/poems/46560/dulce-et-decorum-est</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=47254322">https://news.ycombinator.com/item?id=47254322</a></p>
<p>Points: 220</p>
<p># Comments: 107</p>
]]></description><pubDate>Wed, 04 Mar 2026 21:41:40 +0000</pubDate><link>https://www.poetryfoundation.org/poems/46560/dulce-et-decorum-est</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=47254322</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47254322</guid></item><item><title><![CDATA[New comment by bikeshaving in "Microsoft Creative Writer (1993)"]]></title><description><![CDATA[
<p>I must tell you, it is an incredible relief to learn that McZee was not a figment of my imagination.</p>
]]></description><pubDate>Tue, 03 Mar 2026 00:41:34 +0000</pubDate><link>https://news.ycombinator.com/item?id=47226381</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=47226381</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47226381</guid></item><item><title><![CDATA[New comment by bikeshaving in "Microsoft Creative Writer (1993)"]]></title><description><![CDATA[
<p>Just found the text editor from my childhood</p>
]]></description><pubDate>Mon, 02 Mar 2026 23:05:59 +0000</pubDate><link>https://news.ycombinator.com/item?id=47225537</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=47225537</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47225537</guid></item><item><title><![CDATA[Microsoft Creative Writer (1993)]]></title><description><![CDATA[
<p>Article URL: <a href="https://classicreload.com/play/win3x-creative-writer.html">https://classicreload.com/play/win3x-creative-writer.html</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=47225536">https://news.ycombinator.com/item?id=47225536</a></p>
<p>Points: 18</p>
<p># Comments: 5</p>
]]></description><pubDate>Mon, 02 Mar 2026 23:05:59 +0000</pubDate><link>https://classicreload.com/play/win3x-creative-writer.html</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=47225536</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47225536</guid></item><item><title><![CDATA[New comment by bikeshaving in "When does MCP make sense vs CLI?"]]></title><description><![CDATA[
<p>I’ve found that humans are pretty good at reading through the output of bash commands. And Claude Code keeps insisting on truncating the output for some reason.</p>
]]></description><pubDate>Sun, 01 Mar 2026 20:40:39 +0000</pubDate><link>https://news.ycombinator.com/item?id=47210441</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=47210441</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47210441</guid></item><item><title><![CDATA[New comment by bikeshaving in "When does MCP make sense vs CLI?"]]></title><description><![CDATA[
<p>I keep asking why the default Claude tools like Read(), Write(), Edit(), MultiEdit(), Replace() tools aren’t just Bash() with some combination of cat, sed, grep, find. Isn’t it just easier to pipe everything through the shell? We just need to figure out the permissions for it.</p>
]]></description><pubDate>Sun, 01 Mar 2026 18:10:47 +0000</pubDate><link>https://news.ycombinator.com/item?id=47209144</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=47209144</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47209144</guid></item><item><title><![CDATA[New comment by bikeshaving in "A better streams API is possible for JavaScript"]]></title><description><![CDATA[
<p>Yes, the callable promise abstraction is just a bit of effort:<p><pre><code>  let resolveRef;
  const promise = new Promise((res) => { resolveRef = res; });
  
  const callback = (data) => {
    // Do work...
    resolveRef(data); // This "triggers" the await
  };

  Object.assign(callback, promise);

</code></pre>
There’s a real performance cost to awaiting a fake Promise though, like `await regularPromise` bypasses the actual thenable stuff.</p>
]]></description><pubDate>Fri, 27 Feb 2026 21:39:28 +0000</pubDate><link>https://news.ycombinator.com/item?id=47186012</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=47186012</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47186012</guid></item><item><title><![CDATA[New comment by bikeshaving in "A better streams API is possible for JavaScript"]]></title><description><![CDATA[
<p>Not accepting PRs for this. I think the logic is sound (Easter Eggs should be difficult to trigger).</p>
]]></description><pubDate>Fri, 27 Feb 2026 20:11:05 +0000</pubDate><link>https://news.ycombinator.com/item?id=47184929</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=47184929</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47184929</guid></item><item><title><![CDATA[New comment by bikeshaving in "A better streams API is possible for JavaScript"]]></title><description><![CDATA[
<p>A long time ago, I wrote an abstraction called a Repeater. Essentially, the idea behind it is, what would the Promise constructor look like if it was translated to async iterables.<p><pre><code>  import { Repeater } from "@repeaterjs/repeater";
  
  const keys = new Repeater(async (push, stop) => {
    const listener = (ev) => {
      if (ev.key === "Escape") {
        stop();
      } else {
        push(ev.key);
      }
    };
    window.addEventListener("keyup", listener);
    await stop;
    window.removeEventListener("keyup", listener);
  });
  const konami = ["ArrowUp", "ArrowUp", "ArrowDown", "ArrowDown", "ArrowLeft", "ArrowRight", "ArrowLeft", "ArrowRight", "b", "a"];
  (async function() {
    let i = 0;
    for await (const key of keys) {
      if (key === konami[i]) {
        i++;
      } else {
        i = 0;
      }
      if (i >= konami.length) {
        console.log("KONAMI!!!");
        break; // removes the keyup listener
      }
    }
  })();
</code></pre>
<a href="https://github.com/repeaterjs/repeater" rel="nofollow">https://github.com/repeaterjs/repeater</a><p>It’s one of those abstractions that’s feature complete and stable, and looking at NPM it’s apparently getting 6.5mil+ downloads a week for some reason.<p>Lately I’ve just taken the opposite view of the author, which is that we should just use streams, especially with how embedded they are in the `fetch` proposals and whatever. But the tee critique is devastating, so maybe the author is right. It’s exciting to see people are still thinking about this. I do think async iterables as the default abstraction is the way to go.</p>
]]></description><pubDate>Fri, 27 Feb 2026 15:53:08 +0000</pubDate><link>https://news.ycombinator.com/item?id=47181953</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=47181953</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47181953</guid></item><item><title><![CDATA[New comment by bikeshaving in "Making a font with ligatures to display thirteenth-century monk numerals"]]></title><description><![CDATA[
<p>I was thinking using ZWJ because the staff is always implied by the usage of Cistercian numerals. I was also wondering if we could reuse CISTERCIAN 1-9 for each significant digit rather than having to encode all 4 separately, though at the end of the day it’s only 36 separate code points.<p>Adding the staff is 37 codepoints versus 36, but I think using ZWJ would at least have each numeral independently renderable so it degrades gracefully. I’m not too sure about how combining characters degrade.<p>Essentially it boils down to whether you think the staff and the digit flag part of the numeral are independent or not.</p>
]]></description><pubDate>Thu, 19 Feb 2026 07:47:12 +0000</pubDate><link>https://news.ycombinator.com/item?id=47071049</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=47071049</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47071049</guid></item><item><title><![CDATA[New comment by bikeshaving in "Making a font with ligatures to display thirteenth-century monk numerals"]]></title><description><![CDATA[
<p>Can anyone who works with the Unicode consortium explain why Cistercian numerals aren’t just part of Unicode? There’s Aegean numbers, counting rod numerals, Mayan numerals, Roman numerals (beyond the Latin letter aliases), cuneiform numbers, and plenty of other historical numeral-only systems.<p>The 4-stave system is interesting but can almost certainly be done using ZWJ hacks maybe.</p>
]]></description><pubDate>Thu, 19 Feb 2026 06:34:24 +0000</pubDate><link>https://news.ycombinator.com/item?id=47070603</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=47070603</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47070603</guid></item><item><title><![CDATA[New comment by bikeshaving in "Show HN: Shovel.js – A portable meta-framework built on web standards"]]></title><description><![CDATA[
<p>Thanks for the kind words! Let me know your thoughts if you end up exploring.</p>
]]></description><pubDate>Mon, 09 Feb 2026 18:06:10 +0000</pubDate><link>https://news.ycombinator.com/item?id=46948598</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=46948598</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46948598</guid></item><item><title><![CDATA[Show HN: Shovel.js – A portable meta-framework built on web standards]]></title><description><![CDATA[
<p>I recently built a CLI and set of libraries for running Service Workers as application servers. The idea: instead of inventing new APIs, use the ones browsers already have (Cache API, FileSystem API, CookieStore, URLPattern, AsyncContext) and shim them for Node, Bun and Cloudflare when missing. The result is portable code that runs anywhere and follows rigorous specifications which coding agents like Claude Code already know how to use. `npm create shovel` to try it.</p>
<hr>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=46946989">https://news.ycombinator.com/item?id=46946989</a></p>
<p>Points: 3</p>
<p># Comments: 2</p>
]]></description><pubDate>Mon, 09 Feb 2026 16:21:33 +0000</pubDate><link>https://shovel.js.org/blog/introducing-shovel/</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=46946989</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46946989</guid></item><item><title><![CDATA[New comment by bikeshaving in "Ask HN: What are you working on? (February 2026)"]]></title><description><![CDATA[
<p>I’ve just published the first public release of a new open source project Shovel.js, replacing tools like Express, Fastify, Next.js, Vite. It’s a full-stack/meta server framework which implements the full Service Worker specification but in Node, Bun, Cloudflare. It leans into using web standards to do things like accessing the filesystem, reading cookies, create client-side bundles rather than inventing new APIs. You can read about the process of making Shovel with AI in the introductory blog post.<p><a href="https://shovel.js.org/blog/introducing-shovel/" rel="nofollow">https://shovel.js.org/blog/introducing-shovel/</a><p><a href="https://github.com/bikeshaving/shovel" rel="nofollow">https://github.com/bikeshaving/shovel</a></p>
]]></description><pubDate>Mon, 09 Feb 2026 00:53:37 +0000</pubDate><link>https://news.ycombinator.com/item?id=46940286</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=46940286</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46940286</guid></item><item><title><![CDATA[New comment by bikeshaving in "Computer Systems Security 6.566 / Spring 2024"]]></title><description><![CDATA[
<p>Seeing this makes me miss the salad days of MOOCs. I learned programming in the 2010s through MIT’s EDX Introduction to Programming course, and then a course on Coursera by Martin Odersky on Functional Programming through EPFL, and I feel like that ladder has been kicked away due to MOOC monetization policies. I wonder if we could return to these days.</p>
]]></description><pubDate>Sun, 18 Jan 2026 02:44:37 +0000</pubDate><link>https://news.ycombinator.com/item?id=46664371</link><dc:creator>bikeshaving</dc:creator><comments>https://news.ycombinator.com/item?id=46664371</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46664371</guid></item></channel></rss>