android-new-module
SkillDev toolsGuides your agent through creating new Android Gradle modules in the android-components project.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the android-new-module skill
About this capability
Guide for creating new Android gradle modules in the android-components project.
What this skill tells your AI
The instructions your AI receives, as published by mozilla-firefox/firefox in .agents/skills/android-new-module/SKILL.md and read by ahel’s review.
Overview
This skill helps you create new Android gradle modules following Mozilla's conventions and structure. Components are organized into categories: browser, concept, feature, lib, service, support, ui, and compose.
Component Categories
- browser - High-level browser components (engine, menu, state, etc.)
- compose - Jetpack Compose components
- concept - Abstract API contracts and interfaces
- feature - Feature modules for browser functionality
- lib - Standalone libraries (utilities, tools)
- service - Services (push, sync, etc.)
- support - Support/utility modules
- tooling - Support modules for the build or tools.
- ui - UI components; has overlap with Compose components.
Steps to Create a New Component
Create a plan to execute the steps. The plan should include all nine steps below.
1. Determine Component Type and Name
Ask the user:
- What category? (feature, lib, browser, etc.)
- What should it be named? (lowercase with hyphens, e.g.,
my-component) - What will it do? (for description)
- Will it be published to Maven? (most are
publish: true, examples arepublish: false)
2. Create Directory Structure
mkdir -p mobile/android/android-components/components/{category}/{name}/src/main/java/mozilla/components/{category}/{name}
mkdir -p mobile/android/android-components/components/{category}/{name}/src/test/java/mozilla/components/{category}/{name}
mkdir -p mobile/android/android-components/components/{category}/{name}/src/test/resources
3. Create build.gradle
Reference the example at mobile/android/android-components/components/feature/example/build.gradle for the standard structure.
Key elements:
- Apply the
com.android.libraryplugin in theplugins {}block - Set namespace:
mozilla.components.{category}.{name} - Include common dependencies:
androidx.core,kotlinx.coroutines - Include test dependencies:
junit.bom,junit4,robolectric,kotlinx.coroutines.test - Apply common config and publish scripts
Add dependencies as needed:
- Support base (for LifecycleAwareFeature):
implementation project(':components:support-base') - Lifecycle:
libs.androidx.lifecycle.runtime - Compose: Add
platform(libs.androidx.compose.bom)and compose dependencies - State management:
implementation project(':components:lib-state') - Browser state:
implementation project(':components:browser-state') - Other components:
implementation project(':components:{category}:{component-name}')
4. Create AndroidManifest.xml
File: src/main/AndroidManifest.xml
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<manifest />
5. (Optional) Create Main Kotlin Source
File: src/main/java/mozilla/components/{category}/{name}/{ComponentName}.kt
Reference the example at mobile/android/android-components/components/feature/example/src/main/java/mozilla/components/feature/example/ExampleFeature.kt.
Key elements for a feature component:
- MPL 2.0 license header
- Package:
mozilla.components.{category}.{name} - Implement
LifecycleAwareFeaturefor lifecycle-aware features - Use dependency injection for testability (e.g., inject
CoroutineDispatcher) - Include coroutine scope for async operations
- Override lifecycle methods (
start(),stop())
For simpler library components, a basic class with the necessary methods is sufficient.
6. (Optional) Create Test File
File: src/test/java/mozilla/components/{category}/{name}/{ComponentName}Test.kt
Reference the example at mobile/android/android-components/components/feature/example/src/test/java/mozilla/components/feature/example/ExampleFeatureTest.kt.
Key elements:
- MPL 2.0 license header
- Use
StandardTestDispatcherfromkotlinx.coroutines.testfor testing coroutines - Inject the test dispatcher into the component being tested
- Use
runTest(testDispatcher)to run tests with coroutine support - Use
testDispatcher.scheduler.advanceUntilIdle()to advance virtual time - Track actual callback invocations instead of using mocks
- Write descriptive test names using backticks (e.g.,
`start triggers onUpdate callback`) - Use JUnit assertions to verify behavior
7. Create Robolectric Configuration
File: src/test/resources/robolectric.properties
sdk=35
This configures Robolectric to use Android SDK 35 for unit tests.
8. Create README.md
File: README.md
Reference the example at mobile/android/android-components/components/feature/example/README.md.
Key elements:
- Title with breadcrumb navigation:
# [android-components](../../../README.md) > {Category} > {Name} - Brief description of the component
- Usage section with dependency setup
- Code examples showing how to use the component
- MPL 2.0 license footer
9. Register in .buildconfig.yml
Add the component to .buildconfig.yml in alphabetical order within its category:
components:{category}-{name}:
description: {Brief description}
path: components/{category}/{name}
publish: true
Find the correct insertion point by searching for the category (e.g., components:feature- for feature modules) and inserting in alphabetical order.
Then update the upstream_dependencies for the new buildconfig with this mach command:
./mach android update-buildconfig android-components
Also update taskcluster/config.yml to add the new module's display name to treeherder.group-names. Without this step, CI will fail with a buildconfig mismatch error.
Common Patterns
Package Naming
- Pattern:
mozilla.components.{category}.{name} - Example:
mozilla.components.feature.example
Class Naming
- Convert kebab-case to PascalCase
- Example:
my-component→MyComponent
Dependency Types
api- For interfaces and contracts (concept modules)implementation- For internal dependenciestestImplementation- For testing dependenciesandroidTestImplementation- For instrumented tests
Code Style
- Use MPL 2.0 license headers on all files
- Minimal comments (only for non-obvious code)
- Use
@VisibleForTestingfor test-only visibility - Follow Kotlin coding conventions
Verification
After creating the component, verify it builds with the debug variant:
./mach gradle :components:{category}-{name}:buildDebug
Run tests:
./mach gradle :components:{category}-{name}:testDebug
Format and lint:
./mach lint --fix mobile/android/android-components/components/{category}/{name}
Notes
- Always use
./mach gradleinstead ofgradlewto ensure the build system is executed in its entirety. - Component names use kebab-case (hyphens).
- Package names use lowercase without separators.
- Class names use PascalCase
- Set
publish: falsefor example/sample components because we do not want them to be distributed through the maven mirrors. - The module will be automatically included in the build after registering in
.buildconfig.yml.
Signals
- GitHub stars
- 13k
- Forks
- 1k
- Last commit
- Sep 2026
Others that do the same job
Advanced
- Catalog kind
- skill
- Gateway key
android-new-module-mozilla-firefox- Source
- github.com/mozilla-firefox/firefox