惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Secure Thoughts
C
Cybersecurity and Infrastructure Security Agency CISA
T
Tenable Blog
Project Zero
Project Zero
T
The Exploit Database - CXSecurity.com
T
Threat Research - Cisco Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Cyberwarzone
Cyberwarzone
PCI Perspectives
PCI Perspectives
G
GRAHAM CLULEY
H
Hacker News: Front Page
Cloudbric
Cloudbric
Latest news
Latest news
N
News and Events Feed by Topic
C
CERT Recently Published Vulnerability Notes
Attack and Defense Labs
Attack and Defense Labs
SecWiki News
SecWiki News
Security Latest
Security Latest
MyScale Blog
MyScale Blog
阮一峰的网络日志
阮一峰的网络日志
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Security Archives - TechRepublic
Security Archives - TechRepublic
V2EX - 技术
V2EX - 技术
B
Blog RSS Feed
L
LINUX DO - 最新话题
人人都是产品经理
人人都是产品经理
Last Week in AI
Last Week in AI
IT之家
IT之家
Jina AI
Jina AI
Y
Y Combinator Blog
博客园 - 聂微东
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
V
Visual Studio Blog
P
Privacy International News Feed
B
Blog
S
Schneier on Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Hacker News - Newest:
Hacker News - Newest: "LLM"
Help Net Security
Help Net Security
D
DataBreaches.Net
博客园_首页
G
Google Developers Blog
I
InfoQ
量子位
大猫的无限游戏
大猫的无限游戏
S
Security @ Cisco Blogs

Lobsters

CIFSwitch: a non-universal Linux local root vulnerability RIPE NCC session fixation: poaching logins with an Atlas probe GNOME 2.20 but its Web Components Agentic Search for Context Engineering – Leonie Monigatti Garnix is shutting down [not OC] akashina.tngl.sh/jjc Concerning Emacs (and Jazz) Nitpicking the shell history scene in ‘Tron: Legacy’ What's cooking on SourceHut? Q2 2026 The tenth OpenPGP email summit Package managers that package package managers Clojure on Fennel part three: parsing WordPress at 23 Finding Miscompiles for Fun, Not Profit GitHub - creusot-rs/creusot: Creusot helps you prove your Rust code is correct. Announcing Rust 1.96.0 | Rust Blog A Love Letter to Neovim sqlite AGENTS.md Am I a Bad Friend? CSS vs. JavaScript • Josh W. Comeau Erlang Ecosystem Foundation - Supporting the BEAM community A brief note about slot access cost in Common Lisp Keyboard latency probe Rethinking the GNOME clipboard issues Back to the Building Blocks’ Building Blocks Tech Notes: Theseus: translating win32 to wasm Fast is better than slow Content-addressed Rust builds (or, what kache actually caches) Intent to Prototype: Embedding API Canada’s Bill C-22 and the security cost of collecting more data 5 PostgreSQL locking behaviors that trip people up okmij.org Stop advertising in your commits! | AksDev GitHub - mplsllc/macsurf: A modern web browser for Classic Mac OS 9 PowerPC. Real CSS3, ES5 JavaScript, native HTTPS — built with CodeWarrior on the Carbon API. Introducing DoomBench - Can Your Data Stack Run DOOM? What are some of your favourite developer tools? Building a Scalable Ingestion Pipeline with Temporal (Part 1) Converting shallow Git bundles into normal repositories Are you a member of any professional associations? What is a harmonic? An interactive comic about additive synthesis How Virtual Tables Work in the Itanium C++ ABI Using SwiftUI to Build a Mac-assed App in 2026 Rust (and Slint) on a jailbroken Kindle. ~jack/lambda-on-lambda - Serverless Haskell on AWS - sourcehut git Human proof for FOSS contributions Extremely simple internet radio controlled via IRC Announcing BABLR Splitting Konsole views from Helix to run tools | AksDev GitHub - yugr/rust-slides Serving files over HTTP three ways: synchronous, epoll, and io_uring update docs with information about building with build.py (#979) · astral-sh/python-build-standalone@c9c40c5 A Simple Makefile Tutorial On C extensions, portability, and alternative compilers Switching to Colemak | Pedro Alves Just How Bad Was The Intel IAPX432? Nix's Substituter List Is Not a Routing Table Accelerating copy_if using SIMD Lambda on Lambda: Serverless Haskell on AWS | Blog Announcing feed-repeat v1.0 Scaling Akvorado BMP RIB with sharding EYG news: A host of CLI improvements, new guides and new effects The social contract of writing JS Crossword C array types are weird; and related topics Flatpak will depend on systemd – OSnews Migrating from Go to Rust | corrode Rust Consulting A portentous reunion Vivado Licensing Options How my minimal, memory-safe Go rsync steers clear of vulnerabilities the entropy layer of a wavelet codec, on its own GitHub - nferhat/fht-compositor: A dynamic tiling Wayland compositor. Debian SE Linux and PinTheft Does bulk memmove speed up std::remove_if? (No.) 声明式部分更新 | Blog | Chrome for Developers Fully in-browser container builds Dianne Skoll's Web Site - Remind The Architecture of Open Source Applications (Volume 1)Berkeley DB Pardon MIE? - ironPeak Blog “Long-Term Support” doesn’t mean what you think Jira IS Turing-Complete May I recommend thinking of Emacs as your Fortress of Solitude hershey Floodgap Gopher-HTTP gateway gopher://thelambdalab.xyz/1cuneiforth/ HP QuickWeb, Singular And Pointless That one time I used Go panics for flow control A new suite of modern tools coming for editing and publishing RFCs From the Tabletop… The Digital Antiquarian Building a Host-Tuned GCC to Make GCC Compile Faster Are we self-sovereign PKI yet? Claw Patrol: an open-source security firewall for agents | Deno Revised^7 Report on Scheme, Large: Procedural Fascicle Draft is now public A Network Allow-List Won't Stop Exfiltration — André Graf From AFSK to Goertzel – µArt.cz Software For My New Home Server Introducing Neptune: Direct3D virtualization for QEMU AI Agent Bankrupted Their Operator While Trying to Scan DN42 - Lan Tian @ Blog mimalloc: A new, high-performance, scalable memory allocator for the modern era Making wl_shm fast The Soul of Maintaining a New Machine - Third Draft | Books in Progress What is Git made of?
Fornjot - Shutting Down Fornjot
fornjot.app · 2026-06-19 · via Lobsters

Shutting Down Fornjot

Posted on by Hanno Braun

Fornjot is ending; unfinished, incomplete. This is not what I wanted, not why I started this project. But it is the decision I have made.

For a while now, Fornjot's development has been happening on the side, next to other work that filled most of my day. This became unsustainable, and I addressed that by serializing my efforts: focus on one project at a time until I reach a good point to pause, then switch to the next one.

Ironically, these improved conditions led to my decision to quit. Once it was Fornjot's turn, I made better progress than I could before. As a result, for the first time in a while, I was able to get my head above water and take in the bigger picture, understand where things were going.

That's when I realized I had to quit. My work was supported by sponsors. I couldn't justify taking their money, if I didn't believe that I was on a path to create something meaningfully different (and thus in some ways better) than what's already available.

It became clear to me that under current conditions, it would have easily taken another 2-3 years to put the foundation in place to even start delivering such value. After already being at it for almost 6 years, I realized that I couldn't commit to that. It's too much. I no longer have it in me.

(Before writing this, I sent a private announcement to my sponsors, in which I stated that I had been working on Fornjot for about 5 years, not 6. Which is what I believed at the time, but I just checked, and it turns out the first commit to the Fornjot repository happened on July 30, 2020.)

Mistakes I Made

Six years without even delivering something useful; it's not a good look. CAD kernels are notoriously difficult, but that's only a partial excuse. I made many mistakes along the way. In this section, I want to reflect on those mistakes. Maybe we can learn from them.

When I started working on Fornjot, it was a departure from my earlier experiments with CAD, which had been based on signed distance fields. When I switched to boundary representation, that showed promise, and I expected linear progress from there.

That linear progress never materialized. Instead, I ran into a cliff. Discovering in so many different ways why CAD kernels, specifically b-rep kernels, are considered hard.

Starting in 2022, I became more serious about Fornjot. Opening issues and pull requests to make progress easier to follow, instead of pushing to main directly. Creating a website, publishing regular releases, writing release announcements. And seeking sponsorship.

It worked. The growth in sponsorship enabled everything that followed. If the project ever had a chance to succeed, it was because of that. And yet, I wouldn't do it again; not like this. I was still on my way towards creating something useful. Instead of selling a product, I had sold a dream.

That wasn't my intention. I had been expecting linear progress towards a useful tool, but then never got there. And it gnawed on me for all these years. I mean, I managed. But still, I didn't like it. I don't intend to ever sell a dream again, at least not without an actual product to deliver alongside.

Sticking to Incremental Improvements

As I tried to scale that cliff I had run into, I limited myself to incremental improvements. Those had always served me well, while big rewrites had only ever been a distraction. Born from my yearning to replace a messy situation with a clean slate, without ever solving the underlying problems.

But both attitudes are extremes. There's fertile ground in between. Instead of convincing myself that a new idea was promising, then spending a long time implementing it in small steps, I should have been prototyping. All the time. Only then integrating, incrementally or not, what proved valuable.

Responding to Crisis with Half-Measures

My sponsorship income had reached a sustainable level for the first time some months into 2022, due to a single, very generous sponsor. When they didn't renew in 2023, that left a large gap. A similar thing happened in 2024.

Both times I thought that sponsorship income was unlikely to recover, yet both times existing sponsors stepped up to close the gap. But there were delays between drop and recovery, which gave room for mistakes.

The first time, it broke the spell. Dissolved that image in my head, of Fornjot as the only thing I needed to do. The second time, I decided I needed to double down on diversifying and reduced Fornjot to a side project. A side project I absolutely wanted to still finish. But my life's work became something else.

And that was my biggest mistake. Each time, I had exactly two reasonable options: continue with full commitment or quit right then and there. I did neither. And if I had to trace back the project's failure to a single cause, that would be it.

Allowing My Vision to Become Muddled

The initial goal of Fornjot was to build a code-first CAD application, which included a custom CAD kernel. Reacting to that first drop in income, I decided to cut the application and focus on the kernel only. In a way, this was good. It removed many moving parts, which simplified the project significantly.

But overall, I still think it was a mistake. An application can be focused. A CAD kernel is a generic piece of infrastructure, with many use cases to consider. At least that's how I felt about it at the time. And this muddled my vision (though it recovered somewhat, as time went on).

I should have thought more outside of the box, should have ditched those categories. Something can be a kernel, a library, but still focus on specific use cases. Be a tool instead of a building block. (And building an application on top of an existing kernel was an option that never appealed to me.)

Prototyping Came Too Late

I eventually realized that exclusively sticking to incremental improvements was a mistake. I had maneuvered the codebase into a transitionary state, halfway between and old approach and a new one, when I realized that the new approach was unlikely to pan out.

I then started a series of experiments to discover better ideas, a better architecture to base Fornjot on. Spent over a year on that, in fact! And maybe I succeeded. I came up with a much simpler architecture, which I still think shows promise.

But I did not reap the rewards of that work. I started integrating the new architecture into the existing codebase, with the goal of replacing or adapting the old code. But I didn't finish. I ran out of steam before I got there.

Conclusion

So there we have it. An overambitious project, addled by mistakes at almost every turn. I hope reading about it was useful to you, and maybe helps inform your own work.

As for myself, I believe I'm coming out of this smarter and stronger. But I guess we'll have to see. It's easier to state your mistakes, than it is to actually avoid repeating them. I hope that my future efforts will be proof of how much I learned.