# Extending SMF

The modules of SMF are ordinary Dart packages built on [`smf_contracts`](https://pub.dev/packages/smf_contracts). A module of yours follows the same rules and goes through the same checks as the built-in ones. The pages of this section show how to write one, test it and generate apps with it.

## What you can write

- A feature has screens with their routes and their state for each state manager, and gets its services through dependency injection. It can keep the user from the rest of the app with a guard, and ask for a condition, such as an account, on the routes that need one. See [Write a feature module](https://doc.saymyframe.com/extending/feature-module.md).
- An infrastructure module sets up a library or a service with start-up code, native settings, dependencies, checks of the machine, commands that run after generation and the steps that only the developer of the app can do. See [Write an infrastructure module](https://doc.saymyframe.com/extending/infrastructure-module.md).
- A module of either kind can have a setting that the app remembers and shows on its settings screen, a step of the onboarding, texts in the languages of the app, and notes for the coding agents that work on the app. See [Add a setting](https://doc.saymyframe.com/extending/settings.md), [Add a step to the onboarding](https://doc.saymyframe.com/extending/onboarding-steps.md) and [Texts](https://doc.saymyframe.com/extending/texts.md).
- A provider of a role can be another router, DI container, state manager or layout, a service for analytics, crash reporting, events, preferences, notifications, push messages or purchases, sign-in, a settings screen, an onboarding, a theme, the texts of the app, or the values of `.env`. See [Provide a role](https://doc.saymyframe.com/extending/role-provider.md).
- A new role is a replaceable part of an app that SMF does not have yet, with its sockets, its template, its options and its rules. See [Define a role](https://doc.saymyframe.com/extending/new-role.md).

Before you start, read [the module model](https://doc.saymyframe.com/concepts/module-model.md) and [module independence](https://doc.saymyframe.com/concepts/independence.md), since the rules that the pipeline enforces follow from them.

## How a module reaches an app

`smf` offers a fixed list of modules. To generate apps with a module of yours, build a command of your own on `smf_flutter_cli`, which exports the command line as `runCli` and its modules as `smfModules`:

```dart title="bin/my_smf.dart"
import 'dart:io';

import 'package:smf_counter/smf_counter.dart';
import 'package:smf_flutter_cli/smf_flutter_cli.dart';

Future<void> main(List<String> arguments) async {
  final code = await runCli(
    arguments,
    modules: const [...smfModules, CounterModule()],
  );
  await Future.wait<void>([stdout.flush(), stderr.flush()]);
  exit(code);
}
```

The command has every option and question of `smf create`, and it offers your module next to the built-in ones:

```bash
dart run bin/my_smf.dart create my_app -m home,counter,bottom_tabs,bloc
```

A module that many apps need can also become part of SMF itself; see [Contributing](https://doc.saymyframe.com/contributing.md). [Publish and use a module](https://doc.saymyframe.com/extending/publishing.md) covers both ways.

## The pages of this section

1. [A module package](https://doc.saymyframe.com/extending/module-package.md) covers the layout of the package, its bricks and their bundles.
2. [Write a feature module](https://doc.saymyframe.com/extending/feature-module.md) builds a counter screen with BLoC and Riverpod variants from start to end, declares a guard, and asks for a condition on a route.
3. [Write an infrastructure module](https://doc.saymyframe.com/extending/infrastructure-module.md) covers sockets, dependencies, notes for coding agents, checks of the machine, steps after generation and steps by hand.
4. [Add a setting](https://doc.saymyframe.com/extending/settings.md) builds a module with a setting that the app remembers and shows on its settings screen.
5. [Add a step to the onboarding](https://doc.saymyframe.com/extending/onboarding-steps.md) gives the onboarding a page of a module, such as one that asks for a permission.
6. [Texts](https://doc.saymyframe.com/extending/texts.md) covers the texts of a module in the languages of the app.
7. [Provide a role](https://doc.saymyframe.com/extending/role-provider.md) covers plain providers, service roles, listeners of the router and providers that render the data of their role. Pages of their own cover [the guards in a router](https://doc.saymyframe.com/extending/router-guards.md) and four more roles: [the settings screen](https://doc.saymyframe.com/extending/provide-settings-screen.md), [the localization](https://doc.saymyframe.com/extending/provide-localization.md), [the theme](https://doc.saymyframe.com/extending/provide-theme.md) and [sign-in](https://doc.saymyframe.com/extending/provide-auth.md).
8. [Define a role](https://doc.saymyframe.com/extending/new-role.md) covers sockets, the interface, the template, options and their modes, warnings, conditions on a choice, conditions for routes and rules.
9. [Templates](https://doc.saymyframe.com/extending/templates.md) lists the rules of the bricks.
10. [Test a module](https://doc.saymyframe.com/extending/testing.md) covers the contract harness and the checks of the package.
11. [Rules for modules](https://doc.saymyframe.com/extending/rules.md) is a checklist.
12. [Publish and use a module](https://doc.saymyframe.com/extending/publishing.md) explains how a module reaches users.

The API reference of every type is on pub.dev: [`smf_contracts`](https://pub.dev/documentation/smf_contracts/latest/) for the module model and [`smf_pipeline`](https://pub.dev/documentation/smf_pipeline/latest/) for the harness.
