State of Preact Devtools

📖 tl;dr: We ran into too much trouble trying to make Preact work with the new react-devtools extension, due to differences in how both frameworks work under the hood. We're working on our own preact-devtools extension which will resolve that.

As many of you know the react team released a revamped devtools extension recently. The improvements are countless and not just for endusers, but also the protocol has changed substaintially for the better. Whereas the previous iteration always asked for the information of the complete tree and every detail at once, the new version follows more a pull based approach. It only requests the data it needs and only when it's needed. That's a stark contrast!

Another neat change is that the mappings for elements now happens on the consumer side. When you're attaching devtools to a virtual-DOM-based framework you need to notify the extension of every change in the tree or duplicate some of the reconciliation when element order changes. Both approaches are valid, but whatever you choose, you need to have a way to match old and new elements. You need to know that the just rendered element matches exactly a node on the other side.

Old react-devtools The previous version of react-devtools was great for its time, but known to be a little slow.

With the previous adapter we had to pretend to actually be React, which isn't always easy. With the new one we could now just write our own and attach it to the extension. I started on that adventure in April and got my first components to show up in the new extension (note that it was still marked as experimental back then and months away from a release).

Armed with new possibilities we could do the mapping ourselves in our own preact adapter. Typically you'll store a Map somewhere where you assign an ID for each node. That way you can easily track parent relationships and ordering without having to care about framework specific details. On the plus side this makes the extension code much easier to reason about.

A few weeks later I was able to finally crack it. I got the whole tree showing up in the extension! One by one I spent the following months ticking of one box after another. One week I managed to get props to show up, the other week state and I really made lots of progress.

Not to say that I didn't have my moments where I was stuck on something, but in the end it worked out. Our own demo app we use to test real world code with, was crucial here in aiding my plans.

The difficult bridge to react-devtools

Problems started to arise once the new devtools was released and we received a wider audience of users eager to test it out with Preact. Whilst some issues could be fixed, others could not. I spent 4 full days trying to make it work and ultimately had to call in the defeat.

The new react-devtools with Preact The new react-devtools extension with Preact. As you can see the props panel is broken.

The reason it's difficult is that under the hood Preact and React do things quite a bit different from each other. Due to the focus on concurrent rendering, React splits everything into so called commits. It describes all the changes that were made in the current render request (for a lack of a better word). This means that each call to setState/forceUpdate or the toplevel render() function will create such a commit.

Those commits are then queued up into a message the devtools understands. Those events will be automatically in order so you can traverse it linearly on the extension side. That's pretty great for performance!

Trouble is that in Preact we don't have such a strict model of commits (yet?). When you call forceUpdate on a component we pause the current render and execute the new one in-between before continuing with the previous one. This obviously breaks the strict ordering rules of events for the devtools.

Note that this is just one of the issues I was facing, there are many more subtle ones, simply because both frameworks work so differently. That's even more true for Preact 8.x which is a whole different beast. Overall the main thing that broke me is the insane amount of time I spent on the adapter that masks Preact as React. I've come to the conclusion that it's better for us in the longterm when we have our own extension.

I want to be clear here that the react-devtools extension (as the name implies) is only targeted at React. We were fully aware that we didn't get any official support for that and for good reason (obviously). The devtools are excellent and some of the best we've seen. They even added tiny features just for us to make it easier to interface with it. We're super grateful for that and we have a lot to thank them for!

It's not you, it's me

I'm fully aware that the current situation where the devtools are kinda broken sucks. And I hate that. It makes me sad because we nearly got it working and I personally see any form of devtools as a huge asset for any framework.

Faced with a hard decision, I went with giving our own extension a go. I've spent the past 2.5 weeks working on that and a prototype is finally coming together. For now my main focus is on getting the elements panel right. Additional features such as some sort of profiling tool will come later.

Preact Devtools Don't mind the minor visual glitches (heavy work in progress). I'm more focused on getting the features stable and robust first. It supports both light and dark mode if you're curious.

Introducing Preact Devtools

In just a little more than 2 weeks the basic features are already there. The extension will display a colored icon when it detects Preact on the current page. It will display the current mounted component tree (update and unmount still needs work). It can inspect props and change them. It can highlight the current node in the viewport and most importantely: It's a lot easier for us to work with.

Preact Devtools in light design Light version of the Devtools (heavy work in progress).

But it will also take time, more than I'd like it too. Yet I feel like this is the right direction to take. Although I know the react-devtools code like the back of my hand, I was able to add more features in the past two weeks than I was able to in the past months.

Having our own devtools also means that we can explore more Preact related aspects like visualizing other types of data related to components in the tree. This opens a lot of doors for us!

Right now it's in a rough state and I'm confident that it will mature in the next weeks. It's way too early to set on a release (or pre-release) date, but I just wanted to share with you the current state of devtools, so that you all know what's happening.

Follow me on twitter, mastodon or via RSS to get notified when the next article comes online.