• Which the release of FS2020 we see an explosition of activity on the forun and of course we are very happy to see this. But having all questions about FS2020 in one forum becomes a bit messy. So therefore we would like to ask you all to use the following guidelines when posting your questions:

    • Tag FS2020 specific questions with the MSFS2020 tag.
    • Questions about making 3D assets can be posted in the 3D asset design forum. Either post them in the subforum of the modelling tool you use or in the general forum if they are general.
    • Questions about aircraft design can be posted in the Aircraft design forum
    • Questions about airport design can be posted in the FS2020 airport design forum. Once airport development tools have been updated for FS2020 you can post tool speciifc questions in the subforums of those tools as well of course.
    • Questions about terrain design can be posted in the FS2020 terrain design forum.
    • Questions about SimConnect can be posted in the SimConnect forum.

    Any other question that is not specific to an aspect of development or tool can be posted in the General chat forum.

    By following these guidelines we make sure that the forums remain easy to read for everybody and also that the right people can find your post to answer it.

MSFS html gauge tutorial and samples


I've spent the last 2 months in the shed hammering away at html gauges. I've managed to make a couple of gauges, a radio and a fuel level for my aircraft. After much cursing and swearing I think I have a slight understanding of how to make a gauge. I have made this simple tutorial to help share the knowledge.

Let me just start by saying html is hard. There is a lot of code you need to write just to get something to work in MSFS. I also recommend developing in a web browser instead of MSFS at least for the layout stage of your gauge. MSFS is a real pain in the butt to work within. The tutorial includes examples of gauges that will run in a browser as well as detailing the changes you need to make to convert that gauge to run in MSFS.

Disclaimer: I am not an expert in html, js or css. These examples may not be the most efficient or perfect way to create gauges for MSFS. But they work. They are what I was able to figure out from the last 2 months of repeated head banging against the wall.

Final disclaimer: Please do not ask me to figure out why your gauge is not running. All I can say is carefully check your syntax (including capitalisation) and any changes you make. Like I said, making html gauge is not easy.

This picture shows the sample gauges in operation. As you can see they are very simple, I didn't want anything too complex so you could just focus on the core layout of the gauges. The one on the left is made using SVG elements and you can rotate and translate the yellow rectangle with the elevator and aileron controls. The one on the right is easier to code and uses DIV elements. SVG elements are more complex but necessary if you want to create graphics and glass cockpits. DIV elements are easier and are great for simple text displays (such as radio displays).

At the bottom of the picture on the left you can see the radio gauge I wrote and on the right is the default Aera which is being substituted by the sample SVG gauge. Using the Aera substition allows people using the tutorial to quickly see the gauge in operation without needing to build your own aircraft and create dummy panels.



  • AntsTutorialGauge.zip
    109.9 KB · Views: 1,514
Thanks for doing this Anthony. I don't know if MSFS has changed since you posted this but I'm struggling to follow along with the 'LET'S START' section. You suggest copying the generic 'hmtl_ui' folder from the base MSFS install but I can't find this folder in the location you describe? Maybe I'm missing something simple but I'd appreciate any help you could offer to help me understand this.

Thanks for doing this Anthony. I don't know if MSFS has changed since you posted this but I'm struggling to follow along with the 'LET'S START' section. You suggest copying the generic 'hmtl_ui' folder from the base MSFS install but I can't find this folder in the location you describe? Maybe I'm missing something simple but I'd appreciate any help you could offer to help me understand this.

The install location of MSFS is only something you know. I can only tell you where it is if you install MSFS through the MS Store without changing the default location. If you need more information you should provide some more information. I cannot provide detailed answers to vague questions.
Yeah, I guess that question was a bit vague. My installation is from the Microsoft store and in the default location but it's OK now. I haven't found exactly what you describe but I think I've found what I need.

Thanks for your reply.
Hey @Anthony31,

Thanks for this tutorial! It made it all a lot clearer to me. Would you know prehaps, how you can define where such a gauge is getting its electrical power from?
I have coded an EDM900, but I couldn't figure out yet how to tell to MSFS: "Hey, this is an EDM900 and it is connected to that power source (e.g. an internal alternator)". I found it for some general stuff (in the systems.cfg). But how do I tell that there should be also an EDM900 in the systems list (it's not a default circuit as far as I know).

Thanks in advance!
Hey @Anthony31,

Thanks for this tutorial! It made it all a lot clearer to me. Would you know prehaps, how you can define where such a gauge is getting its electrical power from?
I have coded an EDM900, but I couldn't figure out yet how to tell to MSFS: "Hey, this is an EDM900 and it is connected to that power source (e.g. an internal alternator)". I found it for some general stuff (in the systems.cfg). But how do I tell that there should be also an EDM900 in the systems list (it's not a default circuit as far as I know).

Thanks in advance!
Hi Hans

I'm not at my work computer at the moment but from memory you can use CIRCUIT_XML:n where n is any number (start at 1 and go up depending on how many circuits you need). I think some of the default airplanes use CIRCUIT_XML to supply power to the GPS units (or some other gauges) and so I just copied that and use circuit_xml as a generic power circuit(s). Those aircraft then link the circuit (which may be different depending on the aircraft) through the panel.xml file but I couldn't really figure out how to link that in the javascript so I just directly read the status of the A: var for the circuit within the javascript. You can also switch the circuit on/off in javascript.

I'll edit this comment later to add some more detail as the default gauges use an electricity function in the javascript to check if the power is on/off and the html then uses that function to show/hide the display.

Here's the edits and some examples:

For the systems.cfg

circuit.12 = Type:CIRCUIT_AUDIO #Connections:bus.2# Power:10, 12, 11.5# Name:Audio ; Audio 15W
circuit.13 = Type:CIRCUIT_AUTOPILOT #Connections:bus.2# Power:10, 12, 11.5# Name:Autopilot ; Autopilot 15W
circuit.14 = Type:CIRCUIT_XML:1 #Connections:bus.2# Power:10, 12, 11.5# Name:Radios
circuit.15 = Type:CIRCUIT_XML #Connections:bus.2# Power:10, 15, 11.5# Name:Aera_Tablet

This is in the css:
#Electricity {
  width: 100%;
  height: 100%; }
  #Electricity[state=off] {
    display: none; }

This is in the html. Wrapping your display elements in div id="Electricity" seems to control them:
<script type="text/html" id="Ants_ICA22_Radio">
    <div id="Mainframe">
        <div id="Electricity" state="off">  
            Put all your div id elements in here

This is in the js and these two functions check if power is available:

    updateA22Electricity() {
        let powerOn = this.isA22ElectricityAvailable();
        if (this.electricity) {
            if (powerOn)
                this.electricity.setAttribute("state", "on");
                this.electricity.setAttribute("state", "off");
        return powerOn;
    isA22ElectricityAvailable() {
        var _circuitOn = SimVar.GetSimVarValue("CIRCUIT ON:14", "Bool");
        var _mainVolts = SimVar.GetSimVarValue("ELECTRICAL MAIN BUS VOLTAGE", "volts");
        if ( _circuitOn && _mainVolts > 5 ) { return 1; } else { return 0; }
        return 0;

These are all based off default gauge code so you can refer back to some of the default gauges if you like. It's been months since I wrote these and I think I've forgotten most of the reasoning behind them. But as you can see I am directly reading the CIRCUIT ON:14 simvar to determine if the circuit is on and if there is any main bus volts (the circuit might be on but there needs to be enough power too).

Finally here is some js code showing how to switch a circuit off if it is on. In this case it's turning off a light on circuit 11 if the radio is off.

if ( SimVar.GetSimVarValue("CIRCUIT ON:11", "Bool") ) { SimVar.SetSimVarValue("K:ELECTRICAL_CIRCUIT_TOGGLE", "number", 11); }
Last edited:
great stuff Anthony (as always).

For the actual display I do something very similar in my gauges except I haven't found it necessary to use predefined identifiers like Electricity and this.electricity which I guess means in Asobo code somewhere there's a this.electricity = document.getElementById("Electricity"). If I have something like <div id="b21_radio"> with the HTML/CSS/JS structure being very similar to yours, the power on/off of the gauge is just via this.radio_el = document.getElementById("b21_radio") and this.radio_el.style.display="block" and this.radio_el.style.display="none". Your isA22ElectricityAvailable() function is the genius part and IMHO you don't need to then fall back to the Asobo electricity or show/hide code.

I'd like to add a probably more useful hint (than my stuff just above) of my own, which is update functions are typically called from within the BaseInstrument Update function which means they get called (typically) 18 times per second. As a general programming style it's quite easy to have the gauge only make CSS updates when necessary, rather than setting className or other element attributes (like "state") on every cycle which causes the renderer to have to go through all the CSS rules on every update cycle to see if the display should change. Clearly for power on/off the actual update is relatively infrequent, and the technique I use on all my gauges is to have variables ending in _prev which record the 'previous' state of some variables to the CSS update will only occur if there is a change. In this example you'd have a this.powerOn and this.powerOn_prev and the CSS controlling block would be:
let powerOn = this.isA22ElectricityAvailable();
if (this.powerOn_prev==null || this.powerOn_prev != powerOn) {
                this.electricity.setAttribute("state", powerOn ? "on" : "off"); // but I'd actually use this.b21_radio_el.style.display = powerOn  ? "block" : "none"; (same either way really)
this.powerOn_prev = powerOn
Last edited:
Anthony, thanks! Finally someone trying to address all the void and contradictions and confusion that is NOT mentioned in documentation, samples or most of the community code out there. Your mindset is exactly what I've been looking for as I started to dig into the world of HTML gauges in MSFS.

Some thoughts on various things covered in your tutorial and what I've learned so far (or at least believe I have learned):

  1. I believe it is possible to write some JS code to make loading of the gauge in browser vs in MSFS automatic. However, it's not a walk in the park for the causual (or newbie) JS coder. It also clutter the instrument code with logic that only deals with this and is not relevant for the gauge itself. In other words, just because it's possible I'm not convinced it's a good idea - or at least not for everyone. Example of a project that seems to go in this direction is the FSKneeBoard project that can be found on GitHub as well.
  2. A solution I'd like to explore but don't have time or knowledge for (yet) is to create some sort of templating mechanism. Not sure how, but conceptually to make dev easier by generating either the browser version or the MSFS version from a common template base. In that way, the resulting files are not cluttered with irrelevant code but you can focus on functionality of the gauge. Just an idea, not sure if this is worth the effort.
  3. Your lists of must-follows and doesn't matters are gold. For instance - I was under the impression that file sizes in the layout files work as some sort of basic safety/signature check and that wrong sizes will prevent loading. While this might not be true, I can imagine that it might change over time? Another thing I got the sense of that it was important but not to what extent is naming and what needs to be matching what. A third thing is the need for specific directory structure - which seem to be relevant if overriding an existing gauge - but not if doing a standalone one (?).
  4. Work flow is discussed in at least one separate thread here and it's another thing that's just not mentioned in docs or samples. Not only that, what needs to go where and why when "compiling" a package is quite undocumented. Bits and pieces here and there but that's it. You cover parts of it but I believe there's much more to discover or discuss.
My thoughts are that many things depends more on what you wanna do, what your specific needs are for your gauges. There are plenty of examples, samples and projects showing off how how things can be done. What's missing is a summary of up-to-date info on what is needed to be in place, when it's needed, why it's needed (or not). Still, this tutorial of yours is a gold mine, again - thanks!
Hello. I am trying to see where is that Html_UI folder but I don't find anything @AlienMudPig said that he found something similar, but didn't reply what (I hate when that happens, because we don't have the clue to continue), but the truth is that or something changed or don't now where to look for.
In my case I installed MSFS in an external drive. My C: installed folder have this:

as you can see. nothing of html_ui, even I navigate in each one of those folders. Same if I open the project in developers mode in MSFS.
And my installed directory neither has anything like that. only the asobo-aircraft.... and fs-base or microsoft-aircraft type folders

A help would be appreciated! Thanks!

I have found some html_ui folders in the place where I chose MSFS to be instaled inside several planes, but I suppose the one that I have to choose is more generic, which I have some to choose:

is one of these ones? Thanks!

Edit2: I don't think those are the ones because they are 160mb. Maybe the most heavy is 3mb....
I was watching this video:
but I don't know where to fidn those fs-base-onboarding fs-base-ui. If I look to my folders I have none of them. Just the most similar ones is fs-base-ui-pages where there is an html_ui but don't have anything of that shown..
So I believe all that is said here, is changed in one of the multiple updates we had (for xbox) so, must be one xbox protection to not be hacked Asobo was talking about in the last video...

At the end I want to make my own instruments and fmc, but I don't have any clue and documentation about it..... Frustrated.
Last edited:
I am trying to see where is that Html_UI folder

What is it you're trying to do? Develop a new plane? Edit an existing plane? Just read some of the content of existing html/js gauges ?

Each plane in MSFS is structured as a "package". The default install 'Packages' directory can be found as at the end of this post, but when you install MSFS you actually get an opportunity to specify any location for your Packages directory, and a smart approach is to install a new NVMe solid-state drive and choose that as your Packages install location (probably too late for you to do that though).

The 'Packages' directory has two sub-directories Official and Community.

All the Asobo packages (e.g. every stock aircraft, packages purely holding html/js code, packages relating to core aspects of the sim) go into the Packages/Official directory.

All of your freeware/3rd-party installs go into the Packages/Community directory.

Note that the packages are pretty much anything someone is going to add to the sim, e.g. aircraft, scenery, other sim objects.

There is a difficult thing to comprehend, which is ALL the installed packages (Official and Community) are actually combined into a common 'Virtual File System' when the sim is running. To understand that better you'll need to dive into the SDK docs but the basic idea is actually pretty simple once you get it.

Anyhoo, there isn't ONE html_ui directory, there are html_ui directories scattered all over the Official and Community packages, and these are all (virtually) merged into a single html_ui directory tree as far as the sim is concerned when it's running. This allows planes to access their own unique instruments (because the plane name is in the folder path somewhere) but also any package can access files from any other package, so e.g. Asobo planes can share a common set of html/js gauges.

So it will help if you explain your use case.

If you want to read the html_ui directory of a particular aircraft, then look in that aircraft panel.cfg, see which folder path is given for the instruments (that's assumed to be in the html_ui tree), and then find by trial and error (or a search tool) which package contains the content for that particular path (asobo-vcockpits-instruments is a good start for stock Asobo planes).

If you are going to create a new aircraft, with new custom instruments, then you'll include an html_ui tree in your project, with a unique directory path to the instruments (i.e. one of the sub-folders will be the name of your aircraft), and all your html and js code will be in your unique folder structure.

If you create a 3D model that you can shoe-horn an existing MSFS 'Official' html/js gauge into, then reference that official gauge directly in the panel.cfg for your aircraft, similar to how the stock Asobo planes do it.


For the Windows Store install:​

C:\Users\[Your User Name]\AppData\Local\Packages\ Microsoft.FlightSimulator_8wekyb3d8bbwe\LocalCache\Packages\

For the Steam install:​

C:\Users\[Your User Name]\AppData\Local\Packages\


Important: Windows 10 by default hides the “AppData” folder, so you will have to go to “View” in the menu of File Explorer, and select “Hidden items” so as to see it.
Thanks for the deep explanation.
I am trying to make a new plane. I come from XPlane11 and have a Marchetti there that I am converting into MSFS:

But I also have a CL415 that I have almost modelled but it has displays that need custom gauges and custom fmc.
For that reason I see there are two ways of doing this: C++ which I can do something but not so much when I have to draw something on geometry...
and HTML. I know some HTML and javascripts but looking the existing examples I can more or less mimic and learn to may my owns.

For that reason I chose to possible use the HTML_UI, but in 1.5 years still Microsoft nor Asobo did anything to explain it. And their tutorials are just few, and don't explain to much how to start from zero with this.
Then I saw this post, and was an open door for me. But start bad as I cannot find those necesary files to compile or see my custom gauges in html browsers. So I cannot start to learn and make a basic square moving, or text appearing with Div layers.
So I am stuck.
I go to the area you say in window store (C:\Users\[Your User Name]\AppData\Local\Packages\) and yes, I do have inside one Community and one Official. but inside both are blank.


Those folders are inside my install MSFS directoy
and of course I used the community one to test my SF260, so I know more or less how that works in MSFS. But I have no idea how to create my custom displays and fmc.

I only need the first "push" to start with my work and imagination.