Skip to content

Plugins ​

A plugin is a capability that many features share: networking, storage, sign-in, telemetry and so on. Features use the plugin's contract; the app decides which implementation to plug in. A feature that saves settings never knows whether they land in memory, Hive or shared preferences.

How the pieces fit together

Scroll or pinch to zoom · Drag to move · Esc to close

Every plugin at a glance ​

Vyuh Core ships twelve plugins. Ten have a slot in PluginDescriptor and work out of the box with a sensible default. Two are optional and go in others.

PluginWhat it's forContractDefaultAccessOther implementations
Dependency injectionShare services between featuresDIPluginGetItDIPluginvyuh.diYour own
NetworkingHTTP requests with timeouts and retriesNetworkPluginHttpNetworkPluginvyuh.networkYour own
AuthenticationSign-in, the current user, sessionsAuthPluginUnknownAuthPlugin (signed out)vyuh.authYour provider (Firebase, Supabase...)
NavigationRoutes, redirects, deep linksNavigationPluginDefaultNavigationPlugin (go_router)vyuh.routerYour own
EventsTyped events between features and the platformEventPluginDefaultEventPluginvyuh.eventYour own
StorageKey-value storageStoragePluginInMemoryStoragePluginvyuh.storageHiveStoragePlugin, SharedPreferencesStoragePlugin
Secure storageSecrets such as tokensSecureStoragePluginInMemorySecureStoragePluginvyuh.secureStorageFlutterSecureStoragePlugin
EnvironmentConfiguration valuesEnvPluginNoOpEnvPluginvyuh.envDefaultEnvPlugin (.env files)
AnalyticsProduct analytics and screen trackingAnalyticsPlugin + AnalyticsProviderno-op providervyuh.analyticsYour providers
Telemetry and loggingErrors, traces and logsTelemetryPlugin + TelemetryProviderno-op providervyuh.telemetry, vyuh.logConsoleLoggerTelemetryProvider
Locale and translationsLanguages, translations, device localeLocalePluginnot registeredvyuh.locale (nullable)—
Feature flagsTurn features and behaviour on or offFeatureFlagPluginnot registeredvyuh.featureFlag (nullable)Your provider

The implementation packages:

PackageProvides
vyuh_plugin_storage_hiveHiveStoragePlugin
vyuh_plugin_storage_shared_preferencesSharedPreferencesStoragePlugin
vyuh_plugin_storage_secureFlutterSecureStoragePlugin
vyuh_plugin_telemetry_provider_consoleConsoleLoggerTelemetryProvider

Content and CMS

The content plugin is not part of the core. CMS-driven apps add it from vyuh_extension_content; see the CMS section.

Pick implementations ​

Pass a PluginDescriptor to runApp. Any slot you leave out keeps its default, so you only name what you want to change. Optional plugins and your own go in others.

dart
import 'package:vyuh_core/vyuh_core.dart';
import 'package:vyuh_plugin_storage_hive/vyuh_plugin_storage_hive.dart';
import 'package:vyuh_plugin_storage_secure/vyuh_plugin_storage_secure.dart';
import 'package:vyuh_plugin_telemetry_provider_console/vyuh_plugin_telemetry_provider_console.dart';

void main() {
  runApp(
    plugins: PluginDescriptor(
      storage: HiveStoragePlugin(),
      secureStorage: FlutterSecureStoragePlugin(),
      env: DefaultEnvPlugin(),
      telemetry: TelemetryPlugin(providers: [ConsoleLoggerTelemetryProvider()]),
      navigation: DefaultNavigationPlugin(urlStyle: RouterUrlStyle.path),
      others: [
        LocalePlugin(locales: [/* LocaleConfiguration... */]),
        MyFeatureFlags(),
      ],
    ),
    features: () => [/* ... */],
  );
}

A system plugin belongs in its named slot: putting, say, a StoragePlugin in others throws, so there is never any doubt about which one is active.

Use a plugin from a feature ​

Every plugin has a named accessor on vyuh:

dart
final token = await vyuh.secureStorage.read('auth.token');
final response = await vyuh.network.get(Uri.parse('https://api.example.com/me'));
vyuh.analytics.reportEvent('checkout_started');
vyuh.log.info('Cart has ${items.length} items');
vyuh.router.push('/cart');

Optional plugins return null when the app hasn't registered them:

dart
final enabled = await vyuh.featureFlag?.getBool('new-checkout') ?? false;

Code that must also run without runApp, such as an embedded VyuhContentWidget, uses the same accessors on VyuhBinding.instance.

When plugins start ​

Plugins start before any feature, so a feature's init can use all of them.

  1. Preloaded plugins start first: events, networking, telemetry and analytics. They're needed while everything else starts. If one fails, the app shows its startup failure screen instead of crashing, and Restart tries the failed plugin again. Preloaded plugins that started keep running across restarts.
  2. The remaining plugins start together.
  3. Features start, in dependency order.

There's no dependency order between plugins of the same stage. If your plugin needs another one, await it in its own init. On restart and shutdown, features stop first, while the plugins they use still exist.

Write your own ​

Any shared capability your features need can be a plugin: a payments client, a search index, a remote config service. See writing a plugin.