Static Page.
Obligatory Warning Messages: The main purpose of this documentation is to speed up development times by providing a shortcut for theme authors. It is expected that you are familiar with manually identifying and editing already installed extension packages, as well as (re)creating your own packages from scratch. If you’re not familiar with how Firefox deals with extension packages or are not comfortable with potentially crashing or damaging things, then this page may not be for you.
At present this documentation has been verified to work with Firefox 2 and might also work with 1.5. Methods described here may not be fully compatible with previous versions of Firefox or other Mozilla projects at all. In fact, there are no guarantees that methods described here will work at all. So just to reiterate, anything you do beyond this point does have the potential of ruining your extension or damaging your Firefox installation. Please use your best judgment and always make a complete (before YOU screwed it up) backup of your work.
YOU HAVE BEEN WARNED!
After getting back into the habit of theming and a few failed attempts at finding a faster method to apply updates without repackaging, I gave up and resorted to the tried and true standard method. The standard method of course consisting of repacking and overwriting my old extension package with a new one, which after a while grows into a separate task of it’s own. So while familiarizing myself with all the theme changes made between 1.0 & 2.0 (a ton!), I asked around for a week if anyone remembered if such a shortcut existed. Unfortunately, no one I asked remembered how to do this until Anders figured it out while working on his own extension then presented me with a working example.
Coincidentally this semi-live editing solution existed long before, but it was only useful for working with extensions since themes for Firefox 1.0 did not support chrome.manifest files. Instead themes relied upon a contents.rdf and packages for themes were left untouched upon installation, so creating edits upon an installed theme was inherently difficult to nearly impossible. Since Firefox 1.5 finally introduced the option to include a chrome.manifest in place of the contents.rdf, now setup for editing a theme after it’s installed has become extremely simplified.
Don’t be mistaken, the methods described here haven’t made the process of actually making your theme any easier or doing the packaging for you. But what the method does allow for is letting you skip the painful and repetitive task of having to repackage your entire theme just to see the changes. Further to the point of it all: After packaging and installing your development theme, you’ll then be able to edit your theme directly within your profiles /extensions/ subdirectory. After that, all you’ll have to do is restart Firefox to see your changes.
The old method of editing after creating your initial package and installing:
External Edit > Repackage > Overwrite Installed Package > Restart Firefox
The described method after creating your initial package and installing:
Internal Edit > Restart Firefox
One extension I found very useful for development is the Quick Restart Extension by Juan C. Avila. After making any kind of extension or configuration changes to Firefox, this works as a good shortcut to bring Firefox back up just the way you left it before the restart. Open tabs and all, enough said.
Another small tweak you can make within your about:config, is enabling the install button within your Add-ons window. Locate the following value: extensions.hideInstallButton and change it to false. After a quick restart, access your Add-ons window and you should find a new install button next to the “find updates” button. Installing extensions and themes from a local source just became slightly easier.
Understanding how this works means you should understand the basics of how Firefox treats and installs extensions in the first place. But since that’s something which can be read about in other documentation, I’ll sum up exactly how this process works: A little simple organization, proper path values and installation packages. The one value which makes the real difference between our two packages is the path/to/our/files and how we use them, the /chrome/ directory also helps by keeping things organized.
When you package your theme for a typical release, depending upon how you do things you may just archive the entire folder as is without thinking much about it. What you may not know is exactly how that package is being treated upon install and startup with that theme in use. When you “double-bag” (archive within an archive) your package for release and write out a chrome.manifest to reflect that archive, upon first install of your theme Firefox will read the chrome manifest and extract files accordingly.
Firefox first extracts the necessary set of files from your final package which it needs to register your theme. These files are then placed into your extensions root directory under the unique id you specified which is then registered. These files are the manifest, install.rdf, icon and preview PNG images. The child archive is then moved over to the /chrome/ directory. When you find your package contents in your extensions directory after they have been installed, the folder structure should look exactly like it did before you packaged it.
Basically by altering the package and it’s paths within the manifest, we’re able to tell Firefox the package is to be extracted entirely instead of simply extracted then moved. So once the theme is installed this way, it can then become the primary working folder. You’ll still want to keep the initial packaging folder for finalizing your theme and using it for backing up your new development folder. There is only one small hitch within our newly installed “working folder”, and that is noticed when making any changes to files above the /chrome/ directory which won’t be seen without a complete reinstallation of the theme.
After selecting a desired name for your theme, you’ll want to adjust your workspace to take advantage of this packaging method if you’re not already using it. For the sake of this documentation I’ll be using examples based off of my own workspace layout to set things up and we’ll be working on an already extracted classic.jar. Where you decide to take it after this is entirely up to you.
For starters, You’ll want to create two separate directories for the single theme you’re creating. One for initially installing the development package, and the other for final releases. Since we’re working with the classic.jar, we’ll be naming the two directories “/classic.dev/” and “/classic.release/” within our main “Firefox2″ folder workspace. I’ll also be referring to them as “.dev” and “.release” as well.
Here is a fairly simple illustration of how the two directories would look in a branched out in the main project directory view on the left. And with the files and other folders they have in common in a side by side view in the center and on the right.

While you can still include a contents.rdf file to support legacy themes for older versions of Firefox, I won’t be explaining how to include them in this documentation at the present. However if you don’t plan on having your theme support previous versions of Firefox prior to version 1.5, then you should familiarize yourself with the simplified plain text chrome.manifest which can now be used. You can then quit having to deal with the now deprecated contents.rdf all together.
skin browser My_Theme jar:chrome/myTheme.jar!/browser/
skin communicator My_Theme jar:chrome/myTheme.jar!/communicator/
skin global My_Theme jar:chrome/myTheme.jar!/global/
skin help My_Theme jar:chrome/myTheme.jar!/help/
skin mozapps My_Theme jar:chrome/myTheme.jar!/mozapps/
The final choice is really up to you. But it’s really whether or not you would rather manage something complex as this contents.rdf example, or the simple chrome.manifest example like the one above.
Using the above example chrome.manifest as a base, later we’re going to create from it two distinct chrome.manifest files of our own. While you should really read the chrome registration documents for a more thorough understanding, I’m just going to simplify it by taking the important pieces we need to build our packages. In order for your theme to install let alone work correctly you’ll need to specify the required install.rdf property “internalName“.
<em:internalName>MYinternalName</em:internalName>
The following example is taken straight from the chrome registration documentation and has been slightly modified to accompany the previous example. Since we’re working with a theme, all of our lines will begin with the skin declaration. The packagename attribute will tell Firefox exactly which packages we are referencing, the rest should be fairly self-explanatory.
This example would be suitable for an open folder working theme package.
skin packagename MYinternalName path/to/files
While this example would be more suitable for a double-bagged release package.
skin packagename MYinternalName jar:path/to/YourjarsName.jar!/files
This internalName value remains just that, “internal” and will only seen by you the author. Unless someone should happen to crack open your archive, in which it shouldn’t need to be anything secret. Its value should remain unique to the project but should not contain any spaces as that would introduce errors into your manifest which would later be misread by Firefox upon installation of said theme. I suggest keeping this value short and simple: 0-9A-Za-z, but if you feel like you need spaces use a dash or underscore instead.
By now, you should have already located and finished extracting the chrome into the folder structure recommended in the beginning of this documentation. All the relevant classic.jar files and folders should already be extracted into your “classic.dev” directory. One of the first things you will notice is that the installed classic.jar does not include it’s own install.rdf, chrome.manifest or contents.rdf files, we’ll need to build these from scratch.
For the moment, the /chrome/ directory within your “.release” directory should remain empty. The only files we will need to create in the root “.release” directory with are the chrome.manifest and install.rdf files. For the time being you can copy the preview and icon PNG files over to your root “.release” directory or create new ones if you wish.
After all of that is organized and set we’ll want to create our main install.rdf file which will be used within both of our packages. And since we’re using the default Firefox theme we’ll want to credit it accordingly. For this example I’ll be using the internalName value of “myclassictheme”.
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:name>Firefox (Default "Development Package")</em:name>
<em:id>{0c14551c-a3b3-42d0-b0a4-adcde0da5f93}</em:id>
<em:internalName>myclassictheme</em:internalName>
<em:version>Dev.Version</em:version>
<em:type>4</em:type>
<em:description>A short description about our theme.</em:description>
<em:creator>Gerich and Horlander</em:creator>
<em:contributor>Mozilla Contributors</em:contributor>
<em:homepageURL>http://www.mozilla.org/</em:homepageURL>
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!-- Firefox -->
<em:minVersion>2.0</em:minVersion>
<em:maxVersion>2.0.0.*</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>
If you do decide to use this for your own theme, make sure you create your own unique id and internalName values if you do decide to upload your final theme to the add-ons directory. Feel free to also edit the name, version, creator, contributor and the description attributes as well. Once you’re satisfied with all your changes save and copy it over to the “.release” directory. Next create two blank chrome.manifest files, one for the “.dev” directory and the other for the “.release” directory.
The chrome.manifest in our “.dev” directory will look like this:
skin browser myclassictheme chrome/browser/
skin communicator myclassictheme chrome/communicator/
skin global myclassictheme chrome/global/
skin help myclassictheme chrome/help/
skin mozapps myclassictheme chrome/mozapps/
And the chrome.manifest in our “.release” directory will look like this:
skin browser myclassictheme jar:chrome/classicrel.jar!/browser/
skin communicator myclassictheme jar:chrome/classicrel.jar!/communicator/
skin global myclassictheme jar:chrome/classicrel.jar!/global/
skin help myclassictheme jar:chrome/classicrel.jar!/help/
skin mozapps myclassictheme jar:chrome/classicrel.jar!/mozapps/
Once you save the files out to their correct directories, you’re almost done. Now within your root “.dev” and “.release” directories you should now have 4 files and 1 directory each: One /chrome/ directory, a chrome.manifest file, an install.rdf file, one preview.png and one icon.png. If everything checks out, you’re good to move onto the next step: packaging.
If you’ve managed to read this far, packaging your theme will be more or less of the same to what you’re already familiar with. The only exception here is the need for having to repeat the process during the development stage, so lets get it over with. For the sake of consistency we’re going to be keeping our /chrome/ directory across both packages. The only extra step we’re going to have to take now is creating not a total of two, but three final packages. Yes, my math is correct; three packages.
Up until now you’ve noticed that the /chrome/ directory within “.release” has been left empty, and this is where the first of the three final packages comes in. For the sake of example you’ll want to package up a copy of the /chrome/ directory within “.dev“, and then move it over to our /chrome/ directory within “.release“. The name of this /chrome/ package will be named the same as we specified in the chrome.manifest we created above for “.release“, that name being: “classicrel.jar” without the following exclamation mark.
Now that the contents of each directory have been prepped accordingly, go ahead and pack each one up with paths intact. The final names of these packages is your choice, so long as you can remember which is which during the next step. If you’ve packaged things correctly and take a look at the contents of your two new .jar files, you should have a structure which contains the contents and directories of all your files without the paths which lead up to them.
Now that your packages are built, it’s time to test how successfully they install themselves and function after they’re selected. If you used the unique id provided in the examples you’ll want to install, select, test then uninstall the themes one at a time. But if you were daring enough to improvise along the way and created a different unique id for each install.rdf then you should be able to install the packages side by side.
If both packages install and work correctly, congratulations you’re done. You’ll now want to only install the “.dev” package and locate its id within your profiles extension directory. From here you should be able to make changes to all image and css files within the /chrome/ directory, after making a change restart Firefox to see your changes.
Now since your profiles extensions directory becomes your primary workspace, you’ll want to be extremely careful what edits you make. You should also keep your previous workspace folders around for backups and final releases if you don’t plan on creating a new directory for that purpose. If for any reason you need to add more paths or alter the contents above /chrome/ later, you’ll need to uninstall, make your edits, repackage and then reinstall your development theme again. While you can make those changes when the theme is installed, they just won’t appear until you install them again.
I have also included two finished example packages which I had planned on using exclusively but instead saved them for last to describe the method more fully. If you wish you can examine their structure and contents but keep in mind of the several changes I have made to them. While these examples have worked on my own Firefox installation, I make no guarantee they will work on yours.
Just to make things clear, these packages are intended for example purposes only and will not be endorsed or supported by myself or The Mozilla Foundation. While you are free to use them as a base for your own theme, you should be seriously altering how your theme and its details appear at the end.
The “classic.dev” example can be downloaded from here, and the “classic.release” example can be found here. You should be able to install these packages side by side as seen within the following image, take note I have made several changes between packages.

If you’ve installed these packages, wander into your profiles extensions directory to spot the differences. Below is a list of most if not all the changes I’ve made beyond the icons having a different color. The contents of the /chrome/ directory are identical apart that one has been double-bagged for release while the other has not.
Internal names used:
classicdev - Used for the development package.
classicred - Used for the release package.
Changes made throughout the install.rdf:
Internal Name:
<em:internalName>classicrel</em:internalName>
<em:internalName>classicdev</em:internalName>
Theme Name:
<em:name>Firefox (Default "Developer Package")</em:name>
<em:name>Firefox (Default "Release Package")</em:name>
Version Numbering
<em:version>Dev.Version</em:version>
<em:version>1.9</em:version>
Unique Id for each package
{0c14551c-a1b1-4151-87cc-1c9bf6b3da83} - Dev
{0c14551c-a2b2-42d0-b0a4-adcde0da5f93} - Release
The chrome.manifest differences:
skin browser classicdev chrome/browser/
skin communicator classicdev chrome/communicator/
skin global classicdev chrome/global/
skin help classicdev chrome/help/
skin mozapps classicdev chrome/mozapps/
skin browser classicrel jar:chrome/classicrel.jar!/browser/
skin communicator classicrel jar:chrome/classicrel.jar!/communicator/
skin global classicrel jar:chrome/classicrel.jar!/global/
skin help classicrel jar:chrome/classicrel.jar!/help/
skin mozapps classicrel jar:chrome/classicrel.jar!/mozapps/
It goes without saying that you’re going to run into a few if not many problems while using this or any other method for theming or packaging. And without knowing the exact cause or having a good description of the problem it would be impossible to tell what went wrong. I can only tell you to uninstall the theme or extension in question, check changes you’ve made, and try again.
There is one common issue you will likely run into upon installing a new theme if it’s been improperly packaged. After selecting an installed theme like this and restarting Firefox, Firefox might appear crashed, destroyed, or broken and completely unresponsive upon startup and you can’t find a clean way to shut it down. The only way of exiting is by having to manually kill it’s process from within your process manager. Seem familiar?
This is usually the result of specifying improper paths for your theme and where safe mode comes in to save the day. However, before entering safe mode you’ll want to check your themes extension folder within your profile and see if things check out. Check your chrome.manifest and the contents of the /chrome/ directory to see if it was created and the right files from your package were extracted correctly.
Once you’ve located the problem, you’ll want to correct it within your original workspace files and create a new package. Then simply enter safe mode within Firefox, uninstall the previous package while selecting a theme you know works and try again.