HNHacker News
TopNewBestAskShowJobs

FabianCarbonara

57 karma · joined February 2, 2021

AI Engineer & Curious Human fabian-kuebler.com
submissionscomments
FabianCarbonara··on Extensible Software in the age of LLMs
I've been circling the same exotic holes: I'm trying to sandbox LLM-written code in the browser - running it one layer deeper, in a worker spawned inside the sandboxed iframe.

The WebRTC hole actually goes away down there. RTCPeerConnection is Window-only, so it's just absent in a worker. But you're right not to trust CSP: I'm seeing worse. Under default-src/connect-src 'none' in a worker, Firefox still lets EventSource make the request (fetch/XHR/WebSocket/importScripts all block fine).

What I'm experimenting with right now is SES inside the worker: lockdown() + a Compartment. Still figuring out whether my framework stack survives lockdown().

For UI I'm using Shopify's remote-dom to mirror the UI to the trusted parent page.

FabianCarbonara··on Show HN: Python running on the Super Nintendo (in-browser demo)
(Thanks for vouching! I emailed the mods about my account. I think I tripped a filter with a clumsy submission start...)

About the sprites: loading them from Python at runtime actually works. Stage's Bank objects are plain Python bytes (2048 bytes = 16 tiles at 16x16, 4bpp) plus a palette; on first use, _snesstage.bank() converts them to SNES bitplane format and DMAs them into one of 8 VRAM slots.

On extension modules in general: MicroPython has compiled-in C "user modules" (that's what _snesfb/_snesstage are) and dynamically loadable native .mpy modules. But this needs per-architecture relocation support, and the 65816 isn't among the supported targets.

FabianCarbonara··on Show HN: Python running on the Super Nintendo (in-browser demo)
Python never touches the PPU: the memory-mapped registers live entirely behind a thin C layer (_snesfb / _snesstage modules). Sprite/tile bitmap data gets packed into VRAM tile banks once at startup; at runtime Python only mutates shadow state (hardware tilemaps, an OAM shadow, a framebuf for the GUI stuff) and once per frame the C side DMAs the dirty buffers across during vblank.
FabianCarbonara··on Show HN: Python running on the Super Nintendo (in-browser demo)
Yes, definitely: the GBA is a 32-bit ARM with 256 KB of RAM and mature GCC support, so it sidesteps everything that made this hard: the 16-bit size_t, the far pointers, the barely-stress-tested compiler. The SNES was the fun target though ;)
FabianCarbonara··on Show HN: Python running on the Super Nintendo (in-browser demo)
The bug count surprised me too. Calypsi is a great compiler, but MicroPython is likely the largest program anyone has pushed through it: a huge interpreter switch, packed structs, setjmp/longjmp exception handling, far pointers everywhere. Corners like that had simply never been compiled before.
FabianCarbonara··on I turned Markdown into a protocol for generative UI
Maybe I am a bit overdramatic ;) For me this is mostly about user experience. If the agent creates a complex mini app, the user might have to wait 30 seconds. That's 30 seconds without feedback. It's way nicer to already see information appearing - especially if that information is helpful. Also the UI can be functional already, even if it's not 100% complete!
FabianCarbonara··on I turned Markdown into a protocol for generative UI
A2UI is Google's take — declarative JSON, tool-calling based, predefined component catalog. Clean and safe but constrained.

My approach is the opposite bet: full code execution instead of tool calls. The agent can build any React UI from scratch with the full power of code — including client-server data flow, callbacks, streaming data.

FabianCarbonara··on I turned Markdown into a protocol for generative UI
Whoa, I hadn't seen channels yet — and you already got fenced working with Claude Code?! That's awesome. Would love to see what you built!
FabianCarbonara··on I turned Markdown into a protocol for generative UI
Interesting idea! The slots mechanism already handles some of this — you can mount a skeleton first and fill in named sections later as the LLM generates them. But true out-of-order transclusion could be useful for more complex layouts. Worth exploring!
FabianCarbonara··on I turned Markdown into a protocol for generative UI
and I meant to say: tinkerdown looks pretty cool!
FabianCarbonara··on I turned Markdown into a protocol for generative UI
The goal isn't really a better markdown format — it's bringing code execution and generative UI together. The code fences run on the server: calling APIs, processing data, doing agentic work. And they can also mount reactive UIs with full data flow between client, server, and LLM.

MDX is a compile-time format for static content. This is a runtime protocol where the LLM writes code that executes as it streams, and the UIs it creates stay connected to the server.

FabianCarbonara··on I turned Markdown into a protocol for generative UI
The significance is responsiveness — instead of waiting for the LLM to finish generating the entire code block before anything happens, each statement executes as soon as it's complete. So API calls start, UIs render, and errors surface while the LLM is still streaming tokens.

Combined with a slot mechanism, complex UIs build up progressively — a skeleton appears first, then each section fills in as the LLM generates it.

I wrote a deeper dive on how the streaming execution works technically: https://fabian-kuebler.com/posts/streaming-ts-execution/

FabianCarbonara··on I turned Markdown into a protocol for generative UI
Exactly this!

Right now this uses React for Web but could also see it in the terminal via Ink.

And I love the "freeze" idea — maybe then you could even share the mini app.

FabianCarbonara··on I turned Markdown into a protocol for generative UI
Thanks! Really interesting to hear you're working on something similar.

You're right that the level of expressiveness is the key design decision. There's a real spectrum:

- pre-registered blocks (safe, predictable)

- code execution with a component library (middle ground)

- full arbitrary code (maximum flexibility).

My approach can slide along that spectrum: you could constrain the agent to only use a specific set of pre-imported components rather than writing arbitrary JSX. The mount() primitive and data flow patterns still work the same way, you just limit what the LLM is allowed to render.

Would love to hear what you learn if you explore it!

FabianCarbonara··on I turned Markdown into a protocol for generative UI
Ha, history does rhyme ;) Happy if you reach out via mail!
FabianCarbonara··on I turned Markdown into a protocol for generative UI
Thanks! I totally agree — this isn't about replacing carefully designed UIs. It's about ephemeral interfaces you need in the moment — the throwaway dashboard for this specific dataset, the one-off form for this exact workflow. Things that would normally mean opening 3 different apps.
FabianCarbonara··on I turned Markdown into a protocol for generative UI
In my approach, callbacks are first-class. The agent defines server-side functions and passes them to the UI:

  const onRefresh = async () => {
    data.loading = true;
    data.messages = await loadMessages();
    data.loading = false;
  };

  mount({
    data,
    callbacks: { onRefresh },
    ui: ({ data, callbacks }) => (
      <Button onClick={callbacks.onRefresh}>Refresh</Button>
    )
  });
When the user clicks the button, it invokes the server-side function. The callback fetches fresh data, updates state via reactive proxies, and the UI reflects it — all without triggering a new LLM turn.

So the UI is generated dynamically by the LLM, but the interactions are real server-side code, not just display. Forms work the same way — "await form.result" pauses execution until the user submits.

The article has a full walkthrough of the four data flow patterns (forms, live updates, streaming data, callbacks) with demos.

FabianCarbonara··on I turned Markdown into a protocol for generative UI
Markdown UI and my approach share the "markdown as the medium" insight, but they're fundamentally different bets:

Markdown UI is declarative — you embed predefined widget types in markdown. The LLM picks from a catalog. It's clean and safe, but limited to what the catalog supports.

My approach is code-based — the LLM writes executable TypeScript in markdown code fences, which runs on the server and can render any React UI. It also has server-side state, so the UI can do forms, callbacks, and streaming data — not just display widgets.

FabianCarbonara··on Grief and the AI split
Have a look at my blog! Is linked in my profile :)
FabianCarbonara··on Grief and the AI split
I would say so ;-) Right now AI is a powerful tool for me. It helps me express ingenuity on a more abstract level, e.g. conceptual or product thinking rather than implementation details. Some of my current projects I could have built without AI, but not in the time I had. AI moved them from unrealistic to actually doable.
FabianCarbonara··on Emacs and Vim in the Age of AI
This is super exciting. Emacs already treats UI as just more Elisp to eval. The AI could sculpt the entire editor to whatever you need in the moment. No plugin to install, no config to maintain. Just describe what you need and the editor becomes it.
FabianCarbonara··on Grief and the AI split
For me AI unlocked building things I just couldn't before. My creativity and ingenuity now have an outlet that wasn't possible without agentic coding tools. That's genuinely exciting. But I also keep wondering: how long until the level of abstraction I'm working at now gets automated too?
FabianCarbonara··on Agentic UI with Markdown as the Protocol
I noticed Gemini in Gmail rendering a small interactive UI directly in chat. That made me wonder whether agents could build new interfaces on the fly.

I explored some ideas and built a small prototype around three principles: code first, Markdown as protocol (text, code, data in one stream), and agent-emitted UIs via a simple mount() primitive.

Thoughts welcome! Especially around security and sandboxing of agent-generated code.

FabianCarbonara··on SlimemoldTimemold: Could PFAs explain the obesity epidemic?
Interesting read!
FabianCarbonara··on Fortran adds conditional expressions
to be honest, this was just a very stupid joke. i guess there is no good reason to compare the two.
FabianCarbonara··on Fortran adds conditional expressions
too little, too late! I am super happy with React+Js nowadays..
FabianCarbonara··on Handsfree.js – integrate face, hand, and/or pose tracking to front end projects
Very cool project! This looks like so much fun to build. Thank you for the great documentation of your endeavour!
FabianCarbonara··on Show HN: Sharethatpopcorn.com, watch a movie together online
Thank you for your kind words - they might very well ensure that I keep working on the project!
FabianCarbonara··on Show HN: Sharethatpopcorn.com, watch a movie together online
Hey! Thank you for your input :-). You might need to encode your videos to mp4 first - but then it should work!

Let me clarify how this technically works: Your browser creates a DIRECT connection to your friend's browser and streams DIRECTLY to your friend. I do not see any legal problems - but I am not a lawyer for sure!

FabianCarbonara··on Show HN: Sharethatpopcorn.com, watch a movie together online
Hey! Thank you for the feedback. I put it on my todo list :-)
Page 1 of 2Next →