After some testing I decided not to use the windows that Electron creates by default. I decided to create my own titlebar, with Windows-style control buttons. There are many tutorial guides on the internet. I was inspired by a Ronnie Dutta project.
Update the dependencies
A little note before starting with this post. I’m not starting from scratch but I still use my el3um4s/memento-svelte-electron-typescript template. At first, as usual, I make sure I have all the dependencies updated to the latest version:
npm run check-updates
Create a window without a titlebar
First I create a window without a titlebar by setting the frame
property to false
:
Add basic styles
For aesthetic reasons I add some basic styles to the tailwind.pcss
file:
The only odd class is overflow-y-hidden
. It is used to hide the scrollbar from the Electron window. I’ll be using a custom scrollbar attached to the main section of the page.
When I start the app (with npm run dev
) I get a window like this:

What’s the problem? A window without a titlebar has no close buttons and cannot be moved. It’s time to add a custom titlebar.
Add a custom titlebar
Doing some testing the best way seems to be to create a component src/frontend/Componentes/MainWithTitlebar.svelte
in which to insert both the titlebar and the main section of the page.
I write the basic code:
Then I add the component to App.svelte
:
Obviously this does not cause any visible changes. I need to add some styles to my component:
I set the header height to 32px using Tailwind’s h-8
class and set the underlying page height accordingly:

It is not enough to set a titlebar to be able to move a window. Fortunately, Electron allows you to enable this possibility quite easily. Just add the CSS style -webkit-app-region: drag
:
Add window control buttons
Now the window can move. But I also want to be able to close, minimize and zoom it. I need some buttons:
I set the button area as no-drag
to make it easier to click on the buttons. And speaking of buttons, in the code above I used some writing but maybe it’s better to use icons. Tailwind allows you to easily use heroicons icons. I take advantage of it and create some Svelte components to display the icons. This, for example, is the IconClose.svelte
component:
After creating the icons I insert them in the titlebar:
Add the title to the window
There can be several ways to add the title to a window. A simple way is this:

Customize the scrollbar
Electron shows the Chrome scrollbar by default. I can change its style with some CSS code:
This is the result:

Enable buttons
Nothing happens if I click on the buttons, also because I haven’t added any functions. I resolve immediately:
Obviously the functions must be filled with code. What can I use? I need to use a specific API. I create the src/electron/IPC/windowControl.ts
file:
Register the new API on src/electron/preload.ts
:
Finally I allow the main Electron window to use the API. I edit the src/electron/index.ts
file:
This allows me to go back to the component I’m working on (MainWithTitlebar.svelte
) and add the missing functions:
Now I can use the various buttons to minimize, maximize and close the window.
Reset the window size
However, there is an anomalous behaviour. When I maximize the window I would like to replace the maximize
icon with another one. And maybe when I click I can restore the original window size.
To achieve this I can take advantage of the <svelte:window>
element. By inserting it into my Svelte component I can intercept some events related to the window without leaving the component itself.
Why do I have to do this? Because I haven’t found an easier way to tell when the window is full screen. Then I have to use a trick: I check the size of the window. If the window is at least as big as the screen then I assume it is maximized. Otherwise no.
In Svelte, $:
marks a statement as reactive: this greatly simplifies the necessary code.
Now I just have to add the function:
and then:
Link
That’s all. Finally some useful links:
- the project on GitHub: el3um4s/memento-svelte-electron-typescript
- my Patreon: patreon.com/el3um4s
- Svelte
- TailwindCSS
- ElectronJS
- TypeScript