Back
Chapter 3

Web Extensions with WXT Library

View Source Code

As we could see before creating a Chrome extension at least the basics is super easy but it’s a bit tedious to always reload it when we made some change

And as I mentioned it’s Chrome specific

Luckily there’s a relatively new open source project out there that can help us with our Chrome extension development process

Let’s check it out

Meet WXT

It’s called WXT

And the website is wxt.dev

As you can see it’s a NextGen Web Extension framework an open source tool that makes web extension development faster than ever before

And actually they are not lying

They provide an opinionated framework with tools and naming conventions but if we follow their best practices we can create our extensions blazing fast

They also provide very detailed documentation which I recommend reading but in this course we will follow their best practices

As a start why don’t we rebuild that Chrome extension with that very basic functionality that we created in the previous chapter but using WXT

Installing WXT

So if I read the installation as you can see there are various options pnpm bun and pnpm whichever package manager you prefer

I use bun but it’s totally up to you

I will also just archive this previous project and create a brand new one with WXT

So they say I should just run the init command and follow the instructions so that is exactly what I will be doing

Again bun is already installed on my computer

You probably have npm or yarn whichever

The project directory should be called tabnotes

I’m not using any template I will go with vanilla this time but as you can see you could already choose Vue React

Bun

bun create wxt@latest
cd tabnotes
bun install

Okay it says that I have two things left to do

Going to my folder and run bun install

And while it’s doing it let me just open my folder to see what we have

Starting the dev server

This is WXT’s working folder

However well let’s start with package.json first

We got a couple of scripts here and I can already try the dev script to see what it does

So if I write bun dev or in your case npm run dev or yarn dev it will basically start a new Chrome

You can notice that it’s not the same Chrome browser that I had open but it starts a new one

And it adds the WXT starter Chrome extension

I’ll just pin it

And you can see it has some content while it’s even animating when I move my mouse over the icons

And I can click on it more than that

I can check the developer mode and see the service worker

I can see that it’s also printing some logs in the background script

All right

So now we can see that we got a very very minimalistic basic Chrome extension

File structure

Let’s see the file structure and what’s happening behind the scenes

So if I’m in my code base I can see a wxt config which right now is super empty but this is where we write our own custom configuration

I can see there is a public folder which right now only contains the icon and some images

The assets folder has another SVG about TypeScript

Then the components folder contains a component which is not a React component because we went with vanilla JS but still this is the counter that’s rendered in the popup

And then the entrypoints I have the popup which as you can see renders the contents of the popup including setting up the counter here and some custom CSS

Then we have the background script which uses a bit of a weird syntax but still is the background script

And then we do have a content script

Let’s see what happens

It says that if something matches google.com then it will log hello content

Okay

I suppose I should check if it’s true

I have multiple Chrome browsers now so let’s open the one that WXT created

And if I open google.com and click inspect element I can see that hello content is printed into my dev tools

All right

So as we could see this is something super simple but let’s make sense of what we’ve seen

Out of the box we got an extension that looks more or less as complicated as our previous one was but it has a lot more files

So so far I’m not convinced

Let’s see

Hot reloading

I go to the popup and make some changes such as I can see that it automatically got updated without me doing anything

So hot reloading is working more or less out of the box

I’m saying more or less because you will notice that when you’re making a configuration change or something that’s more complicated then you will still need to restart everything

But when you’re just changing the styles text HTML tags or basic JavaScript then it should work without any problem

But how does it work

Well if you look carefully we have a hidden folder called output and in the output we have chrome-mv3-dev

I think I’ve seen this somewhere before

Well when I run the dev command I can see that it puts the files there

So basically how WXT works is that based on all our source files it generates these output files and stores them

And that browser that just started up is loading that folder just like how we did with the unpacked folder in the previous chapter

And it just takes care of it all

The generated manifest

So let’s see what’s in our files

Here is a manifest.json which we didn’t create

It was 100% created by WXT and it has a lot more information than we added two hours previously

But we don’t have to worry about it because WXT will always update the manifest.json to the right format

Why is this relevant

Because in case we’re targeting a different browser such as Firefox maybe some of the configuration needs to be different

So you don’t have to worry about it because this framework will take care of it

Okay

What other files

We can see that in the manifest.json we defined the background JS which is indeed here

It defined the popup which is indeed here

And it defined some permissions and the content scripts are also living in the file structure

Now of course these files contain a little bit more than what we added to them

Think of it like a bundler that adds some extra code just to make everything work smoothly

Also remember this is in development mode

WXT uses Vite under the hood

So that’s why it’s so fast and that’s why we get hot reloading and other cool features

Rebuilding our extension

Okay

So let’s try to recreate our previous extension in WXT

To get started I will clean up the popup because we had a much simpler one

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>TabNotes</title>
</head>
<body>
  <h1>TabNotes</h1>
</body>
</html>

I don’t even need these two files

We actually do not need the content script because we didn’t have a content script and neither the counter nor the TypeScript logo really because we don’t render it in our popup

What do we have left

We have the icon and the background script

We will talk about all of this later in details but let me try to copy here what we had in our previous extension

export default defineBackground(() => {
  browser.tabs.onActivated.addListener(async (activeInfo) => {
    const tab = await browser.tabs.get(activeInfo.tabId);
    console.log('Tab activated:', tab);
  });
});

All right

We are getting some errors and it says cannot find name chrome

Why is that

WXT as I told you handles various browsers

So instead of calling it chrome we need to change it to browser because it can be any other browser

Really

Well what do we have here

The assets is empty components empty

We have one single popup and we have a background script which supposedly checks whether a tab has changed

Let’s come here

And wow the extension disappeared which happens from time to time

And as I told you this is a perfect moment when some error happens is to simply stop with Ctrl C and start again

All right

That note is there

And if I check the extension the service worker

Indeed

The tab gets activated just as we had before

All right

Why WXT works

So as you could see we could create the previous extension relatively similarly as how we did before

And actually that’s the whole point of WXT

It’s not reinventing the wheel

It just makes normal web extension development so much simpler

If this overview felt a little bit rushed and overwhelming don’t worry

This was just a brief overview because in the next chapters we will look into everything in detail

So you have a very good understanding of every part while we are building our very own web extension