Open-Source Wikis

/

Gecko

/

How to contribute

/

Patterns and conventions

mozilla/gecko-dev

Patterns and conventions

Gecko's coding patterns are partly modern, partly legacy. The codebase has accumulated decades of conventions, and you will see all of them depending on which directory you're in.

C++ conventions

Namespaces

  • Old code uses no namespace; types start with ns (nsCOMPtr, nsString).
  • Newer code uses mozilla:: and submodules (mozilla::dom::, mozilla::layout::, mozilla::ipc::).
  • Pure-platform code lives directly in mozilla::.
  • New types should generally go in mozilla::<subsystem>:: rather than the global ns* namespace.

Strings

  • nsAString / nsACString are the abstract base classes for UTF-16 / UTF-8 strings.
  • nsString (UTF-16, owned), nsAutoString (stack buffer + heap fallback), nsLiteralString (compile-time).
  • nsCString (8-bit), nsAutoCString, nsLiteralCString.
  • Avoid std::string and std::wstring in platform code.
  • Headers under xpcom/string/ and mfbt/.

Smart pointers

  • RefPtr<T> for refcounted classes (where T has AddRef/Release).
  • nsCOMPtr<T> for XPCOM interface pointers (nsIFoo).
  • mozilla::UniquePtr<T> (≈ std::unique_ptr).
  • mozilla::WeakPtr<T>.
  • Raw T* is fine for non-owning, non-escaping references.

Refcounting

  • NS_INLINE_DECL_REFCOUNTING(Class) for cheap, single-threaded ref counting.
  • NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Class) for cross-thread.
  • NS_DECL_ISUPPORTS + NS_IMPL_ISUPPORTS(...) for full XPCOM types.
  • Cycle-collected classes use NS_DECL_CYCLE_COLLECTING_ISUPPORTS and NS_IMPL_CYCLE_COLLECTING_ADDREF/RELEASE.

Annotations

  • MOZ_CAN_RUN_SCRIPT — function may invoke JS. Static analysis enforces transitive correctness.
  • MOZ_CAN_RUN_SCRIPT_BOUNDARY — JS boundary stop.
  • MOZ_KNOWN_LIVE — argument is guaranteed live for the duration.
  • MOZ_NEVER_INLINE, MOZ_ALWAYS_INLINE.
  • MOZ_ASSERT(...) — debug-only assert.
  • MOZ_RELEASE_ASSERT(...) — release-mode assert.
  • MOZ_DIAGNOSTIC_ASSERT(...) — release on Nightly/dev, off in release builds.

Error handling

  • Most XPCOM APIs return nsresult. NS_OK is success; NS_FAILED(rv) / NS_SUCCEEDED(rv) to check.
  • Use NS_ENSURE_SUCCESS(rv, ret) and NS_ENSURE_TRUE(...) for early returns.
  • New code prefers mozilla::Result<T, E> and MOZ_TRY(...) (analogous to ? in Rust).

JavaScript conventions

File naming

  • .sys.mjs — JS modules loaded into the system principal (ChromeUtils.importESModule(...)). Replaced the older .jsm extension.
  • .mjs — content-side ES modules.
  • .jsm — legacy module format; in active migration to .sys.mjs.

Module patterns

// Modern (.sys.mjs)
export class Foo {
  /* ... */
}

// Legacy (.jsm)
this.EXPORTED_SYMBOLS = ['Foo'];

Importing

// In chrome / browser code
import { Foo } from 'resource://gre/modules/Foo.sys.mjs';

// Or from a chrome script
const { Foo } = ChromeUtils.importESModule(
  'resource://gre/modules/Foo.sys.mjs'
);

Lazy modules

For startup performance, define lazy getters:

const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
  Foo: 'resource://gre/modules/Foo.sys.mjs',
});

Linting

  • eslint.config.mjs is the entry point. Sub-config files apply per-directory rules.
  • The Mozilla-specific ESLint plugin lives at tools/lint/eslint/eslint-plugin-mozilla/.
  • Run ./mach eslint <path> --fix to auto-fix.

Build files

Every directory that contains source files has a moz.build. Common patterns:

# Sources
SOURCES += ["MyFile.cpp"]
UNIFIED_SOURCES += ["A.cpp", "B.cpp"]  # combined for faster compile
EXPORTS.mozilla.foo += ["MyFile.h"]

# JS modules
EXTRA_JS_MODULES += ["MyModule.sys.mjs"]

# IDL
XPIDL_SOURCES += ["nsIFoo.idl"]
WEBIDL_FILES += ["Foo.webidl"]
IPDL_SOURCES += ["PFoo.ipdl"]

# Subdirs
DIRS += ["sub1", "sub2"]
TEST_DIRS += ["test"]

# Bug component
with Files("**"):
    BUG_COMPONENT = ("Component", "Sub-component")

UNIFIED_SOURCES concatenates files into one translation unit for faster builds; this means symbols you static-define can collide with the next file in the unification.

IDL conventions

  • WebIDL goes in */dom/.../*.webidl. Bindings auto-generated by dom/bindings/.
  • XPIDL .idl files declare XPCOM interfaces; the resulting C++ headers and JS bindings flow through the typelib system.
  • IPDL .ipdl files declare per-protocol IPC actors. Each PFoo.ipdl generates PFooParent and PFooChild C++ classes.

Cycle collection

If a class can hold references that form cycles with other cycle-collected classes (very common in DOM), it must participate in the cycle collector. Use NS_DECL_CYCLE_COLLECTION_CLASS(...) and implement traversal/unlink macros. See xpcom/base/nsCycleCollector.cpp.

Threading

  • The "main thread" is the only thread allowed to touch most XPCOM types.
  • NS_DispatchToMainThread(runnable) to post work.
  • nsISerialEventTarget is the standard type for "thread or thread-pool slot".
  • MOZ_ASSERT(NS_IsMainThread()) is everywhere.
  • For C++ async/await-style code, see mozilla::MozPromise (xpcom/threads/MozPromise.h).

Pref naming

  • branch.subsystem.feature.knob — dot-separated, lowercase, hyphens for words.
  • Defaults defined in modules/libpref/init/all.js and per-component *.js pref files.
  • Read with Services.prefs.getBoolPref("path", default) or StaticPrefs::path() (generated from modules/libpref/init/StaticPrefList.yaml).

Cross-process actors

  • IPDL actors — heavy, full protocol with state machines. Use for performance-critical channels. *.ipdl files.
  • JSActor — declarative, JS-only. Two pieces: a JSWindowActorParent and a JSWindowActorChild. Registered through MessageManager JSON config. See dom/ipc/JSActor.cpp. Most browser chrome uses these.

Linting tools

Tool Scope
clang-format C/C++ formatting
clang-tidy (selected checks) C++ static analysis
eslint + Mozilla plugin JS
prettier JS, CSS, JSON
stylelint CSS
ruff, black Python
rustfmt, clippy Rust
mozlint meta-linter that runs all of the above

Run them all with ./mach lint.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Patterns and conventions – Gecko wiki | Factory