# 1.3 Create Custom Plugin

By now it should be clear that all functionality in BlueBase is added via plugins. So in order to add views to our To-Do app, we need to create our own plugin.

### Step 1: Install components library

Start by adding the following dependency:

```shell
yarn add @bluebase/components
```

This library provides typescript typings of components imported from the BlueBase context.

### Step 2: Create a plugin icon

The first thing that we will do is to create a plugin icon component. Create the following files:

{% code title="src/components/ToDoAppIcon/ToDoAppIcon.tsx" %}

```typescript
import { DynamicIcon, View } from '@bluebase/components';
import { useStyles, useTheme } from '@bluebase/core';
import React from 'react';
import { TextStyle, ViewStyle } from 'react-native';

export interface ToDoAppIconStyles {
	iconColor: { color: TextStyle['color'] };
	root: ViewStyle;
}

export interface ToDoAppIconProps {
	size: number;
	styles?: Partial<ToDoAppIconStyles>;
}

export const ToDoAppIcon = (props: ToDoAppIconProps) => {
	const { size } = props;
	const { theme } = useTheme();

	const styles: ToDoAppIconStyles = useStyles('ToDoAppIcon', props, {
		iconColor: {
			color: theme.palette.error.contrastText,
		},
		root: {
			backgroundColor: theme.palette.error.main,
			borderRadius: theme.shape.borderRadius * 3,
			alignItems: 'center',
			justifyContent: 'center',
			height: size,
			width: size,
		},
	});

	return (
		<View style={styles.root}>
			<DynamicIcon
				type="icon"
				name="checkbox-multiple-marked-outline"
				color={styles.iconColor.color}
				size={size * 0.75}
			/>
		</View>
	);
};

ToDoAppIcon.defaultProps = {
	size: 100,
};
```

{% endcode %}

The code above uses the BlueBase theme syntax to customize styles. Read more about it in the [Themeing Chapter](https://bluebase.gitbook.io/core/tutorial/5.-forms/5.2-theming).

{% code title="src/components/ToDoAppIcon/index.tsx" %}

```typescript
export * from './ToDoAppIcon';

import { ToDoAppIcon } from './ToDoAppIcon';
export default ToDoAppIcon;
```

{% endcode %}

{% code title="src/components/index.tsx" %}

```typescript
import { ToDoAppIcon } from './ToDoAppIcon';

export const components = {
	ToDoAppIcon,
};
```

{% endcode %}

### Step 3: Create plugin

Time to create the plugin itself. Create the following file:

{% code title="src/index.ts" %}

```typescript
import { createPlugin } from '@bluebase/core';
import { ToDoAppIcon } from './components/ToDoAppIcon';

export default createPlugin({
	key: 'tasks',
	name: 'Tasks',
	description: 'A todo app made with BlueBase framework.',

	components: {
		ToDoAppIcon,
	},
	
	icon: {
		component: 'ToDoAppIcon',
		type: 'component',
	},

	indexRoute: 'HomeScreen',
});
```

{% endcode %}

In the above code, we use the `createPlugin` function from the the `@bluebase/core` library. This function takes attributes as input, and returns a BlueBase Plugin.

* The `key` property servers as the plugin ID, as well as the slug in the plugin URL path. So in this case the path to access this plugin would be: `http://localhost:19006/p/tasks`.
* The `name` and `description` properties are pretty self explanatory. The `name` property is rendered below the icon on the home screen.
* The `components` property is a Map of key, value pair. Where key is a string, and value is a React component. This map is used by BlueBase to store these components in its context. These can be fetched dynamically at a later stage, and can be overwritten by plugins to change the plugin implementation. More on this [here](https://bluebase.gitbook.io/core/key-concepts/components).\
  \
  We save the `ToDoAppIcon` component in the example above.
* The `icon` property defines the plugin icon that is rendered on the home page. In the `icon.component` sub-property tells which component to render. \
  \
  We use `'ToDoAppIcon'` value, which is the same as the key on the component object in Line 10. So, by doing this we are telling BlueBase to render a component by the key `ToDoAppIcon` .
* Lastly, the `indexRoute` key tells BlueBase which screen to navigate to when the icon is pressed. We tell it to go to `HomeScreen` here. Since we would already be on the `HomeScreen` so pressing this button will not do anything.

### Step 4: Use the plugin

Now we're all set to use our shiny new plugin Edit our plugin files to add our own plugin to the list.

{% code title="plugins.ts" %}

```typescript
import BlueBasePluginJsonSchemaComponents from '@bluebase/plugin-json-schema-components';
import BlueBasePluginLauncher from '@bluebase/plugin-launcher';
import BlueBasePluginMaterialUI from '@bluebase/plugin-material-ui';
import BlueBasePluginReactRouter from '@bluebase/plugin-react-router';
import BlueBasePluginResponsiveGrid from '@bluebase/plugin-responsive-grid';
import BlueBasePluginSettingsApp from '@bluebase/plugin-settings-app';
import { MaterialCommunityIcons } from '@bluebase/plugin-vector-icons';

import Plugin from './src';

export const plugins = [
	BlueBasePluginJsonSchemaComponents,
	BlueBasePluginLauncher,
	BlueBasePluginMaterialUI,
	BlueBasePluginReactRouter,
	BlueBasePluginResponsiveGrid,
	MaterialCommunityIcons,

	Plugin,
	BlueBasePluginSettingsApp,
];
```

{% endcode %}

{% code title="plugins.native.ts" %}

```typescript
import BlueBasePluginJsonSchemaComponents from '@bluebase/plugin-json-schema-components';
import BlueBasePluginLauncher from '@bluebase/plugin-launcher';
import BlueBasePluginReactNativePaper from '@bluebase/plugin-react-native-paper';
import BlueBasePluginReactNavigation from '@bluebase/plugin-react-navigation';
import BlueBasePluginResponsiveGrid from '@bluebase/plugin-responsive-grid';
import BlueBasePluginSettingsApp from '@bluebase/plugin-settings-app';
import { MaterialCommunityIcons } from '@bluebase/plugin-vector-icons';

import Plugin from './src';

export const plugins = [
	BlueBasePluginJsonSchemaComponents,
	BlueBasePluginLauncher,
	BlueBasePluginReactNativePaper,
	BlueBasePluginReactNavigation,
	BlueBasePluginResponsiveGrid,
	MaterialCommunityIcons,

	Plugin,
	BlueBasePluginSettingsApp,
];
```

{% endcode %}

### Step 5: Run

Now run the app again:

```
expo start
```

You should see the following screen on launch:

![Web](https://3369392052-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LPjsIbS1DfhqT8BS3Ui%2Fuploads%2F9ImV8dKQfpPqTgoeNNs8%2FScreenshot%202022-04-22%20at%203.02.43%20AM.png?alt=media\&token=bf273ff5-7efa-4355-8f90-991f1b225f87) ![iOS](https://3369392052-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-LPjsIbS1DfhqT8BS3Ui%2Fuploads%2FAPgzr02ZUPbQyru5S9Tq%2FScreenshot%202022-04-22%20at%203.02.51%20AM.png?alt=media\&token=eff89db5-0cb1-4b91-9d42-2293864ae75b)
