# SVG Core Plugins

Documentation for using and creating plugins with the Font Awesome JavaScript API.

> The SVG Core library includes a Plugins architecture so you can limit the file size and improve performance with only the features you need.

Make sure you already:

- [Set up access](./get-started) to the Javascript API in your project.

## Font Awesome Can Do a Lot

Here are the plugins:

| Plugin name          | What it does                                                            |
| -------------------- | ----------------------------------------------------------------------- |
| InjectCSS            | Adds CSS to the `<head>` of the page that is needed to display icons    |
| ReplaceElements      | Replaces `<i>` elements with `<svg>` icons                              |
| Layers               | Support for [layers](/web/style/layer.md)                                  |
| LayersCounter        | Support for [layer counters](/web/style/layer.md)                          |
| LayersText           | Support for [layer text](/web/style/layer.md)                              |
| PseudoElements       | Support for [pseudo-elements](/web/add-icons/pseudo-elements.md)           |
| MutationObserver     | Watches the page (DOM) for changes and replaces elements (`i` to `svg`) |
| PowerTransforms      | Support for [Power Transforms](/web/style/power-transform.md)              |
| Masks                | Support for [masking](/web/style/mask.md)                                  |
| MissingIconIndicator | Mark missing icons with an animated indicator                           |
| SvgSymbols           | Support for [SVG symbols](/web/add-icons/svg-symbols.md)                   |

When you import anything from `@fortawesome/fontawesome-svg-core` it comes with all batteries included.

But with a few small changes you **can pick the plugins you wish to use**. This saves bytes and can improve performance if you aren't wasting time doing unnecessary things.

## An Example

This example is using [Rollup.js](https://rollupjs.org) but the same principles apply to most other projects that use Webpack or even tools like ESBuild.

```bash
mkdir fa-lite
cd fa-lite
```

```
npm init -y
```

This will create a `package.json` file in the `fa-lite`.

Next up is installing some dependencies for Rollup and Font Awesome. (Don't act surprised, you kinda knew we'd be installing some deps didn't you?)

  <h4>
   Pro Plan Required
  </h4>
  Installing `@fortawesome/pro-solid-svg-icons` requires a Pro Plan and a Pro
  Package Token. [Get your package manager set up for Pro](/web/setup/packages.md)

  **Kit Package:**
  **Pro SVG Icon Package:**

```bash
npm install --save-dev rollup @rollup/plugin-node-resolve rollup-plugin-terser
npm i --save-dev @fortawesome/fontawesome-svg-core
npm i --save-dev '@awesome.me/kit-KIT_CODE'
```

```bash
npm install --save-dev rollup @rollup/plugin-node-resolve rollup-plugin-terser
npm i --save-dev @fortawesome/fontawesome-svg-core @fortawesome/pro-solid-svg-icons
```

Create `src/fontawesome.js`

**Kit Package:**
**Pro SVG Icon Package:**

```javascript
import { library, dom } from '@fortawesome/fontawesome-svg-core'
import { all } from '@awesome.me/kit-KIT_CODE/icons'

library.add(...all)

window.addEventListener('DOMContentLoaded', () => {
  dom.i2svg()
  dom.watch()
})
```

```javascript
import { library, dom } from '@fortawesome/fontawesome-svg-core'
import { faAlicorn, faAlien, faBoombox } from '@fortawesome/pro-solid-svg-icons'

library.add(faAlicorn, faAlien, faBoombox)

window.addEventListener('DOMContentLoaded', () => {
  dom.i2svg()
  dom.watch()
})
```

Create `rollup.config.js`

```javascript
import resolve from '@rollup/plugin-node-resolve'

const plugins = [resolve()]

export default [
  {
    input: 'src/fontawesome.js',
    output: {
      file: 'dist/fontawesome.js',
      format: 'esm'
    },
    plugins
  }
]
```

Open a terminal in the current directory and we'll run Rollup with `--watch`:

```bash
npx rollup -c rollup.config.js --watch
```

```bash
rollup v2.56.3
bundles src/fontawesome.js → dist/fontawesome.js...
created dist/fontawesome.js in 536ms

[2021-09-13 15:03:39] waiting for changes...

```

Create `index.html`

```html
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
    <script src="dist/fontawesome.js" type="module"></script>
  </head>
  <body>
    <i class="fas fa-alien"></i>
  </body>
</html>
```

Open another terminal in the current directory and we'll run a small HTTP server:

```bash
npm install --save-dev http-server
npx http-server
```

```bash
Starting up http-server, serving ./

http-server settings:
CORS: disabled
Cache: 3600 seconds
Connection Timeout: 120 seconds
Directory Listings: visible
AutoIndex: visible
Serve GZIP Files: false
Serve Brotli Files: false
Default File Extension: none

Available on:
  http://127.0.0.1:8080
  http://127.51.68.120:8080
  http://192.168.4.22:8080
  http://192.168.4.42:8080
Hit CTRL-C to stop the server

```

Load this up in the browser to see an alien icon.

## Switching to Plugins

While the icons have been subsetted you are still including every single one of the features Font Awesome provides.

Create `src/fontawesome-lite.js` next:

**Kit Package:**
**Pro SVG Icon Package:**

```javascript
import { register, InjectCSS, ReplaceElements } from '@fortawesome/fontawesome-svg-core/plugins'

const api = register([InjectCSS, ReplaceElements])

import { all } from '@awesome.me/kit-KIT_CODE/icons'

api.library.add(...all)

window.addEventListener('DOMContentLoaded', () => {
  api.dom.i2svg()
  api.dom.watch()
})
```

```javascript
import { register, InjectCSS, ReplaceElements } from '@fortawesome/fontawesome-svg-core/plugins'

const api = register([InjectCSS, ReplaceElements])

import { faAlicorn, faAlien, faBoombox } from '@fortawesome/pro-solid-svg-icons'

api.library.add(faAlicorn, faAlien, faBoombox)

window.addEventListener('DOMContentLoaded', () => {
  api.dom.i2svg()
  api.dom.watch()
})
```

  <h4>
   The api object changes subtly
  </h4>

An important point to make here is that the `api` object is now created by
calling `register()` from the `@fortawesome/fontawesome-svg-core/plugins`
module. Calls to things like `library.add()` will need to become
`api.library.add()`. If you are importing anything from
`@fortawesome/fontawesome-svg-core` (without `plugins`) you'll lose the
benefits of the plugin system altogether.

Modify `rollup.config.js`

```javascript {7-9,20-27}
import resolve from '@rollup/plugin-node-resolve'

const plugins = [resolve()]

if (process.env.NODE_ENV === 'production') {
  plugins.push(require('rollup-plugin-terser').terser())
}

export default [
  {
    input: 'src/fontawesome.js',
    output: {
      file: 'dist/fontawesome.js',
      format: 'esm'
    },
    plugins
  },
  {
    input: 'src/fontawesome-lite.js',
    output: {
      file: 'dist/fontawesome-lite.js',
      format: 'esm'
    },
    plugins
  }
]
```

Since we've changed `rollup.config.js` we need to stop and re-start. Type **CTRL+C** and then run Rollup again.

```bash
npx rollup -c rollup.config.js --watch
```

Change `dist/fontawesome.js` to use our `dist/fontawesome-lite.js` version

```html {7}
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
    <script src="dist/fontawesome-lite.js" type="module"></script>
  </head>
  <body>
    <i class="fas fa-alien"></i>
  </body>
</html>
```

## What to Expect

Compare the file-sizes before and after using the plugin system.

  <h4>
   The following sizes were measured using a code minifier called Terser
  </h4>

Terser is already included in this example because you installed it earlier.
Run `NODE_ENV=production npx rollup -c rollup.config.js` to use it.

| Filename                 | Size |
| ------------------------ | ---- |
| dist/fontawesome.js      | 61k  |
| dist/fontawesome-lite.js | 45k  |

Well, butter my bread! That's 16k saved. Using "lite" may be a bit generous, but
we'll be continuing to improve this API as time goes on. This architecture also
promises to open up some new possibilities with Font Awesome in the future.
