• Skip to main content
  • Select language
  • Skip to search
MDN Web Docs
  • Technologies
    • HTML
    • CSS
    • JavaScript
    • Graphics
    • HTTP
    • APIs / DOM
    • WebExtensions
    • MathML
  • References & Guides
    • Learn web development
    • Tutorials
    • References
    • Developer Guides
    • Accessibility
    • Game development
    • ...more docs
Add-ons
  1. MDN
  2. Mozilla
  3. Add-ons
  4. Extension Etiquette

Extension Etiquette

In This Article
  1. User Interface
    1. Tools menu items
    2. Other UI elements
    3. Focus
    4. About dialogs
    5. Theming
    6. Extension icons
  2. Coding practices
    1. Namespace conflicts
  3. Names and Metadata
    1. Naming
    2. Descriptions
    3. Documentation
    4. IDs
    5. Version numbering
  4. Internationalization
    1. Locales
    2. Options
    3. Preferences' internal names
  5. General
    1. Dependencies

Add-ons using the techniques described in this document are considered a legacy technology in Firefox. Don't use these techniques to develop new add-ons. Use WebExtensions instead. If you maintain an add-on which uses the techniques described here, consider migrating it to use WebExtensions.

From Firefox 53 onwards, no new legacy add-ons will be accepted on addons.mozilla.org (AMO).

From Firefox 57 onwards, WebExtensions will be the only supported extension type, and Firefox will not load other types.

Even before Firefox 57, changes coming up in the Firefox platform will break many legacy extensions. These changes include multiprocess Firefox (e10s), sandboxing, and multiple content processes. Legacy extensions that are affected by these changes should migrate to WebExtensions if they can. See the "Compatibility Milestones" document for more.

A wiki page containing resources, migration paths, office hours, and more, is available to help developers transition to the new technologies.

This article describes best practices when making extensions, including how to be kind to your users. It assumes that you are already familiar with Building an Extension.

User Interface

Tools menu items

Using the Tool menu option gives the author the maximum amount of choices. Whether the extensions should go at the top, bottom, or somewhere in between on the Tools menu, the author always has a choice. Ideally, the location would be below the Add-ons item, grouped with the other extension-related commands (menuitem:insertafter="javascriptConsole,devToolsSeparator"). Sub-menus should be used for single extensions needing multiple menu items, and a Tools menu item should not be created for options and preferences (for options and preferences, see the add-on manager). If possible, create a menu item in the menu where it is most applicable; for instance, a bookmark sharing extension should be called from the Bookmarks menu. To maintain the default theme, avoid the use of an icon next to the menu items.

Other UI elements

In general, toolbar items are very useful to end users because they can be removed or added to various toolbars as necessary. Status bar items should only be added for extensions that need constant monitoring, such as ad blocking, page ranking, or cookie management. Likewise, use context menu items sparingly — only for tasks that are done frequently or on specific elements of a web page.

Focus

Don't steal focus. It's not your extension's job to take focus from the web content. If the user loads a website and they ask for focus, they should get it. Overriding their request isn't very nice.

About dialogs

There is a default popup About dialog that is created from install.rdf data; creating a new XUL About box is usually unnecessary. You can decrease download size by omitting a customized About box. Make one only if you have a special feature that needs to be included — for example, a custom updater.

Theming

If you have XUL buttons in your extension that do functions similar to ones that already exist in a browser — for example, a feed reader that reloads and stops — use icons from the browser's theme. The icons makes the extension lighter, while providing more consistency, especially for users using different themes.

Extension icons

Unique icons are usually worth their download weight. They allow for easy identification among other extensions in the Extensions manager.

Coding practices

Namespace conflicts

There are many namespaces which extensions often must share with other consumers, be they other add-ons, web code, or the browser itself. These often include areas such as:

  • Object prototypes, such as String.prototype, which are often extended to add methods to native objects.
  • Global variables, such as top-level declarations on scripts loaded into shared windows or web pages.
  • Expando properties of shared objects, such as document objects, or DOM nodes.
  • IDs and class names in HTML and XUL documents, when extensions add elements to web pages or browser windows.
  • chrome: or resource: packages, which are often defined in chrome.manifest files.
  • about: page URLs.
  • XPCOM contract IDs, which are often registered in chrome.manifest files.

While these are among the most common examples of namespaces in which conflicts can occur, there are many others. In general, care must be taken whenever defining a name anywhere that other code might do likewise. Strategies to avoid such conflicts include:

Avoid shared namespaces where possible
Many naming conflicts are best avoided by simply not sharing namespaces. Scripts can be loaded into their own globals, such as CommonJS modules, JavaScript modules, or Sandboxes, to avoid most global variable and prototype conflicts. Expando properties are best avoided using tools such as WeakMaps.
Prefix names in shared namespaces

When shared namespaces can't be avoided, the simplest solution to prevent conflicts is to use a distinct prefix for all of your names. Class names for HTML elements created by the Cool Beans extension, for instance, might all be prefixed with cool-beans-. Global variables might all be defined as properties of the CoolBeans object.

Some namespaces have specific conflict prevention conventions, which should be followed as appropriate. XPCOM contract IDs, for instance, should always begin with an @, followed by a domain name that the author controls, e.g., "@example.com/foo/bar;1"

It is important that the prefix that you use be unlikely to conflict with other code, and that it be indicative of the name of your add-on. Generic prefixes such as myextension-, or short prefixes such as ffx-, are likely to be used elsewhere, and therefore unsuitable to the purpose.

Call .noConflict(true) where applicable

Many common libraries which create global variables provide a method called noConflict, or similar, which revert any global variables they've declared, and return the object itself. For instance, calling jQuery.noConflict(true) will remove the window.jQuery and window.$ variables, and return the jQuery object itself, for future use by the caller.

When available, these methods should always be used to prevent conflicts with third-party code.

Names and Metadata

Naming

Be creative! Don't be redundant and include "extension," "Mozilla/Firefox/Thunderbird," or the version number in the name. Be original!

Descriptions

Use something that is descriptive, but that would fit in the default add-on manager width. The Mozilla extensions (Inspector/Reporter/Talkback) believe starting with a verb is the best way. For example, "Does an action in the browser."

Documentation

Assume that the vast majority of your users don't have inner working knowledge of Mozilla. Make sure your extension's homepage states the "obvious," including the purpose of your extension. Users also appreciate when your extension is shipped with a simple how-to document.

IDs

Firefox/Thunderbird 1.5 or later are much more strict about the IDs of extensions than their 1.0 counterparts. Make sure they're valid.

Version numbering

Please follow the Mozilla pattern: major version dot current incarnation dot security/bugfix release (like 1.0.7).

Internationalization

Locales

Always use locale DTDs and property files, even if providing your extension in one language. It will make translation of your extension to another language easier. It occurs more often than you would think.

Options

Firefox users like options. Lots of options. Try to include everything a user could ever want to customize in your extension, remembering more can be added later. For a large number of options for your extension, break the options window into multiple pages (tabs) that are well labeled. Don't hesitate to give long descriptions for each preference, as long as they are easy to understand, even for non-computer-savvy users. However, please make sure the default set of preferences is adequate — don't require people to tweak options in order to get your extension's core functionality.

Preferences' internal names

Internal Firefox preference names for extensions or to be clear, the name of the preference as it appears in the about:config, should start with "extensions.," then the name of the extension, with a dot, then the name of the preference. For instance, a boolean for the Reporter extension's option for hiding the privacy statement is "extensions.reporter.hidePrivacyStatement".

General

Dependencies

Requiring a user to download another extension in order to use yours isn't nice. Avoid the dependency on other extensions, especially extensions that you didn't develop.

Document Tags and Contributors

Tags: 
  • Add-ons
  • Extensions
  • Guide
 Contributors to this page: bunnybooboo, wbamberg, kmaglione, kscarfone, ishita, Pesh_Mode, liaskin, maybe, jswisher, MarkDilley, Sheppy, charron12, Ryanerasure, Goofy, Another sam, Gomita, GdzSir, Taken, Mgjbot, Ted_Mielczarek, Ssmedberg, NickolayBot, Peterdawson, MarbleheadMan, Nickolay, Dfarning, Dria
 Last updated by: bunnybooboo, Apr 20, 2017, 5:05:28 PM
See also
  1. WebExtensions
  2. Getting started
    1. What are WebExtensions?
    2. Your first WebExtension
    3. Your second WebExtension
    4. Anatomy of a WebExtension
    5. Example WebExtensions
  3. How to
    1. Intercept HTTP requests
    2. Modify a web page
    3. Add a button to the toolbar
    4. Implement a settings page
  4. Concepts
    1. Using the JavaScript APIs
    2. User interface components
    3. Content scripts
    4. Match patterns
    5. Internationalization
    6. Content Security Policy
    7. Native messaging
  5. Porting
    1. Porting a Google Chrome extension
    2. Porting a legacy Firefox add-on
    3. Embedded WebExtensions
    4. Comparison with the Add-on SDK
    5. Comparison with XUL/XPCOM extensions
    6. Chrome incompatibilities
  6. Firefox workflow
    1. Temporary Installation in Firefox
    2. Debugging
    3. Getting started with web-ext
    4. web-ext command reference
    5. WebExtensions and the Add-on ID
    6. Publishing your WebExtension
  7. JavaScript APIs
    1. Browser support for JavaScript APIs
    2. alarms
    3. bookmarks
    4. browserAction
    5. browsingData
    6. commands
    7. contextMenus
    8. contextualIdentities
    9. cookies
    10. devtools.inspectedWindow
    11. devtools.network
    12. devtools.panels
    13. downloads
    14. events
    15. extension
    16. extensionTypes
    17. history
    18. i18n
    19. identity
    20. idle
    21. management
    22. notifications
    23. omnibox
    24. pageAction
    25. privacy
    26. runtime
    27. sessions
    28. sidebarAction
    29. storage
    30. tabs
    31. topSites
    32. webNavigation
    33. webRequest
    34. windows
  8. Manifest keys
    1. applications
    2. author
    3. background
    4. browser_action
    5. chrome_settings_overrides
    6. chrome_url_overrides
    7. commands
    8. content_scripts
    9. content_security_policy
    10. default_locale
    11. description
    12. developer
    13. devtools_page
    14. homepage_url
    15. icons
    16. manifest_version
    17. name
    18. omnibox
    19. options_ui
    20. page_action
    21. permissions
    22. protocol_handlers
    23. short_name
    24. sidebar_action
    25. version
    26. web_accessible_resources
  9. Add-on SDK
  10. Getting started
    1. Installation
    2. Getting started
    3. Troubleshooting
  11. High-Level APIs
    1. addon-page
    2. base64
    3. clipboard
    4. context-menu
    5. hotkeys
    6. indexed-db
    7. l10n
    8. notifications
    9. page-mod
    10. page-worker
    11. panel
    12. passwords
    13. private-browsing
    14. querystring
    15. request
    16. selection
    17. self
    18. simple-prefs
    19. simple-storage
    20. system
    21. tabs
    22. timers
    23. ui
    24. url
    25. webextension
    26. widget
    27. windows
  12. Low-Level APIs
    1. /loader
    2. chrome
    3. console/plain-text
    4. console/traceback
    5. content/content
    6. content/loader
    7. content/mod
    8. content/symbiont
    9. content/worker
    10. core/heritage
    11. core/namespace
    12. core/promise
    13. dev/panel
    14. event/core
    15. event/target
    16. frame/hidden-frame
    17. frame/utils
    18. fs/path
    19. io/byte-streams
    20. io/file
    21. io/text-streams
    22. lang/functional
    23. lang/type
    24. loader/cuddlefish
    25. loader/sandbox
    26. net/url
    27. net/xhr
    28. places/bookmarks
    29. places/favicon
    30. places/history
    31. platform/xpcom
    32. preferences/event-target
    33. preferences/service
    34. remote/child
    35. remote/parent
    36. stylesheet/style
    37. stylesheet/utils
    38. system/child_process
    39. system/environment
    40. system/events
    41. system/runtime
    42. system/unload
    43. system/xul-app
    44. tabs/utils
    45. test/assert
    46. test/harness
    47. test/httpd
    48. test/runner
    49. test/utils
    50. ui/button/action
    51. ui/button/toggle
    52. ui/frame
    53. ui/id
    54. ui/sidebar
    55. ui/toolbar
    56. util/array
    57. util/collection
    58. util/deprecate
    59. util/list
    60. util/match-pattern
    61. util/object
    62. util/uuid
    63. window/utils
  13. Firefox for Android
  14. Getting started
    1. Walkthrough
    2. Debugging
    3. Code snippets
  15. APIs
    1. Accounts.jsm
    2. BrowserApp
    3. HelperApps.jsm
    4. Home.jsm
    5. HomeProvider.jsm
    6. JavaAddonManager.jsm
    7. NativeWindow
    8. Notifications.jsm
    9. PageActions.jsm
    10. Prompt.jsm
    11. RuntimePermissions.jsm
    12. Snackbars.jsm
    13. Sound.jsm
    14. Tab
  16. Legacy
  17. Restartless extensions
    1. Overview
  18. Overlay extensions
    1. Overview
  19. Themes
  20. Lightweight themes
    1. Overview
  21. Complete themes
    1. Overview
  22. Publishing add-ons
  23. Guides
    1. Signing and distribution overview
    2. Submit an add-on
    3. Review policies
    4. Developer agreement
    5. Featured add-ons
    6. Contact addons.mozilla.org
  24. Community and support
  25. Channels
    1. Add-ons blog
    2. Add-on forums
    3. Stack Overflow
    4. Development newsgroup
    5. IRC Channel