# 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](/core/tutorial/5.-forms/5.2-theming.md).

{% 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](/core/key-concepts/components.md).\
  \
  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](/files/y8pvQe94UxDFzO8d0Zcu) ![iOS](/files/Th0SKBtwziAa5A7QKD32)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bluebase.gitbook.io/core/tutorial/overview/1.3-create-custom-plugin.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
