• Stars
    star
    164
  • Rank 223,145 (Top 5 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created over 3 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A plugin system for JS & React apps.

React-pluggable Logo React Pluggable

1) Introduction

React Pluggable: A plugin system for JS & React apps

While React itself is a plugin system in a way, it focuses on the abstraction of the UI. It is inherently declarative which makes it intuitive for developers when building UI. With the help of React Pluggable, we can think of our app as a set of features instead of a set of components. It provides a mixed approach to solve this problem.

We at GeekyAnts have used React Pluggable for large & complex apps like BuilderX to add independent and dependent features over time, and it has worked wonderfully for us. Find out more on our official documentation.

2) Motivation

In React, we think of everything as components. If we want to add a new feature, we make a new component and add it to our app. Every time we have to enable/disable a feature, we have to add/remove that component from the entire app and this becomes cumbersome when working on a complex app where there are lots of features contributed by different developers.

We are a huge fan of Laravel and love how Service Provider works in it. Motivated by how we register any service for the entire app from one place, we built a plugin system that has all your features and can be enabled/disabled with a single line of code.

React Pluggable simplifies the problem in 3 simple steps:

  1. To add a new feature in your app, you write it's logic and install it in the plugin store.
  2. You can use that feature anywhere in the app by calling that feature using PluginStore rather than importing that feature directly.
  3. If you do not want a particular plugin in your app, you can uninstall it from your plugin store or just comment out the installation.

3) Features

  • Open-closed Principle

The O in SOLID stands for Open-closed principle which means that entities should be open for extension but closed for modification. With React Pluggable, we can add plugins and extend a system without modifying existing files and features.

  • Imperative APIs for Extensibility

React is inherently declarative which makes it intuitive for developers when building UI but it also makes extensibility hard.

  • Thinking Features over Components

React abstracts components very well but a feature may have more than just components. React Pluggable pushes you to a feature mindset instead of a component mindset.

4) Installation

Use npm or yarn to install this to your application:

npm install react-pluggable
yarn add react-pluggable

5) Usage

  • Making a plugin

ShowAlertPlugin.tsx

import React from 'react';
import { IPlugin, PluginStore } from 'react-pluggable';

class ShowAlertPlugin implements IPlugin {
  public pluginStore: any;

  getPluginName(): string {
    return 'ShowAlert';
  }

  getDependencies(): string[] {
    return [];
  }

  init(pluginStore: PluginStore): void {
    this.pluginStore = pluginStore;
  }

  activate(): void {
    this.pluginStore.addFunction('sendAlert', () => {
      alert('Hello from the ShowAlert Plugin');
    });
  }

  deactivate(): void {
    this.pluginStore.removeFunction('sendAlert');
  }
}

export default ShowAlertPlugin;`
  • Adding it to your app

App.tsx

import React from 'react';
import './App.css';
import { createPluginStore, PluginProvider } from 'react-pluggable';
import ShowAlertPlugin from './plugins/ShowAlertPlugin';
import Test from './components/Test';

const pluginStore = createPluginStore();
pluginStore.install(new ShowAlertPlugin());

const App = () => {
  return (
    <PluginProvider pluginStore={pluginStore}>
      <Test />
    </PluginProvider>
  );
};

export default App;
  • Using the plugin

Test.tsx

import * as React from 'react';
import { usePluginStore } from 'react-pluggable';

const Test = () => {
  const pluginStore = usePluginStore();

  return (
    <>
      <button
        onClick={() => {
          pluginStore.executeFunction('sendAlert');
        }}
      >
        Show Alert
      </button>
    </>
  );
};

export default Test;
  • Using the inbuilt renderer

Sometimes a plugin has a UI component associated with it. You can implement this functionality by simply building a plugin of your own or using the default plugin provided by the package.

SharePlugin.tsx

import React from 'react';
import { IPlugin, PluginStore } from 'react-pluggable';

class SharePlugin implements IPlugin {
  public pluginStore: any;

  getPluginName(): string {
    return 'Share plugin';
  }

  getDependencies(): string[] {
    return [];
  }

  init(pluginStore: PluginStore): void {
    this.pluginStore = pluginStore;
  }

  activate(): void {
    this.pluginStore.executeFunction('RendererPlugin.add', 'top', () => (
      <button>Share</button>
    ));
  }

  deactivate(): void {
    //
  }
}

export default SharePlugin;

You can add the inbuilt renderer plugin by importing and installing RendererPlugin provided in the package.

  • Importing the plugin

App.tsx

import \* as React from 'react';
import { usePluginStore } from 'react-pluggable';
import {
createPluginStore,
PluginProvider,
RendererPlugin,
} from 'react-pluggable';
import SharePlugin from './plugins/SharePlugin';
import Test from './components/Test';

const pluginStore = createPluginStore();
pluginStore.install(new RendererPlugin());
pluginStore.install(new SharePlugin());

function App() {
return (
<PluginProvider pluginStore={pluginStore}>
<Test />
</PluginProvider>
);
}

export default App;

Test.tsx

import \* as React from 'react';
import { usePluginStore } from 'react-pluggable';

const Test = (props: any) => {
const pluginStore: any = usePluginStore();

let Renderer = pluginStore.executeFunction(
'RendererPlugin.getRendererComponent'
);

return (
<>
<h1>I am header</h1>
<Renderer placement={'top'} />
</>
);
};

export default Test;

6) Examples

Here are some examples of React Pluggable:

7) Tech Stack

Javascript & React.

8) Naming Conventions

Although the naming of plugins, functions, or events is not an enforced rule, we recommend a few conventions to standardize things.

  1. Plugin Name: Let's consider a plugin which provides authentication, named as Auth.
  2. Class Name: The name of the class will be your plugin name suffixed with 'Plugin' i.e. AuthPlugin.
  3. getPluginName: When returning the name of the plugin, we add <plugin_name> with @, followed by the version. ex : [email protected] (<plugin_name>@).
  4. Adding functions: While functions can be added to pluginStore with any name, to ensure uniqueness across plugins, we recommend the format <plugin_name>.<function_name>. Ex : Auth.authenticate.
  5. Events: Events can be added and dispatched from pluginStore using any name. To show which event belongs to which plugin, we recommend the format <plugin_name>.<event_name> Ex: Auth.checking.

Example :

AuthPlugin.tsx

import React from 'react';
import { IPlugin, PluginStore } from 'react-pluggable';

class AuthPlugin implements IPlugin {
  getPluginName(): string {
    return '[email protected]'; //line 2
  }

  getDependencies(): string[] {
    return [];
  }

  public pluginStore: any;

  init(pluginStore: PluginStore): void {
    this.pluginStore = pluginStore;
  }

  authenticate = (credentials: object) => {
    // checks the credentials and returns username if matches.
    return { name: 'username' };
  };

  activate(): void {
    this.pluginStore.addFunction(
      'Auth.authenticate', //line 3
      (credentials: object) => this.authenticate(credentials)
    );
  }

  deactivate(): void {
    this.pluginStore.removeFunction('Auth.authenticate'); //line 4
  }
}

export default AuthPlugin;

We have seen in the class AuthPlugin that the name of the plugin is used several times. An alternate way is to define a variable that stores the name of the plugin and use that variable in the class wherever we want the plugin name.

AuthPlugin

import React from 'react';
import { IPlugin, PluginStore } from 'react-pluggable';

class AuthPlugin implements IPlugin {
  private namespace = 'Auth';

  getPluginName(): string {
    return `${this.namespace}@1.0.0`; //line 2
  }

  getDependencies(): string[] {
    return [];
  }

  public pluginStore: any;

  init(pluginStore: PluginStore): void {
    this.pluginStore = pluginStore;
  }

  authenticate = (credentials: object) => {
    // checks the credentials and returns username if matches.
    return { name: 'username' };
  };

  activate(): void {
    this.pluginStore.addFunction(
      `${this.namespace}.authenticate`, //line 3
      (credentials: object) => this.authenticate(credentials)
    );
  }

  deactivate(): void {
    this.pluginStore.removeFunction(`${this.namespace}.authenticate`); //line 4
  }
}

export default AuthPlugin;

9) Contributors

10) How to Contribute

Thank you for your interest in contributing to React Pluggable! Pull requests are welcome. Head over to Contribution Guidelines and learn how you can be a part of a wonderful, growing community.

For major changes, please open an issue first to discuss changes and update tests as appropriate.

11) License

Licensed under the MIT License, Copyright © 2020 GeekyAnts. See LICENSE for more information.

More Repositories

1

NativeBase

Mobile-first, accessible components for React Native & Web to build consistent UI across Android, iOS and Web.
TypeScript
20,030
star
2

vue-native-core

Vue Native is a framework to build cross platform native mobile apps using JavaScript
JavaScript
8,328
star
3

NativeBase-KitchenSink

An example app with all the UI components of NativeBase
JavaScript
2,184
star
4

react-native-easy-grid

Easy React Native Layout & Grid for the Dumb
JavaScript
2,172
star
5

flutter-login-home-animation

Dart
1,223
star
6

express-typescript

Express + TypeScript + Boilerplate for Web / API App
TypeScript
1,096
star
7

react-native-seed

Get your favorite boilerplate of React Native
652
star
8

flutter-starter

A Flutter starter-kit for production-level apps.
Dart
425
star
9

KitchenSink-Vue-Native

KitchenSink app for Vue Native (using NativeBase)
Vue
417
star
10

flutter-web-admin-dashbaord

Admin Dashboard built using Flutter Web
Dart
250
star
11

flick-video-player

Dart
240
star
12

react-native-aria

A library of React Hooks for React-Native (Android/iOS/web) to provide accessible UI primitives for a design system.
TypeScript
225
star
13

sb-admin-svelte

StartBootstrap SB Admin rebuilt using Svelte + Sveltestrap
CSS
221
star
14

FlatApp-Firebase-Flutter

Flap App with Firebase in Flutter by GeekyAnts.
Dart
217
star
15

ignite-native-base-boilerplate

JavaScript
184
star
16

FlatApp-Flutter

Flap App in Flutter by GeekyAnts.
Dart
169
star
17

NativeBase-Sketch-Template

Sketch Template for NativeBase components
159
star
18

vue-native-starter-app

Vue Native Starter App with Login, News Feed and Sidebar using Vuelidate and Vuex
Vue
140
star
19

react-native-hamburger

Hamburger menu for react-native!
JavaScript
134
star
20

native-base-react-navigation-stack-navigator

JavaScript
125
star
21

flutter-galaxy-game

2D Flutter Galaxy Game
Dart
122
star
22

vue-native-cli

Write Native Mobile Apps using Vue. Vue Native is a wrapper around React Native APIs
JavaScript
92
star
23

express-typescript-postgres

An API Boilerplate for Node.js, Express.js & PostgresSQL.
TypeScript
90
star
24

vue-js-animation-starter-kit

JavaScript
90
star
25

reazy

Reazy Framework - A simple services-based framework for React and React Native
JavaScript
85
star
26

react-native-native-base-seed

React Native Seed Project with NativeBase, Redux, CodePush, Router, Push Notification and other basic must-have libraries
JavaScript
82
star
27

native-base-docs

Documentation of NativeBase
HTML
74
star
28

nativebase-tutorial

Sample App using NativeBase
JavaScript
71
star
29

nativebase-templates

NativeBase Templates for different platforms.
JavaScript
71
star
30

react-native-boilerplate-redux-typescript

TypeScript
68
star
31

flutter-carousel

A carousel package in flutter with various configuration options
Dart
66
star
32

NativeBase-TodoApp

A basic Todo App built using NativeBase and Redux
Java
61
star
33

react-native-boilerplate-redux-flow

JavaScript
59
star
34

ReactNative-Redux-TypeScript-Boilerplate

React Native Boilerplate app - Redux + TypeScript
TypeScript
57
star
35

FlappyBird-ReactNative

Flappy Bird Experiment using React Native
JavaScript
57
star
36

GaugesFlutter

A gauge package for Flutter that displays progress and can be customized for appearance and behavior.
Dart
57
star
37

customise-tinder-swipe

A tinder swipe package that can be customised
Dart
50
star
38

firestore-react

[UNMAINTAINED] Firestore bindings for React components
TypeScript
50
star
39

nativebase-v3-kitchensink

NativeBase KitchenSink App
TypeScript
41
star
40

react-native-to-flutter

TypeScript
40
star
41

native-base-cli

JavaScript
40
star
42

nextjs-typescript-firebase

Next.js + TypeScript + Firebase
TypeScript
40
star
43

vue-native-router

JavaScript
37
star
44

infinite-carousel-flutter

Carousel in flutter. Supports infinite looping and gives control over anchor and velocity.
Dart
37
star
45

flutter_amplify_datastore_demo

A WhatsApp clone build using Flutter and AWS Amplify DataStore
Dart
37
star
46

flutter-folder-structure

The base folder structure to start any new project
Dart
36
star
47

vue-native-website

The website of Vue Native
JavaScript
36
star
48

flutter-docs-code-samples

Dart
35
star
49

NativeBase-VectorIconApp

Example repo to demo how to use Icons with NativeBase
JavaScript
34
star
50

mobx-state-tree-firebase

[UNMAINTAINED] Firebase Integration for your mobx-state-tree models.
TypeScript
34
star
51

do-app-builderx-sketch-import

A sample app to show how Sketch to React Native works in BuilderX
JavaScript
32
star
52

react-native-boilerplate-mobx-typescript

TypeScript
32
star
53

svelte-admin-dashboard

SB Admin dashboard, built using Svelte!
HTML
31
star
54

sample-e-voting-system-ethereum

TypeScript
30
star
55

sample-decentralised-kyc-ethereum

TypeScript
29
star
56

native-base-example-github-app

JavaScript
27
star
57

flutter_amplify_graphql_demo

A WhatsApp clone build using Flutter and AWS Amplify GraphQL API.
Dart
25
star
58

nativebase-docs

Mobile-first, accessible components for React Native & Web.
TypeScript
25
star
59

react-native-boilerplate-mobx-flow

JavaScript
23
star
60

react-native-boilerplate-mobx-state-tree-typescript

TypeScript
23
star
61

native-base-market-taxi-app-backend-docs

HTML
22
star
62

sample-supply-chain-ethereum

TypeScript
22
star
63

react-mst-boilerplate

React + mobx-state-tree + TypeScript + styled-components = Clean Boilerplate
TypeScript
19
star
64

localization-json-translator

A localisation language file generator using the Google translator
JavaScript
19
star
65

react-native-zebra-bluetooth-printer

Java
18
star
66

laravel-inertia-sharedo

Easy-to-add Share functionality for your Laravel project
Vue
15
star
67

ga-wdio

An automation CLI tool that creates the tests project for Web, API & Mobile apps and runs things like geckodriver, chromedriver & appium internally for various stacks, browsers, platforms & modes.
JavaScript
14
star
68

nativebase-vscode-extension

NativeBase VS Code Extensions are specifically designed to quicken your development process using NativeBase 3.0.
14
star
69

native-base-example-redux-form

JavaScript
13
star
70

react-animated-charts

React wrapper for D3.js
JavaScript
13
star
71

react-native-tinder-card-swiper

Tinder like Card Swipe Example using NativeBase DeckSwiper component
Objective-C
13
star
72

react-native-bing-maps

Java
12
star
73

laravel-lumen-jwt-boilerplate

A boilerplate for your app using laravel, lumen & jwt libraries/frameworks.
PHP
12
star
74

flutter-bluetooth-adapter

Java
12
star
75

nativebase-v3-taxi-app

TypeScript
12
star
76

react-native-chat

Chat Plugin for your React Native Apps
JavaScript
12
star
77

native-base-example-redux-counter

JavaScript
11
star
78

external_app_launcher

C++
10
star
79

Hacker-News-RN-Clone

Hacker News React Native clone built using BuilderX
JavaScript
9
star
80

sample-smart-contract-ethereum

JavaScript
9
star
81

native-base-example-flatlist-stickyHeaders

Example to demonstrate use of FlatList to include Sticky Headers using NativeBase components
JavaScript
8
star
82

flutter-firebase-notification-sender

A flutter client to send out firebase push notifications
Dart
8
star
83

native-base-example-rnrf

JavaScript
7
star
84

flutter-deno-sample-app

TypeScript
7
star
85

react-native-chat-example

react-native-chat.com Example
JavaScript
7
star
86

react-native-fireworks

JavaScript
7
star
87

native-base-market-dating-app-docs

Documentation of Dating App (Tinder like) on StrapMobile.com
HTML
7
star
88

line-segment-slider-input

2D Line Segment Slider Input. Originally built for BuilderX.io
TypeScript
6
star
89

twitter-clone-svelte

HTML
6
star
90

geekymodel

GeekyModel - Opinionated State Container for Remote and Local Storage with a Database-like API powered by MobX
TypeScript
6
star
91

native-basev3-testbed

App for building nbv3 components.
TypeScript
6
star
92

native-base-atom-package

NativeBase snippets for Atom Editor
5
star
93

nativebase-v3-examples

All the examples of NativeBase v3 used in building the new website.
TypeScript
5
star
94

NativeBase-Customizer

JavaScript
5
star
95

gform

React Forms with Validation, Two-way binding, Nested Forms
TypeScript
5
star
96

native-base-example-mobx-counter

JavaScript
5
star
97

NativeBase_Flutter

Dart
4
star
98

about-us

4
star
99

flutter-starter-cli

4
star
100

FlutterLearn-Casts

Source code of all the widgets covered in FlutterLearn Casts.
Dart
4
star