~/portfolio/blog — godot_is_the_natural_successor_to_electr
build: ok v0.4.7
← cd ../
guest@portfolio:~/blog$ cat 2025-10-godot-beyond-games.md
2025.10.11

Godot is the natural successor to Electron

#godot · #frameworks · #electron ·9 min

I posted three takes about Godot on Mastodon and they got more traction than anything else I’ve written this year. So here’s the long version.

My cold take: Godot is being massively under-utilized as a non-game software development framework.

My warm take: The lifecycle of nodes is simpler and safer than a React component.

My hot take: Godot is technically the largest competitor of React Native and the natural successor to Electron.

I’ll defend each in turn.

Cold take: it’s a software framework that thinks it’s a game engine

Strip away the editor and the rendering pipeline for a second and look at what Godot actually gives you:

  • A scene graph with strong ownership semantics
  • A signal/event system that doesn’t leak
  • A first-class GUI toolkit (Control nodes) that ships across every platform Godot supports
  • Native exports for Windows, macOS, Linux, Android, iOS, and the web
  • A scripting language that boots in milliseconds, plus C#, plus GDExtension if you need native speed
  • A 50MB editor that runs anywhere

That’s not a game engine. That’s a cross-platform application framework that happens to be very good at games. The “game engine” framing is so dominant that nobody outside the gamedev community even considers it for a desktop app.

Warm take: nodes have a saner lifecycle than React components

Both Godot and React are tree-of-things-that-render frameworks. But the lifecycles diverge sharply.

A React component can mount, unmount, re-render an arbitrary number of times, and the closure state from one render can leak into the next via stale callbacks. Hooks make this manageable with rules, but the underlying model is “this function runs again and again, please don’t accidentally capture the wrong variable.”

A Godot node has one life. It’s instantiated, _ready fires once, _process ticks as long as it’s in the tree, and then it’s freed. There is no re-render. There is no closure-over-stale-state. If you want a node to refresh, you tell it to refresh.

extends Control

@onready var label: Label = $Label

func _ready() -> void:
    GameState.score_changed.connect(_on_score_changed)

func _on_score_changed(new_score: int) -> void:
    label.text = "Score: %d" % new_score

That’s it. No useEffect, no dependency array, no memo. The subscription is set up once, torn down when the node is freed, and the framework guarantees both.

I’m not saying React is bad. I’m saying that for the kind of UI where state lives in well-defined places and updates are explicit, the node model is a smaller mental tax.

Hot take: Godot vs Electron, Godot vs React Native

Electron ships a Chromium per app. The smallest possible “Hello, world” is around 150MB on disk and 100MB of RAM before you’ve done anything useful. The defense is that all your web skills transfer. Fine, but the cost is shipping a browser to every user, forever.

A Godot export of a similar app is roughly 50MB and idles around 50MB of RAM. The GUI toolkit is built in. There is no embedded browser. There is no V8 to update for every security advisory.

React Native is the closer comparison on mobile. Both target iOS and Android. Both have a tree-shaped UI model. Both ship native widgets (RN literally so, Godot via its own rendering). Where Godot wins:

  • One codebase covers desktop and mobile and web, without an Expo-shaped detour.
  • The build is a single binary, not a bundler-plus-native-shell dance.
  • There is no JavaScript bridge. UI updates are direct.

Where React Native still wins:

  • Ecosystem. There is no react-navigation equivalent for Godot apps. You’re rolling your own.
  • Talent pool. Hiring “a Godot developer who wants to build line-of- business software” is a tiny set.
  • Native platform integration. Push notifications, deep links, background tasks — all solved problems in RN. In Godot you’re reaching for GDExtension and writing platform code.

That ecosystem gap is the whole reason this post exists. The framework is ready. The libraries aren’t.

What I want to see

A serious effort at:

  • A routing library (think react-router but for Control nodes)
  • A persistence layer that isn’t “save a Resource”
  • HTTP/fetch abstractions that match what web devs expect
  • Authentication primitives — OAuth, OIDC, the whole zoo
  • A Tailwind-equivalent for theming

None of these are hard. They’re just unwritten because almost nobody has needed them yet.

If you build apps for a living and you’re tired of paying the Electron tax, Godot is worth a weekend. The worst case is you learn a new framework. The best case is you ship a 50MB native app instead of a 200MB one.