Interview with Tao Xin, senior staff software engineer at Google

VanJS: "Enabling everyone to build useful UI apps with a few lines of code, anywhere, any time, on any device"

VanJS: "Enabling everyone to build useful UI apps with a few lines of code, anywhere, any time, on any device"

Interview with Tao Xin, senior staff software engineer at Google

VanJS: "Enabling everyone to build useful UI apps with a few lines of code, anywhere, any time, on any device"


We spoke with Tao Xin, senior staff software engineer at Google to learn all about VanJS, a minimalist reactive UI framework. It enables you to compose the UI tree in a declarative and intuative way. Let's find out more about this minimalist reactive UI framework.

devmio: Thank you for taking the time to answer our questions! First, could you please introduce yourself to our readers? What is your background and how did you end up in your line of work?

Tao Xin: Hi, my name is Tao Xin. I am a senior staff software engineer at Google. In the past decade I've been working for various products of Google - ads, cloud, Play, etc. Despite taking more and more leadership role in my career, I keep a keen passion for the programming itself. I'm interested in a wide range of programming-related topics, such as performance optimizations, designing concise declarative API, programming languages, etc.

Mostly, I can be considered as a backend engineer, as the vast majority of my work in my professional life is backend engineering. Thus indeed I don't have too much front-end background. That said, when it comes to computers, I'm a DIY enthusiast. I enjoy building tools for my personal use. But here is the thing: most tools need some sort to UI to be minimally useful. Consider an example, a tool to track your investment portfolio: Of course this can be done by a CLI program. But the way we can interact with CLI program is quite limited. It's not easy even for rendering a simple table view, let alone charts. And the only way we can provide input to the tool is typing some lengthy, hard-to-memorize strings in the commandline.

Thus, it's fair to say, to write some useful program, particularly "useful" in the sense of day-to-day life (for some sparse use case like scientific calculation, CLI program might be ok), you have to build some UI. And to build some UI, you either learn some proprietary UI framework, or you learn some web framework. Either option likely requires you to at least read through a book to start with. This situation resonates a very remarkable gap I was facing 20+ years ago when I started learning programming: when I had my first computer, I was fascinated by all the powerful things it can do, and all the apps built on top of it. I couldn't wait to learn programming, Pascal first and then C++, hoping to build something interesting and powerful, but only to realize the only possible thing I can build is a popping black screen where I can output some white characters like Hello World. What a disappointment. Indeed, it took me several years to finally come out with something that is not a popping black screen, way after I felt I was pretty skillful at C++ and programming in general.

Wind95 Screenshot

neither MFC nor Win32 API was easy 20+ years ago 🙁

Today, even after 20+ years with all the technology advancement, I don't think the situation has substantially changed. We see frameworks after frameworks after frameworks. We see a specialized group of people called FE engineers. But for most other people, the apps they are proficient to build are not much different from a popping black screen with white characters. Well, maybe a white screen with black characters, or a dark blue screen with light gray characters 😁. We've seen a great deal of efforts to bring in more modernized terminals and shells. But my thought is: why not going with the other direction instead? Why not making building UI apps as simple as CLI programs so that most of us don't have to be confined to the limitations of terminals? btw: even for the quest of modernizing terminals, VanJS is pretty good at it - a web-based Unix terminal with notable improvements can be built under 300 lines with the help of VanJS

So this is the motivation behind VanJS. In https://vanjs.org/, I mentioned that VanJS is positioned as the scripting language for UI. I do think there is the divergence between more and more powerful interactions we can have with computers, and the abilities where most programmers (except for a small group of people specialized in FE or UI) can utilize the powerful UI for useful tools.

devmio: What exactly is VanJS and what does it aim to accomplish?

Tao Xin: VanJS is designed to bridge in the remarkable gap: on one hand, computers has become universally useful, with apps available to almost all day-to-day use cases we can think of; on the other hand, the programs which most people are comfortable to write, are not much different from a popping black screen with white characters. In the home page of https://vanjs.org/, it has VanJS's mission statement: Enabling everyone to build useful UI apps with a few lines of code, anywhere, any time, on any device.

In a nutshell, VanJS is a minimalist (world's smallest) reactive UI framework. It enables you to compose the UI tree in a declarative and intuative way. You can easily define states of your apps and bind the states to UI elements, just as you would do with much more complex frameworks. The amazing part of VanJS is: you don't need any tools to use VanJS. Nothing. You don't need to install any dependencies, not even npm. You don't even need an IDE. You can just grab-n-go the VanJS library and build powerful UI apps with it in any environment with barely a browser and a text editor. There is no transpiling, no bundling, no extra binary needed for your code to work. What you write is exactly what is being executed in the browser. This is critical to VanJS's mission: ... build UI apps ..., anywhere, any time, on any device. You can even build UI apps completely on your smartphone (or feature phone perhaps?).

devmio: Where did you get the idea to create VanJS? What were your main inspirations or goals?

**Tao Xin:**This is a great question! VanJS was originated in the process of building various tools on my own. As someone without much background on FE or UI programming, I felt the only viable way for me to build a UI without spending months on learning is to start from scratch with web programming. As more and more apps being built, I felt that there are common problems where a set of helper functions can make the UI code concise, and DRY. There are problems of composing the UI structure declaratively; There are problems of binding UI to states and reacting to state changes. Eventually these helper functions became the early prototype of VanJS. I had a discussion post that talks about the evolution history in the early days of VanJS.

In terms of API design, VanJS draws inspiration from React. As the most widely-used UI framework, React offers a good example on how a mature reactive UI framework should look like: A declarative way to describe the DOM tree structure; Reusable composed UI elements; One-way data-binding from states to UI. The creation of VanJS is an illustration that these can be achieved in a much simpler way. There are 3 things that VanJS has proved:

  1. You don't need JSX and transpiling to describe the DOM tree declaratively: In VanJS, DOM hierarchy can be declared in pure vanilla JavaScript, with even more concise code! The HTML to VanJS Converter can convert any HTML snippet into the equivalent VanJS code where you can do the comparison. We have examples (1, 2) where apps built with VanJS are 3~4 times shorter than the React counterparts.

  2. You don't need complex class hierarchy and lifecycle management for reusable components: In VanJS, a reusable UI component is just a plain JavaScript function, nothing more.

  3. You don't need Virtual DOM and hidden diff algorithm for reactive data binding: VanJS demonstrates that reactive data binding is possible with pure native methods of DOM elements. Thus, there is no need to introduce a new parallel layer of the virtual DOM tree. No need for any hidden control flow.

devmio: Exactly how lightweight is VanJS and what benefits does that offer?

Tao Xin: As of VanJS 1.0.0, the .min.js.gz bundle is only 0.9kB and the .min.js file is 1.6kB. This is 50~100 times smaller than most popular web frameworks. It is by far the smallest reactive UI framework in the world.

Among all of benefits of being such ridiculously small, the first and foremost one is its utmost simplicity. Unlike other frameworks where you typically need reading a book or joining a bootcamp to start with, the tutorial of VanJS, together with the complete API reference, is just a single web page, and can be learned within 1 hour. VanJS can enable people without FE background to build a UI app in just a couple hours.

Another important benefit of being such lightweight is performance. For web application, a smaller bundle means faster page loading, and less bandwidth consumption. And because VanJS is just a very thin layer on top of the standard web API (native code implemented by browsers), the code executes fast as well.

Last but not the least, amid the phenomenal rise of Generative AI and LLM (large language model), VanJS's size might find itself an interest spot in this space. With the token limit being the bottleneck of LLM, VanJS's tiny size means the entire library can be used as part of prompt to LLM. I have tried to paste the entire source code to ChatGPT. What I found amazing is that, ChatGPT can not only understand what the code does, it can also generate sample apps on top of it and adjust the code based on follow-up prompts. So think of that, you don't need to train the language model with any knowledge about VanJS. You don't need to fine tune the model. You don't even need to provide any sample code. Just paste the source code of VanJS and ChatGPT will automatically be able to build apps based on it. My conversation history can be found here. I believe there will be very interesting applications by combining LLM and VanJS.

devmio: Could you show us some sample code so we can see how it looks in action?

Tao Xin: Sure.

const Counter = () => {
  const counter = van.state(0)
  return span(
    "❤️ ", counter, " ",
    button({onclick: () => ++counter.val}, "👍"),
    button({onclick: () => --counter.val}, "👎"),
  )
}

This is a sample app shown in the home page of https://vanjs.org/. The app defines a counter state, and 2 buttons that can respectively increment and decrement the counter. As you can see, the DOM tree is built declaratively with pure JavaScript. You don't need JSX and transpiling for declarative UI programming.

The HTML to VanJS Converter can convert any HTML snippet into the equivalent VanJS code. For instance, for

<div>
  <p>👋Hello</p>
  <ul>
    <li>🗺️World</li>
    <li><a href="https://vanjs.org/">🍦VanJS</a></li>
  </ul>
</div>

the equivalent VanJS code will be:

div(
  p("👋Hello"),
  ul(
    li("🗺️World"),
    li(a({href: "https://vanjs.org/"}, "🍦VanJS")),
  ),
)

In https://vanjs.org/demo page, there are lots of interesting apps built with VanJS. You can see many handy utilities can indeed built in just a few lines of code with the help of VanJS:

devmio: What instances is VanJS best suited for, and where should users potentially hold off for now?

Tao Xin: The prime use cases of VanJS is for someone without much experience of FE or UI programming, but wants some quick solution to add a usable UI into their app. I believe this type of use cases are profoundly underestimated. Lots of CLI programs can be enhanced with a UI layer, which could greatly improve their usability. Taking a personal tool that I recently built - a code generator, as an example, we can have a quick and dirty CLI script for it. But after adding more and more features, it will be crucial to have a convenient way to tweak different types of code generation parameters, to live preview the generated code when parameter changes, and to copy/paste designated piece of code. All of these functionalities are very difficult, if not impossible to implement with CLI. Thus VanJS bridges the gap between CLI programming and GUI programming. You won't feel substantially different between writing a shell script and building a web UI with VanJS. VanJS empowers all programers. Even people with basic programming skills can have the feeling that the day-to-day apps they're using are within their reach to build.

Even for people who would become professional FE programmer, VanJS can provide a smooth learning curve. VanJS offers a very easy start as its tutorial is so easy to walk through. And the programming experience with VanJS is definitely helpful to strength their understanding of reactive UI programming which will eventual benefit their proficiency of much more complex frameworks like React.

The transpiling-free characteristic of VanJS makes it an ideal tool for REPL. All modern browsers have a developer console that allows you to run arbitrary JavaScript code on the fly, but not the code that requires transpiling. With VanJS, you're able to construct any HTML elements with concise code for the current web page right in the developer console. Another related use case is for browser extensions. The lightweight of the library makes it suitable to be embedded in the content scripts that slightly enhance the appearance and behavior of web pages.

Furthermore, VanJS shines in use cases where size is an essential factor, such as ensuring fast page load in low connecitvity network. Integration with LLM is another interesting area to explore. As mentioned earlier, because its tiny size, we can paste the entire source code of VanJS into ChatGPT and asks ChatGPT to generate application code based on it without the need of any training or fine tuning. This is not possibile with any much larger libraries as they can't fit in the token limit.

Regarding the use cases where users should hold off for now, I think, objectively, VanJS doesn't have the ecosystem compared to the established counterparts. Thus, even though theoretically VanJS is cappable of many types of applications, you should be aware that you don't have a large collection of reusable components readily available. Other than the limitation on the ecosystem, I think VanJS is suitable for quite many use cases, perhaps more broad than some people might have thought. Some people has said, well, VanJS might excel on simple use cases, but for more complex UI components, VanJS's code is not as readable as React's JSX. I respectively disagree with that, as illustrated in the example above, the VanJS-based DOM tree is structurally equivalent to JSX counter part, only more concise (as we can see examples where VanJS apps can be 3~4 times shorter than React counterparts).

devmio: What is Mini Van and what are its use cases?

Tao Xin: Mini-Van is a slimmed-down version of VanJS that only supports DOM tree composition and manipulation (i.e.: without reactivity). Thus compared to VanJS, Mini-Van is even more lightweight. But more importantly, Mini-Van supports SSR (server-side rendering) and hence can be used as a server-side template engine. The entire https://vanjs.org/ website is built with the help of Mini-Van.

Mini-Van is an exploratory step for VanJS to unify server-side and client-side rendering. With Mini-Van, you can write server-side web pages and components similar to the ones on the client-side. There are 2 remaining matters to address to truly unify server-side and client-side rendering?

  1. What is an effective way to share UI components between server-side and client-side?
  2. How to enable hydration?

Currently these can be done with some workarounds. In future, I can consider adding the official support if use cases are well understood.

devmio: Are there any future plans from the roadmap that you would like to share? What do you hope to add in an upcoming release, or what is currently in progress?

Tao Xin: That is a great question! First, I would like to lay out the general principles about future evolution of VanJS:

  1. Reliability is the top priority of the VanJS project. Among my limited bandwidth working on this project, reliability is the thing I will give most attention to. I would like to reassure people that despite VanJS being personal project, it's completely reliable to use, even in production settings. Every single code change in VanJS requires passing 400+ test cases, which cover all the supported usage of the library that I can think of, as well as examples illustrated in the tutorial. You can refer to https://vanjs.org/about#reliability for the details.
  2. VanJS is committed to remain minimalist and performant. I will be very cautious of adding new features to VanJS. There are definetely lots of features can be added into VanJS to make it fancier in certain specific use cases. But there will be a high bar to include them in the core library. Notable things to consider regarding new features are: Will this feature restrict how people optimize their applications? Does this feature introduce performance penalty for use cases where the feature is not being used? For the reasons above, certain features are not included in VanJS, such as lazy-evaluated states (as we want to give users the flexibility in scheduling the expensive evaluation), general-purpose diffing (as we don't want to introduce the performance penalty for the majority of use cases where diffing is not needed), etc.
  3. Optional features can be added via add-ons. Relatively, bar can be lower if features are not added into the core library. Use-case-specific libraries on top of VanJS should be the way to address special needs, as unlike the core library, add-ons are completely optional.
  4. VanJS should be easy to work with other libraries and remain unopinionated on which one to choose. We understand there are a good collection of high-quality libraries in JavaScript ecosystem that people enjoy for different kinds of problems, such as CSS, routing, animation, advanced statement management, etc. Instead of providing an in-house solution for each problem in VanJS to be on par with other libraries, we choose to keep VanJS minimalist and unopinionated so that its users can freely combine it with other available solutions. I think this is the beauty of open source community.

With these guiding principles, these are the things planned in the short-term future:

  1. I will build a set of grab-n-go UI components based on VanJS. It's fairly easy to build reusable UI components with the current library but even some basically components might not seem that obvious to the beginners of FE programing, especially for the CSS tricks to enable the basic constructs such as modal, tabs, banner, message box, etc. I believe this will be beneficial for VanJS to further eliminate the entry barrier of FE programing. The work is ongoing - you can check it out here, and we will be implementing more UI components in the near-term future.
  2. I would like to do some benchmarking for VanJS. Although not validated by benchmarking, I strongly believe that the performance of VanJS is much closer to Vanilla JavaScript than to React, given its simplicity in design and performance-aware implementation. Some benchmarking will prove this point and give people the confidence in case they are still unsure whether adopting VanJS is a performance-wise sound decision.

devmio: Besides VanJS, what current technology, programming language, hardware, etc. are you most excited about and would like to see progress in the coming years?

Tao Xin: The recent development on AI (particular around LLM) is defintely exciting. I'm keen on it and looking forward to foundamental innovation coming out in this field.

Other than that, I'm generally interested in programming languages for a long time. I think in general, there are 2 flavors of design philosophy. One flavor is: making things easy to use, and completely hide the complex stuff from its users. To certain extend, JavaScript is designed in this flavor, as the memory is managed by the runtime. The downside of this flavor is users lose the ability to fine tune things. Thus essentially, we're trading the flexibility in exchange for ease of use. What I'm particularly interested in is the second flavor, which is: maximally preserving the flexibilty of its users and at the same time, still trying to make things as easy as it could. Rust is a perfect example in this flavor. It preserves users' flexibility on memory management but on the other hand, achieves the same level of memory safety (maybe higher) as managed languages.

Recently, Zig has captured lots of my interest. Its way of handling compile-time meta-programming is absolutely innovative, and its insistence on no hidden control flow means giving the maximal transparency and flexibility to its users. Particularly, it preserves one flexibility even Rust doesn't offer - memory allocation. We've seen great projects like Bun which leverages this flexibility for its performance optimizations (btw: Bun, which aims to be a much faster JavaScript runtime, is another project that I am very interested in and wish to succeed). Compared to Rust, Zig takes the subtle balance between memory safety and ease of use. It doesn't try to prohibit writing memory-unsafe code, but instead provides good language constructs to make correct code is much easier to write than incorrect one. To certain extent, this is similar to one main design philosophy of VanJS: unlike most other UI frameworks which prohibit the procedural-styled DOM manipulation, VanJS allows direct DOM manipulation and I believe it could be useful in certain use cases, for performance and/or for convenience. Right now Zig is in a very early stage and it is planned to take a few more years to the 1.0 milestone, but this is really something I am wishing for its progress and good adoption.

Tao Xin

Tao Xin is a seasonal programmer with decades of programming experience and currently working at Google as a senior staff software engineer. Throughout the years of programming, he has been working on different types of products, and different types of software systems. Tao has a keen interest in a wide-range of programming topics, and has been always pursing the simplicity in design. Meanwhile, he is a DIY enthusiast and likes building many tools to boost his personal productivity. VanJS is a project that comes out of the quest - how to have a simple, zero-dependency toolkit that even people without any FE or UI background can build good tools with a usable UI in a couple hours?


More articles on this topic


Gen AI Engineering Days 2024

Live on 29 & 30. October 2024 | 13:00 – 16:30 CEST