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

推荐订阅源

C
Check Point Blog
AI
AI
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
U
Unit 42
Vercel News
Vercel News
Stack Overflow Blog
Stack Overflow Blog
P
Proofpoint News Feed
Microsoft Security Blog
Microsoft Security Blog
The GitHub Blog
The GitHub Blog
WordPress大学
WordPress大学
Martin Fowler
Martin Fowler
博客园 - 【当耐特】
B
Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
F
Full Disclosure
Google DeepMind News
Google DeepMind News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
H
Help Net Security
Recorded Future
Recorded Future
N
News and Events Feed by Topic
雷峰网
雷峰网
V
Vulnerabilities – Threatpost
Schneier on Security
Schneier on Security
aimingoo的专栏
aimingoo的专栏
S
Schneier on Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
O
OpenAI News
Project Zero
Project Zero
罗磊的独立博客
G
GRAHAM CLULEY
腾讯CDC
P
Privacy International News Feed
V
V2EX
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Hugging Face - Blog
Hugging Face - Blog
爱范儿
爱范儿
H
Heimdal Security Blog
L
LINUX DO - 热门话题
Forbes - Security
Forbes - Security
美团技术团队
MongoDB | Blog
MongoDB | Blog
Security Latest
Security Latest
M
MIT News - Artificial intelligence
T
Tor Project blog
Cisco Talos Blog
Cisco Talos Blog
宝玉的分享
宝玉的分享
T
Threat Research - Cisco Blogs
TaoSecurity Blog
TaoSecurity Blog

Minko Gechev's blog

skillgrade Unit Tests for AI Agent Skills You Should Care About AI Generative Development Reactive framework in ~200 lines of JavaScript Managing Angular Are LLMs going to replace us? Prefetching Heuristics Design Patterns in Open Source Projects - Part II Design Patterns in Open Source Projects - Part I What I learned doing 125 public talks - Part I Dynamic imports solve all the problems, right? 5 Angular CLI Features You Didn't Know About Angular quicklink Preloading Strategy Introducing Bazel Schematics for Angular CLI Building TypeScript Projects with Bazel Joining Google Playing Mortal Kombat with TensorFlow.js. Transfer learning and data augmentation Fast, extensible, configurable, and beautiful linter for Go Introducing Guess.js - a toolkit for enabling data-driven user-experiences on the Web Machine Learning-Driven Bundling. The Future of JavaScript Tooling. JavaScript Decorators for Declarative and Readable Code 3 Tricks For Using Redux and Immutable.js with TypeScript Follow Your Dream Career with Open Source. Personal Story. Redux Anti-Patterns - Part 1. State Management. Faster Angular Applications - Understanding Differs. Developing a Custom IterableDiffer Faster Angular Applications - Part 2. Pure Pipes, Pure Functions and Memoization Faster Angular Applications - Part 1. On Push Change Detection and Immutability Understanding Dynamic Scoping and TemplateRef Implementing a Simple Compiler on 25 Lines of JavaScript Developing Statically Typed Programming Language WebVR for a Gamified IDE 7 Angular Tools That You Should Consider Announcing ngrev - Reverse Engineering Tool for Angular Implementing Angular's Dependency Injection in React. Understanding Element Injectors. Distributing an Angular Library - The Brief Guide Angular in Production Ahead-of-Time Compilation in Angular 2.5X Smaller Angular 2 Applications with Google Closure Compiler Using Stripe with Angular (Deprecated) Building an Angular Application for Production Implementing the Missing "resolve" Feature of the Angular 2 Router Scalable Single-Page Application Architecture Managing ambient type definitions and dealing with the "Duplicate identifier" TypeScript error Static Code Analysis of Angular 2 and TypeScript Projects Enforcing Best Practices with Static Code Analysis of Angular 2 Projects ViewChildren and ContentChildren in Angular Dynamically Configuring the Angular's Router Angular 2 Hot Loader Lazy Loading of Route Components in Angular 2 Aspect-Oriented Programming in JavaScript Flux in Depth. Store and Network Communication. Using JSX with TypeScript Flux in Depth. Overview and Components. Even Faster AngularJS Data Structures Boost the Performance of an AngularJS Application Using Immutable Data - Part 2 Angular2 - First Impressions Build Your own Simplified AngularJS in 200 Lines of JavaScript Persistent State of ReactJS Component Boost the Performance of an AngularJS Application Using Immutable Data Processing Binary Protocols with Client-Side JavaScript Stream your Desktop to HTML5 Video Element Multi-User Video Conference with WebRTC Asynchronous calls with ES6 generators Binary Tree iterator with ES6 generators WebRTC chat with React.js AngularJS in Patterns (Part 3) AngularJS in Patterns (Part 2). Services. Using GitHub Pages with Jekyll! AngularJS in Patterns (Part 1). Overview of AngularJS Singleton in JavaScript Express over HTTPS What I get from the JavaScript MV* frameworks Remote Desktop Client with AngularJS and Yeoman The magic of $resource (or simply a client-side Active Record) AngularJS Inheritance Patterns AngularAOP v0.1.0 Advanced JavaScript at Sofia University AngularJS style guide Lazy prefetching of AngularJS partials VNC client on 200 lines of JavaScript Aspect-Oriented Programming with AngularJS CSS3 flipping effect Practical programming with JavaScript Why I should use publish/subscribe in JavaScript JavaScript, the weird parts Functional programming with JavaScript plainvm Looking for performance? Probably you should NOT use [].sort (V8) JavaScript image scaling ELang Caching CSS with localStorage Self-invoking functions in JavaScript (or Immediately Invoked Function Expressions) Asus N56VZ + Ubuntu 12.04 (en) Asus N56VZ + Ubuntu 12.04 Debian Squeeze + LXDE on Google Nexus S (or having some fun while suffering) HTML5 image editor Курсови проекти – ФМИ Carousel Gallery SofiaJS...
LLM-first Web Framework
2025-04-19 · via Minko Gechev's blog

The opinions stated here are my own, not necessarily those of my employer.

Over the past few weeks I’ve been thinking about how we can make a framework easier for AI. In particular I’ve been only focused on building user interface. When we add a backend, database, and communication protocol across the backend and the frontend, we get another set of problems that could be a good fit for another post and exploration.

Looking at the current landscape of platforms for “vibe coding” I see two main problems:

  • Mismatch of API versions. Often the LLM will generate code that uses deprecated or missing APIs from previous versions. I see that across the board with all frameworks since they all use versions and deprecate APIs.
  • Lack of substantial training data. If you’re using a framework that’s not as popular or has new APIs that the LLM is not familiar with yet, you will likely get a dissatisfactory output. Frameworks such as Angular and React often are not too impacted here due to abundance of training data. You can still see this manifest for new APIs that are not widely used and documented yet.

You can find the code from this experiment on GitHub.

There are a variety of solutions to these problems. For example:

  • We can use the context window to provide relevant examples of the latest APIs
  • We can also use RAG to augment the output with the latest documentation
  • If we have money redundancy…we can fine-tune the model

I decided to solve these problems by building a framework!

Design decisions

The LLM-first framework I created has the following design:

  • Minimal versus expressive syntax. It has orthogonal APIs that complement each other and there’s a single way of doing things. This could potentially make building apps with it more verbose, but there’s less for the LLM to “learn” and “know.”
  • Familiar versus novel. Decided to use very basic syntax, hoping to leverage the LLM’s preexisting training data. For example, templating uses JavaScript object literals. There are a lot of them on GitHub and they have structural similarity to JSON.
  • Fine-grained reactivity. Why not enable generation of fast apps by default!

I based this LLM-first framework on Revolt with one major change - the framework gets all text node and attribute values by invoking a getter function. This way, the framework accesses reactive and static values in the same way.

For example instead of specifying the value of the text node and the style attribute as text values, I’d use functions.

const HelloWorld = () => {
  return {
    name: "div",
    children: () => "Hello, World!",
    attributes: {
      style: () => "color: red;"
    }
  };
};

This makes it easier for the LLM to produce working code. It doesn’t have to “understand” the difference between a static and reactive value.

Revolt LLM

I had a few spare hours and built a “vibe coding” platform that generates Revolt apps.

You can find the source code on GitHub.

Here’s a quick demo video:

The first (and only) draft of the system prompt I came up with:

You are a senior web developer who is expert in using signals in JavaScript. Create an application
based on a user prompt. For the purpose, use the framework and the examples of apps implemented in
this framework below:

// Framework implementation

// A couple of basic component examples

// Todo example, intentionally skipped

// Tetris example, intentionally skipped

Output the application as syntactically correct and executable JavaScript and will render the app on the screen.
All the styles of the application should be inlined under the style attribute of each element.
Use a dark theme for all the applications you generate.

Give your output in the format:
<revolt-response>
<revolt-explanation>
Explanation in up to 3 sentences and without any newlines
</revolt-explanation>
<revolt-code>
The code
</revolt-code>
</revolt-response>

For example:
<revolt-response>
<revolt-explanation>
Here is a simple hello world app
</revolt-explanation>
<revolt-code>
const HelloWorld = () => {
  return {
    name: "div",
    children: () => "Hello, World!",
    attributes: {
        style: () => "color: red;"
    }
  };
};
render(HelloWorld(), document.body);
</revolt-code>
</revolt-response>

All future prompts will be from the user in the format:
User prompt: <prompt>

In Revolt LLM, I decided to keep chat history for the past two prompts and responses to provide a little extra context to the LLM. This works well for flows such as:

> User: Create a todo app
> LLM: [output]
> User: Change the color of the delete button to red
> LLM: [output]

In the example above, in addition to the “Change the color…” prompt, the LLM will also receive the previous prompt and output it produced.

Revolt as an IR

Another potential path forward is to use Revolt as an intermediate representation to generate code that uses a general purpose framework such as Angular or React. Technologies like mitosis use a similar technique for other use cases.

Revolt as an IR

This way we get the benefit of avoiding version skew since we pass Revolt in the context window. At the same time, the final output is code that uses a general purpose framework. In the compiler that transforms Revolt to Angular/React, we can hardcode rules that ensure the output uses the latest general purpose framework APIs.

Generating code that uses a general purpose framework allows developers to debug a technology they are familiar with and get a better interop with the corresponding framework ecosystem.

Moving forward

The three different approaches we discussed are:

  1. Augment the model by passing examples to ensure we generate working code using latest APIs
  2. Instead of using a general purpose framework, use Revolt and pass it in the context window
  3. Generate Revolt code and transform it to a general purpose framework via a deterministic compiler

All the three approaches have their trade-offs. I can definitely see a future in which an entire product will be based on a LLM-first framework and will provide a component model, together with integrations with other platforms.

In the short-term, I see how tools will primarily use the first approach and fallback to the third one in case of highly personalized user interface.