Blog by Ika Pkhakadze

Javascript, Technology, Personal Reflections

The Dumbest Idea: Technology Behind Stack Browser

September 23, 2023

Invader in sand

In June, two years ago, my co-founders Ziko, Gego, and I packed our bags for a week-long trip to Zandvoort, a beautiful seaside town in the Netherlands. The place was full of visitors, especially surfers riding the summer waves. However, our mission was different. We were looking for a fresh atmosphere, free from everyday distractions, to focus our thoughts on one important question: What's the next chapter for Stack?

Adding more and more features doesn't always mean that you're truly advancing the product. There comes a time when a team has to pause, step back, and look at things with a new perspective. Moments of realization like this one bring intertwined feelings of relief and anxiety, I believe many startup founders can resonate with. This time though, for us at Stack, it was different - we knew the challenge was coming.

By the time of our retreat to Zandvoort, the first version of Stack was already up and running. We now refer to it as Stack Legacy, and it had roughly 15k active global users. However, through our Intercom, we received tons of messages from users pointing out unexpected behaviors, requesting missing features, and, most frequently, expressing concerns about performance.

The problem with the performance was not some sort of memory leak in the codebase; it was the whole technology we were using. Simply put, everything was wrong.

Turns out, building a browser-like application is quite challenging, and this blog post is about the technology on which today's Stack is based.

Stack Legacy

The initial version of Stack was started by Ziko in 2018 as a weekend project. He was working in a bank as a Software Engineer and wanted to create an app that could bypass the company's restrictions on browsing social media websites during working hours.

During a weekend, he spun up ElectronJS project and created a simple SPA. It rendered websites with predefined links using the webview tag. If you haven't played with Electron, the webview tag works in a very similar fashion to iFrames: it's part of the DOM, can be positioned using CSS, takes a URL as a parameter, and displays website content. After placing a few webviews in a flexbox and surrounding them with a decent UI, the product was ready for its Product Hunt debut

To cut a long story short, launching on Product Hunt was a game-changer. The response was overwhelming. Feedback made us recognize a genuine need for innovative ways to experience the web. Without any initial intent, but driven by the appetite, what began as a 'TweetDeck for social media' transformed into a full-fledged browser. As the idea grew bigger, so did the size of our team and the complexity of the codebase. We added tons of features onto the original code, experimenting with various approaches. However, throughout this process, one thing was clear: ElectronJS wasn't the right platform for building a browser-like application.

The Search for the Better Technology

We spent around 6 months looking for alternative platforms. By using our investor connections from 500 startups and reaching out to additional experts, we gathered valuable insights. After building several MVPs and analyzing the results, it became clear that there weren't many options available.

We started prototyping using React Native, taking advantage of its ability to compile for Desktop. Tauri, which was still in Beta, was the next promising option on our list.

Meanwhile, we partnered with external companies to create prototypes by directly forking Chromium or using Qt.

This probably deserves another blog post, but in a nutshell, none of these directions could tick all the following checkboxes:

  • Performance - Together with many other aspects of performance, one of the key features of Stack is the Panoramic Scroll. As part of our MVP, it had to be buttery smooth.

  • Chromium-based - React Native and Tauri on macOS use WebKit. This is not inherently a problem, but as we tried to implement some of Stack's signature features, we often found ourselves restricted. Chromium, on the other hand, is like a Swiss army knife. It offers the flexibility to isolate sessions from each other, extension support, and compatibility with Windows - to name a few.

  • Multi-platform - Being a small startup with up to 70% of our Stack Legacy users on Windows, we couldn't afford to focus just on one platform. Migrating all our users to the newer version was a crucial business objective.

  • Development Costs - On paper, forking Chromium seemed like a dream choice, only if we had unlimited time and the key to Uncle Scrooge's money vault. But taking into account our team's expertise, size, and the commitment in both time and funds, we had to find a realistic alternative.

With a few options on the table, none of them seemed just right. We found ourselves at a dead-end, running out of alternatives. The only logical step forward was to challenge the boundaries of one of the existing options and see if we could push it beyond its known limits.

Second Spin of Electron

Electron framework has a lot of critical minds laser-pointed to it, and for valid reasons. However, it still remains one of the most popular and widely used frameworks.

It is high likely that you have at least few Electron based apps sitting in your Dock - VSCode, Discord, Figma, Slack, 1Password, Superhuman, MS Teams, Notion, GH Desktop, Obsidian - to name few possibilities.

It's not a surprise that these companies faced challenges with Electron, and one way or another they did manage to demonstrate a potential of the platform when used correctly.

The most interesting for us was Figma, since they had faced similar problems with WebViews' instability and performance.

Quote from their blog post written in 2017 - Introducing BrowserView for Electron

One of our most important contributions to the Electron project is BrowserView, a new way to embed web apps with fewer bugs and improved performance. While Webview is part of the DOM hierarchy, BrowserView exists within the OS window hierarchy. Web apps in a BrowserView run as fast as they do in Chrome.

Even though it sounds exactly what we needed, we had it ignored for quite some time, believing it wasn't suited for our specific needs. The challenge was clearly outlined in the same blog post:

The downside is that positioning and layering BrowserViews become more complex, as the usual HTML and CSS methods can't be applied like they can with a webview. For apps with intricate layering and positioning, this could be a no-go.

Let's elaborate on this by using a following example.

Extensions Dropdown

In this screenshot from Stack, you see a website of a concert venue in Amsterdam. In the top right corner, there's a dropdown list displaying installed extensions. If the content of the website was rendered using a webview, implementing the dropdown would be straightforward – just use absolute positioning combined with z-index.

BrowserView is different. It's a native component. While you can position it exactly where you want, it always stays on top of everything else. Think of it as a frameless window. So, displaying our dropdown on top of the web content becomes a challenge, unless the dropdown itself is a BrowserView, positioned over everything else, including the website's content.

I won't dive into every little detail, but in order to implement Stack's UI using BrowserViews, practically every layer in UI would need to be wrapped into it's own BrowserView. This includes the Card Topbar, Dropdown menus, the Special (command palette tool in Stack), Dock, and even elements like tooltips and toaster messages.

Stack Layers

In one of the discussions on Reddit I mentioned that we use Electron to build a native-like application. I realize that this statement is misleading without the full context, and also it's only partially true. Yet, one Redditor responded: "...that's probably the dumbest fucking thing I've ever heard on this website and there's a lot of dumb fucking shit..."

And, that's actually true. Two years ago we went to Zandvoort to build yet another prototype with the dumbest fucking idea - use native browser-view component for each individual UI component and compare its performance to other options and assess the feasibility of this direction.


In the second part of this post I will demonstrate technical details of the implementation. I'll dive into challenges associated with BrowserViews and our solutions for each of them.

Fast forward, 2 years later, in August 2023 we launched fully functional Stack, yet still in Beta, with full support of Extensions and multi platform.

I always felt a discomfort when discussing our technology for a long time. Was it during the hiring process with interviewees, discussions with my friends, or with investors. We knew it was a stupid experiment. But today, I have this weird feeling of a child, who's stupid idea wins.

I do know that it's not a final version of Stack. People who I respect and learn a lot from tell us that we'll need to migrate to full native, and I absolutely agree. While we're working on to find a market fit, attract talented people, grow our team and business, the solution that we have today is the best, I say it proudly as well as confidently.