Repository: teleporthq/teleport-code-generators
Pull request #514 (2020-11-25 08:23:30)

(feat): Plugins for project-generators 
- [x] Fix all the test cases
- [x] Add test cases for project-generators assembly line
- [x] Add test cases for individual project-plugins
- [x] Add integration test-cases for individual project-plugins

codecov[bot]: # [Codecov](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514?src=pr&el=h1) Report
> Merging [#514](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514?src=pr&el=desc) (6fe50b0) into [development](https://codecov.io/gh/teleporthq/teleport-code-generators/commit/f3195a9b0a7331745f1010ef225476b1e0ebaef7?el=desc) (f3195a9) will **decrease** coverage by `1.10%`.
> The diff coverage is `36.61%`.

[![Impacted file tree graph](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514/graphs/tree.svg?width=650&height=150&src=pr&token=LI2WPEFm1R)](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514?src=pr&el=tree)

```diff
@@               Coverage Diff               @@
##           development     #514      +/-   ##
===============================================
- Coverage        76.34%   75.23%   -1.11%     
===============================================
  Files              156      159       +3     
  Lines             5685     5779      +94     
  Branches          1203     1204       +1     
===============================================
+ Hits              4340     4348       +8     
- Misses            1286     1372      +86     
  Partials            59       59              
```


| [Impacted Files](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [...ges/teleport-project-generator-gatsby/src/utils.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHJvamVjdC1nZW5lcmF0b3ItZ2F0c2J5L3NyYy91dGlscy50cw==) | `91.35% <ø> (-0.04%)` | :arrow_down: |
| [...t-plugin-gatsby-styled-components/src/constants.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHJvamVjdC1wbHVnaW4tZ2F0c2J5LXN0eWxlZC1jb21wb25lbnRzL3NyYy9jb25zdGFudHMudHM=) | `0.00% <0.00%> (ø)` | |
| [...oject-plugin-gatsby-styled-components/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHJvamVjdC1wbHVnaW4tZ2F0c2J5LXN0eWxlZC1jb21wb25lbnRzL3NyYy9pbmRleC50cw==) | `0.00% <0.00%> (ø)` | |
| [...eport-project-plugin-next-css-modules/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHJvamVjdC1wbHVnaW4tbmV4dC1jc3MtbW9kdWxlcy9zcmMvaW5kZXgudHM=) | `0.00% <0.00%> (ø)` | |
| [...eport-project-generator/src/assembly-line/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHJvamVjdC1nZW5lcmF0b3Ivc3JjL2Fzc2VtYmx5LWxpbmUvaW5kZXgudHM=) | `61.90% <61.90%> (ø)` | |
| [packages/teleport-project-generator/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHJvamVjdC1nZW5lcmF0b3Ivc3JjL2luZGV4LnRz) | `65.55% <72.72%> (+1.09%)` | :arrow_up: |
| [packages/teleport-code-generator/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtY29kZS1nZW5lcmF0b3Ivc3JjL2luZGV4LnRz) | `95.83% <100.00%> (+0.37%)` | :arrow_up: |
| [...ges/teleport-project-generator-gatsby/src/index.ts](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514/diff?src=pr&el=tree#diff-cGFja2FnZXMvdGVsZXBvcnQtcHJvamVjdC1nZW5lcmF0b3ItZ2F0c2J5L3NyYy9pbmRleC50cw==) | `100.00% <100.00%> (ø)` | |
| ... and [1 more](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514?src=pr&el=footer). Last update [f3195a9...6fe50b0](https://codecov.io/gh/teleporthq/teleport-code-generators/pull/514?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

JayaKrishnaNamburu: If we refer to this file --> https://github.com/teleporthq/teleport-code-generators/blob/feat/project-generator-plugins/packages/teleport-project-plugin-next-css-modules/src/index.ts

It is a test implementation of how the project-plugins can look like. One main issue is to handle the post-processors on top of project plugins.

Use case
-  The custom hand written code can still be formatted to match the code that is generated using code-generators.  

But currently, the post-processors will work using the chunking concept. So, we can't directly use them for formatting files. Should we need to change the current post-processors a little to solve this use case. Or have a completely new set of post-processors.
JayaKrishnaNamburu: To address the above formatting concept. Having a project wide post-processor is not suggested. Since we have individual component formatter, running formatter again on top of all these files is not doing any good. 

Next, we need formatters to run on files that are being modified or custom generated. So we can directly format them using the existing formatter, which looks something like 

```js
const nextContent = prettierJS({
      [FileType.JS]: `const withCSS = require('@zeit/next-css')
    module.exports = withCSS({
      cssModules: true
    })`,
    })
```

We can discuss a little on how the API can be exposed etc. But with this, we are going to format the code using the same config that the generators use internally when they are used as default.

Here is how plugins will look like.

https://github.com/teleporthq/teleport-code-generators/pull/514/commits/952953e6a1079e7049ad5832066010ed0b3637d0#diff-3d9de7f13f3c7caa6a9c3b9623ceae18fe2e8a5130c3ba9dbf057fa2fccf495c

JayaKrishnaNamburu: One DX with enabling plugins for project-generators is, we need to re-configure generators every time we want to switch just the style variation for the project.

### Problem

Currently we can configure style variation only for component generators. Something like

```js
const reactComponentGenerator = createReactComponentGenerator(
  ReactStyleVariation.CSSModules
);
reactComponentGenerator.addMapping(ReactProjectMapping);

const reactPagesGenerator = createReactComponentGenerator(
  ReactStyleVariation.CSSModules,
  {
    plugins: [headConfigPlugin],
    mappings: [ReactProjectMapping],
  }
);
```

We currently don't have a global place to configure the style variation in the strategy.
https://github.com/teleporthq/teleport-code-generators/blob/development/packages/teleport-types/src/generators.ts#L134

Let's introduce a new field in strategy something like this

```js
const generator = createProjectGenerator({
  components: {
    generator: reactComponentGenerator,
    path: ["src", "components"],
  },
  pages: {
    generator: reactPagesGenerator,
    path: ["src", "views"],
  },
  projectStyleSheet: {
    generator: styleSheetGenerator,
    fileName: "style",
    path: ["src"],
  },
  router: {
    generator: routingComponentGenerator,
    path: ["src"],
    fileName: "index",
  },
  entry: {
    generator: htmlFileGenerator,
    path: ["public"],
    fileName: "index",
  },
  static: {
    prefix: "",
    path: ["public"],
  },
});
```

to this

```js
const generator = createProjectGenerator({
  variation: ReactStyleVariation.CSSModules,
  components: {
    generator: reactComponentGenerator,
    path: ["src", "components"],
    plugins: [importStatementsPlugins],
    processors: [prettierJS],
    mappaings: [],
  },
  pages: {
    generator: reactPagesGenerator,
    path: ["src", "views"],
    plugins: [],
    processors: [],
  },
  projectStyleSheet: {
    generator: styleSheetGenerator,
    fileName: "style",
    path: ["src"],
    plugins: [],
    processors: [],
  },
  router: {
    generator: routingComponentGenerator,
    path: ["src"],
    plugins: [reactAppRoutingPlugin],
    processors: [],
    fileName: "index",
  },
  entry: {
    generator: htmlFileGenerator,
    path: ["public"],
    fileName: "index",
  },
  static: {
    prefix: "",
    path: ["public"],
  },
});
```

So, the appending plugins and post-processors and style variation configurations happens in project-generators.

JayaKrishnaNamburu: Thinking a little more, we shouldn't allow template to be changed from a project plugin. In my view the main use case for project plugins is to quickly adding some extra component plugins or remove some. Or change some files that are generated along. 

In this case, if we build plugins on a default generator and some plugin changes the template in middle. Then the whole pipeline gives us a broken project. So, if we want to change the template, it can be done by building a new generator.
JayaKrishnaNamburu: ### Question

Should we add a new option in component-generators, to emit Code or just AST at the end of pipeline.

When we think of component-generators alone, having code at the end makes sense. But when we think of project-generators and the plugin eco-system around it. Sometimes, we need to change a couple of files or edit them or add them. 

Right now, because of

**AST to Code** and **Prettier** happening at component level. We are using MagicString to quickly add or edit a file as here https://github.com/teleporthq/teleport-code-generators/pull/514/files#diff-9fcbca22388001116d00da990af640ebed9d89ba33d07f1324fabb6b733830cdR32
and then running prettier on top of it.

The problem in long run is, Magic String works using indexes as we can see from the existing plugins. So every-time, even a little of context changes inside the component. These indexes need to be changed to support them. Which is not the best solution.

So my emitting AST from component generators during project-generators pipeline. We can just change the AST structure and the post-proceessors run at the end. Since we will be changing AST, we don't need to worry about indexes.
Utwo: Awesome work! :100: 
JayaKrishnaNamburu: Most of the plugins will be opinionated towards a framework. So, basically we can't use a `pluginNextCssModules` to a `gatsby-project-generator`. So, we need a `strategy-id` through which we can detect and throw error in plugins. If the `strategy-id` is not the plugin looking for. So, we can eliminate the errors, that we run into by using a plugin of one framework with another one. 

Or is it really mandatory for the plugins to do this check before doing operation ?

cc @Utwo 

Patch:
diff --git a/packages/teleport-code-generator/package.json b/packages/teleport-code-generator/package.json
index ef65ba94..6a56bf05 100644
--- a/packages/teleport-code-generator/package.json
+++ b/packages/teleport-code-generator/package.json
@@ -50,7 +50,11 @@
     "@teleporthq/teleport-publisher-vercel": "^0.15.0",
     "@teleporthq/teleport-publisher-zip": "^0.15.0",
     "@teleporthq/teleport-shared": "^0.15.0",
-    "@teleporthq/teleport-types": "^0.15.0"
+    "@teleporthq/teleport-types": "^0.15.0",
+    "@teleporthq/teleport-project-plugin-next-css-modules": "^0.15.0",
+    "@teleporthq/teleport-project-plugin-gatsby-styled-components": "^0.15.0",
+    "@teleporthq/teleport-project-plugin-next-styled-components": "^0.15.0",
+    "@teleporthq/teleport-project-plugin-next-react-jss": "^0.15.0"
   },
   "gitHead": "b185c3fdb7dc94ff8c7eed63f7edba055fffa8d0"
 }
diff --git a/packages/teleport-code-generator/src/index.ts b/packages/teleport-code-generator/src/index.ts
index e93588c3..5198084a 100644
--- a/packages/teleport-code-generator/src/index.ts
+++ b/packages/teleport-code-generator/src/index.ts
@@ -10,7 +10,15 @@ import {
   InvalidProjectTypeError,
   InvalidPublisherTypeError,
   GeneratorOptions,
+  Mapping,
+  ComponentGenerator,
+  ComponentGeneratorInstance,
 } from '@teleporthq/teleport-types'
+import pluginNextCSSModules from '@teleporthq/teleport-project-plugin-next-css-modules'
+import pluginGatsbyStyledComponents from '@teleporthq/teleport-project-plugin-gatsby-styled-components'
+import pluginNextStyledComponents from '@teleporthq/teleport-project-plugin-next-styled-components'
+import pluginNextReactJSS from '@teleporthq/teleport-project-plugin-next-react-jss'
+
 import { createProjectPacker } from '@teleporthq/teleport-project-packer'
 import { Constants } from '@teleporthq/teleport-shared'
 
@@ -76,7 +84,7 @@ import { createStencilComponentGenerator } from '@teleporthq/teleport-component-
 import { createAngularComponentGenerator } from '@teleporthq/teleport-component-generator-angular'
 import { createReactNativeComponentGenerator } from '@teleporthq/teleport-component-generator-reactnative'
 
-const componentGeneratorFactories = {
+const componentGeneratorFactories: Record<ComponentType, ComponentGeneratorInstance> = {
   [ComponentType.REACT]: createReactComponentGenerator,
   [ComponentType.PREACT]: createPreactComponentGenerator,
   [ComponentType.ANGULAR]: createAngularComponentGenerator,
@@ -94,17 +102,33 @@ const componentGeneratorProjectMappings = {
   [ComponentType.REACTNATIVE]: ReactNativeProjectMapping,
 }
 
+const nextCSSModulesProjectGenerator = createNextProjectGenerator()
+nextCSSModulesProjectGenerator.addPlugin(pluginNextCSSModules)
+
+const gatsbyStyledComponentsProjectGenerator = createGatsbyProjectGenerator()
+gatsbyStyledComponentsProjectGenerator.addPlugin(pluginGatsbyStyledComponents)
+
+const nextStyledComponentsProjectGenerator = createNextProjectGenerator()
+nextStyledComponentsProjectGenerator.addPlugin(pluginNextStyledComponents)
+
+const nextReactJSSProjectGenerator = createNextProjectGenerator()
+nextReactJSSProjectGenerator.addPlugin(pluginNextReactJSS)
+
 const projectGeneratorFactories = {
-  [ProjectType.REACT]: createReactProjectGenerator,
-  [ProjectType.NEXT]: createNextProjectGenerator,
-  [ProjectType.VUE]: createVueProjectGenerator,
-  [ProjectType.NUXT]: createNuxtProjectGenerator,
-  [ProjectType.PREACT]: createPreactProjectGenerator,
-  [ProjectType.STENCIL]: createStencilProjectGenerator,
-  [ProjectType.ANGULAR]: createAngularProjectGenerator,
-  [ProjectType.REACTNATIVE]: createReactNativeProjectGenerator,
-  [ProjectType.GRIDSOME]: createGridsomeProjectGenerator,
-  [ProjectType.GATSBY]: createGatsbyProjectGenerator,
+  [ProjectType.REACT]: createReactProjectGenerator(),
+  [ProjectType.NEXT]: createNextProjectGenerator(),
+  [ProjectType.VUE]: createVueProjectGenerator(),
+  [ProjectType.NUXT]: createNuxtProjectGenerator(),
+  [ProjectType.PREACT]: createPreactProjectGenerator(),
+  [ProjectType.STENCIL]: createStencilProjectGenerator(),
+  [ProjectType.ANGULAR]: createAngularProjectGenerator(),
+  [ProjectType.REACTNATIVE]: createReactNativeProjectGenerator(),
+  [ProjectType.GRIDSOME]: createGridsomeProjectGenerator(),
+  [ProjectType.GATSBY]: createGatsbyProjectGenerator(),
+  [ProjectType.NEXT_CSS_MODULES]: nextCSSModulesProjectGenerator,
+  [ProjectType.GATSBY_STYLED_COMPONENTS]: gatsbyStyledComponentsProjectGenerator,
+  [ProjectType.NEXT_STYLED_COMPONENTS]: nextStyledComponentsProjectGenerator,
+  [ProjectType.NEXT_REACT_JSS]: nextReactJSSProjectGenerator,
 }
 
 const templates = {
@@ -118,6 +142,10 @@ const templates = {
   [ProjectType.ANGULAR]: AngularTemplate,
   [ProjectType.GRIDSOME]: GridsomeTemplate,
   [ProjectType.GATSBY]: GatsbyTemplate,
+  [ProjectType.NEXT_CSS_MODULES]: NextTemplate,
+  [ProjectType.GATSBY_STYLED_COMPONENTS]: GatsbyTemplate,
+  [ProjectType.NEXT_STYLED_COMPONENTS]: NextTemplate,
+  [ProjectType.NEXT_REACT_JSS]: NextTemplate,
 }
 
 const projectPublisherFactories = {
@@ -154,7 +182,7 @@ export const packProject: PackProjectFunction = async (
     path: [Constants.ASSETS_IDENTIFIER],
   })
 
-  packer.setGenerator(projectGeneratorFactory())
+  packer.setGenerator(projectGeneratorFactory)
   packer.setTemplate(projectTemplate)
 
   // If no publisher is provided, the packer will return the generated project
@@ -182,11 +210,14 @@ export const generateComponent: GenerateComponentFunction = async (
 ) => {
   const generator = createComponentGenerator(componentType, styleVariation)
   const projectMapping = componentGeneratorProjectMappings[componentType]
-  generator.addMapping(projectMapping)
+  generator.addMapping(projectMapping as Mapping)
   return generator.generateComponent(componentUIDL, componentGeneratorOptions)
 }
 
-const createComponentGenerator = (componentType: ComponentType, styleVariation: StyleVariation) => {
+const createComponentGenerator = (
+  componentType: ComponentType,
+  styleVariation: StyleVariation
+): ComponentGenerator => {
   const generatorFactory = componentGeneratorFactories[componentType]
 
   if (!generatorFactory) {
@@ -198,8 +229,7 @@ const createComponentGenerator = (componentType: ComponentType, styleVariation:
     componentType === ComponentType.PREACT ||
     componentType === ComponentType.REACTNATIVE
   ) {
-    // @ts-ignore
-    return generatorFactory(styleVariation)
+    return generatorFactory({ variation: styleVariation })
   }
 
   return generatorFactory()
diff --git a/packages/teleport-component-generator-angular/src/index.ts b/packages/teleport-component-generator-angular/src/index.ts
index e89f22c8..e33422a7 100644
--- a/packages/teleport-component-generator-angular/src/index.ts
+++ b/packages/teleport-component-generator-angular/src/index.ts
@@ -10,7 +10,11 @@ import prettierTS from '@teleporthq/teleport-postprocessor-prettier-ts'
 import prettierHTML from '@teleporthq/teleport-postprocessor-prettier-html'
 
 import AngularMapping from './angular-mapping.json'
-import { ComponentGenerator, FileType } from '@teleporthq/teleport-types'
+import {
+  ComponentGenerator,
+  FileType,
+  ComponentGeneratorInstance,
+} from '@teleporthq/teleport-types'
 
 const importStatementsPlugin = createImportPlugin({ fileType: FileType.TS })
 const stylePlugin = createCSSPlugin({
@@ -18,7 +22,7 @@ const stylePlugin = createCSSPlugin({
   declareDependency: 'decorator',
 })
 
-const createAngularComponentGenerator = ({
+const createAngularComponentGenerator: ComponentGeneratorInstance = ({
   mappings = [],
   plugins = [],
   postprocessors = [],
diff --git a/packages/teleport-component-generator-preact/src/index.ts b/packages/teleport-component-generator-preact/src/index.ts
index 803474db..772d3df5 100644
--- a/packages/teleport-component-generator-preact/src/index.ts
+++ b/packages/teleport-component-generator-preact/src/index.ts
@@ -1,26 +1,29 @@
-import { PreactStyleVariation, ComponentGenerator } from '@teleporthq/teleport-types'
+import {
+  PreactStyleVariation,
+  ComponentGenerator,
+  GeneratorFactoryParams,
+  ComponentPlugin,
+  ComponentGeneratorInstance,
+} from '@teleporthq/teleport-types'
 import preactComponentPlugin from '@teleporthq/teleport-plugin-preact-base-component'
 import { createCSSModulesPlugin } from '@teleporthq/teleport-plugin-css-modules'
 import { createCSSPlugin } from '@teleporthq/teleport-plugin-css'
 import inlineStylesPlugin from '@teleporthq/teleport-plugin-jsx-inline-styles'
 import importPlugin from '@teleporthq/teleport-plugin-import-statements'
 import proptypesPlugin from '@teleporthq/teleport-plugin-jsx-proptypes'
-
 import prettierJS from '@teleporthq/teleport-postprocessor-prettier-js'
-
-import {
-  createComponentGenerator,
-  GeneratorFactoryParams,
-} from '@teleporthq/teleport-component-generator'
+import { createComponentGenerator } from '@teleporthq/teleport-component-generator'
 
 import PreactMapping from './preact-mapping.json'
 
-const createPreactComponentGenerator = (
+const createPreactComponentGenerator: ComponentGeneratorInstance = ({
+  mappings = [],
+  plugins = [],
+  postprocessors = [],
   variation = PreactStyleVariation.CSSModules,
-  { mappings = [], plugins = [], postprocessors = [] }: GeneratorFactoryParams = {}
-): ComponentGenerator => {
+}: GeneratorFactoryParams = {}): ComponentGenerator => {
   const generator = createComponentGenerator()
-  const stylePlugins = {
+  const stylePlugins: Record<PreactStyleVariation, ComponentPlugin> = {
     [PreactStyleVariation.InlineStyles]: inlineStylesPlugin,
     [PreactStyleVariation.CSSModules]: createCSSModulesPlugin({
       classAttributeName: 'class',
@@ -33,7 +36,7 @@ const createPreactComponentGenerator = (
       forceScoping: true,
     }),
   }
-  const stylePlugin = stylePlugins[variation]
+  const stylePlugin = stylePlugins[variation as PreactStyleVariation]
   if (!stylePlugin) {
     throw new Error(`Invalid style variation '${variation}'`)
   }
diff --git a/packages/teleport-component-generator-react/src/index.ts b/packages/teleport-component-generator-react/src/index.ts
index 4cc23c70..c4364319 100644
--- a/packages/teleport-component-generator-react/src/index.ts
+++ b/packages/teleport-component-generator-react/src/index.ts
@@ -7,9 +7,13 @@ import reactStyledComponentsPlugin from '@teleporthq/teleport-plugin-react-style
 import reactStyledJSXPlugin from '@teleporthq/teleport-plugin-react-styled-jsx'
 import propTypesPlugin from '@teleporthq/teleport-plugin-jsx-proptypes'
 import importStatementsPlugin from '@teleporthq/teleport-plugin-import-statements'
-
 import prettierJSX from '@teleporthq/teleport-postprocessor-prettier-jsx'
-
+import {
+  ComponentGenerator,
+  Mapping,
+  ReactStyleVariation,
+  ComponentGeneratorInstance,
+} from '@teleporthq/teleport-types'
 import {
   createComponentGenerator,
   GeneratorFactoryParams,
@@ -17,12 +21,12 @@ import {
 
 import ReactMapping from './react-mapping.json'
 
-import { ComponentGenerator, Mapping, ReactStyleVariation } from '@teleporthq/teleport-types'
-
-const createReactComponentGenerator = (
+const createReactComponentGenerator: ComponentGeneratorInstance = ({
+  mappings = [],
+  plugins = [],
+  postprocessors = [],
   variation = ReactStyleVariation.CSSModules,
-  { mappings = [], plugins = [], postprocessors = [] }: GeneratorFactoryParams = {}
-): ComponentGenerator => {
+}: GeneratorFactoryParams = {}): ComponentGenerator => {
   const cssPlugin = createCSSPlugin({
     templateChunkName: 'jsx-component',
     templateStyle: 'jsx',
diff --git a/packages/teleport-component-generator-reactnative/src/index.ts b/packages/teleport-component-generator-reactnative/src/index.ts
index 88084c07..9c02d21e 100644
--- a/packages/teleport-component-generator-reactnative/src/index.ts
+++ b/packages/teleport-component-generator-reactnative/src/index.ts
@@ -5,14 +5,16 @@ import propTypesPlugin from '@teleporthq/teleport-plugin-jsx-proptypes'
 import importStatementsPlugin from '@teleporthq/teleport-plugin-import-statements'
 import resourceLoaderPlugin from '@teleporthq/teleport-plugin-reactnative-resource-loader'
 import navigationPlugin from '@teleporthq/teleport-plugin-reactnative-component-navigation'
-
 import prettierJSX from '@teleporthq/teleport-postprocessor-prettier-jsx'
-
 import { createComponentGenerator } from '@teleporthq/teleport-component-generator'
-
 import ReactNativeMapping from './react-native-mapping.json'
-
-import { ComponentGenerator, Mapping, ReactNativeStyleVariation } from '@teleporthq/teleport-types'
+import {
+  ComponentGenerator,
+  Mapping,
+  ReactNativeStyleVariation,
+  GeneratorFactoryParams,
+  ComponentGeneratorInstance,
+} from '@teleporthq/teleport-types'
 
 // This extracts Text, View, Image as illegal element names
 const rnMapping = ReactNativeMapping as Mapping
@@ -30,24 +32,28 @@ const stylePlugins = {
   [ReactNativeStyleVariation.StyledComponents]: styledComponentsPlugin,
 }
 
-const createReactNativeComponentGenerator = (
+const createReactNativeComponentGenerator: ComponentGeneratorInstance = ({
   variation = ReactNativeStyleVariation.StyledComponents,
-  mapping: Mapping = {}
-): ComponentGenerator => {
+  mappings = [],
+  postprocessors = [],
+  plugins = [],
+}: GeneratorFactoryParams = {}): ComponentGenerator => {
   const generator = createComponentGenerator()
-  const stylePlugin = stylePlugins[variation] || inlineStylesPlugin
+  const stylePlugin = stylePlugins[variation as ReactNativeStyleVariation] || inlineStylesPlugin
 
   generator.addMapping(ReactNativeMapping as Mapping)
-  generator.addMapping(mapping)
+  mappings.forEach((mapping) => generator.addMapping(mapping))
 
   generator.addPlugin(reactComponentPlugin)
   generator.addPlugin(stylePlugin)
   generator.addPlugin(propTypesPlugin)
   generator.addPlugin(resourceLoaderPlugin)
   generator.addPlugin(navigationPlugin)
+  plugins.forEach((plugin) => generator.addPlugin(plugin))
   generator.addPlugin(importStatementsPlugin)
 
   generator.addPostProcessor(prettierJSX)
+  postprocessors.forEach((postprocessor) => generator.addPostProcessor(postprocessor))
 
   const originalGeneratorFn = generator.generateComponent
 
@@ -62,5 +68,3 @@ const createReactNativeComponentGenerator = (
 }
 
 export { createReactNativeComponentGenerator, ReactNativeMapping, ReactNativeStyleVariation }
-
-export default createReactNativeComponentGenerator()
diff --git a/packages/teleport-component-generator-stencil/src/index.ts b/packages/teleport-component-generator-stencil/src/index.ts
index f096357d..90b866db 100644
--- a/packages/teleport-component-generator-stencil/src/index.ts
+++ b/packages/teleport-component-generator-stencil/src/index.ts
@@ -8,11 +8,15 @@ import {
   GeneratorFactoryParams,
 } from '@teleporthq/teleport-component-generator'
 
-import { ComponentGenerator, FileType } from '@teleporthq/teleport-types'
+import {
+  ComponentGenerator,
+  FileType,
+  ComponentGeneratorInstance,
+} from '@teleporthq/teleport-types'
 
 import StencilMapping from './stencil-mapping.json'
 
-const createStencilComponentGenerator = ({
+const createStencilComponentGenerator: ComponentGeneratorInstance = ({
   mappings = [],
   plugins = [],
   postprocessors = [],
diff --git a/packages/teleport-component-generator-vue/src/index.ts b/packages/teleport-component-generator-vue/src/index.ts
index a567aa41..51635b7c 100644
--- a/packages/teleport-component-generator-vue/src/index.ts
+++ b/packages/teleport-component-generator-vue/src/index.ts
@@ -2,20 +2,17 @@ import {
   createComponentGenerator,
   GeneratorFactoryParams,
 } from '@teleporthq/teleport-component-generator'
-
 import vueComponentPlugin from '@teleporthq/teleport-plugin-vue-base-component'
 import { createCSSPlugin } from '@teleporthq/teleport-plugin-css'
 import importStatementsPlugin from '@teleporthq/teleport-plugin-import-statements'
-
 import prettierJS from '@teleporthq/teleport-postprocessor-prettier-js'
 import prettierHTML from '@teleporthq/teleport-postprocessor-prettier-html'
 import vueFileProcessor from '@teleporthq/teleport-postprocessor-vue-file'
+import { ComponentGenerator, ComponentGeneratorInstance } from '@teleporthq/teleport-types'
 
 import VueMapping from './vue-mapping.json'
 
-import { ComponentGenerator } from '@teleporthq/teleport-types'
-
-const createVueComponentGenerator = ({
+const createVueComponentGenerator: ComponentGeneratorInstance = ({
   mappings = [],
   plugins = [],
   postprocessors = [],
diff --git a/packages/teleport-component-generator/src/index.ts b/packages/teleport-component-generator/src/index.ts
index 49266d93..9e2478c6 100644
--- a/packages/teleport-component-generator/src/index.ts
+++ b/packages/teleport-component-generator/src/index.ts
@@ -1,32 +1,24 @@
 import { Validator, Parser } from '@teleporthq/teleport-uidl-validator'
 import { Resolver, HTMLMapping } from '@teleporthq/teleport-uidl-resolver'
-import AssemblyLine from './assembly-line'
-import Builder from './builder'
-
 import { UIDLUtils } from '@teleporthq/teleport-shared'
-
 import {
   ChunkDefinition,
   ComponentGenerator,
   CompiledComponent,
-  ComponentPlugin,
   PostProcessor,
   Mapping,
   FileType,
   GeneratorOptions,
+  GeneratorFactoryParams,
 } from '@teleporthq/teleport-types'
-
-interface GeneratorFactoryParams {
-  mappings?: Mapping[]
-  plugins?: ComponentPlugin[]
-  postprocessors?: PostProcessor[]
-}
+import AssemblyLine from './assembly-line'
+import Builder from './builder'
 
 const createComponentGenerator = ({
   mappings = [],
   plugins = [],
   postprocessors = [],
-}: GeneratorFactoryParams = {}): ComponentGenerator => {
+}: Omit<GeneratorFactoryParams, 'variation'> = {}): ComponentGenerator => {
   const validator = new Validator()
   const resolver = new Resolver([HTMLMapping as Mapping, ...mappings])
   const assemblyLine = new AssemblyLine(plugins)
diff --git a/packages/teleport-plugin-react-styled-components/src/style-sheet.ts b/packages/teleport-plugin-react-styled-components/src/style-sheet.ts
index 47c4455e..38d1fe9e 100644
--- a/packages/teleport-plugin-react-styled-components/src/style-sheet.ts
+++ b/packages/teleport-plugin-react-styled-components/src/style-sheet.ts
@@ -1,5 +1,4 @@
 import * as t from '@babel/types'
-import { ASTUtils } from '@teleporthq/teleport-plugin-common'
 import {
   ComponentPlugin,
   ComponentPluginFactory,
@@ -103,7 +102,16 @@ export const createStyleSheetPlugin: ComponentPluginFactory<StyleSheetPlugin> =
           t.variableDeclaration('const', [
             t.variableDeclarator(
               t.identifier('TOKENS'),
-              ASTUtils.objectToObjectExpression(tokensMap)
+              t.objectExpression(
+                Object.keys(tokensMap).reduce((acc: t.ObjectProperty[], token) => {
+                  const value =
+                    typeof tokensMap[token] === 'number'
+                      ? t.numericLiteral(Number(tokensMap[token]))
+                      : t.stringLiteral(String(tokensMap[token]))
+                  acc.push(t.objectProperty(t.identifier(token), value))
+                  return acc
+                }, [])
+              )
             ),
           ])
         ),
diff --git a/packages/teleport-project-generator-angular/src/index.ts b/packages/teleport-project-generator-angular/src/index.ts
index 13f6baa4..da860711 100644
--- a/packages/teleport-project-generator-angular/src/index.ts
+++ b/packages/teleport-project-generator-angular/src/index.ts
@@ -1,6 +1,9 @@
 import { createAngularModulePlugin } from '@teleporthq/teleport-plugin-angular-module'
 import { createImportPlugin } from '@teleporthq/teleport-plugin-import-statements'
-import { createAngularComponentGenerator } from '@teleporthq/teleport-component-generator-angular'
+import {
+  createAngularComponentGenerator,
+  AngularMapping,
+} from '@teleporthq/teleport-component-generator-angular'
 import { createPrettierTSPostProcessor } from '@teleporthq/teleport-postprocessor-prettier-ts'
 import { createPrettierHTMLPostProcessor } from '@teleporthq/teleport-postprocessor-prettier-html'
 import { createComponentGenerator } from '@teleporthq/teleport-component-generator'
@@ -16,41 +19,22 @@ const createAngularProjectGenerator = () => {
   const prettierTS = createPrettierTSPostProcessor({ fileType: FileType.TS })
   const importStatementsPlugin = createImportPlugin({ fileType: FileType.TS })
 
-  const rootModuleGeneratorAngular = createAngularModulePlugin({ moduleType: 'root' })
-  const componentModuleGeneratorAngular = createAngularModulePlugin({ moduleType: 'component' })
-  const pagesModuleGeneratorAngular = createAngularModulePlugin({ moduleType: 'page' })
-
-  const angularComponentGenerator = createAngularComponentGenerator()
-  angularComponentGenerator.addMapping(AngularProjectMapping as Mapping)
-
-  const angularPageGenerator = createAngularComponentGenerator()
-
-  const angularRootModuleGenerator = createComponentGenerator()
-  angularRootModuleGenerator.addPlugin(rootModuleGeneratorAngular)
-  angularRootModuleGenerator.addPlugin(importStatementsPlugin)
-  angularRootModuleGenerator.addPostProcessor(prettierTS)
-
-  const angularComponentModuleGenerator = createComponentGenerator()
-  angularComponentModuleGenerator.addPlugin(componentModuleGeneratorAngular)
-  angularComponentModuleGenerator.addPlugin(importStatementsPlugin)
-  angularComponentModuleGenerator.addPostProcessor(prettierTS)
-
-  const anuglarPageModuleGenerator = createComponentGenerator()
-  anuglarPageModuleGenerator.addPlugin(pagesModuleGeneratorAngular)
-  anuglarPageModuleGenerator.addPlugin(importStatementsPlugin)
-  anuglarPageModuleGenerator.addPostProcessor(prettierTS)
-
-  const htmlFileGenerator = createComponentGenerator()
-  htmlFileGenerator.addPostProcessor(createPrettierHTMLPostProcessor())
-
-  const styleSheetGenerator = createComponentGenerator()
-  styleSheetGenerator.addPlugin(createStyleSheetPlugin())
+  const rootModuleGeneratorAngularPlugin = createAngularModulePlugin({ moduleType: 'root' })
+  const componentModuleGeneratorAngularPlugin = createAngularModulePlugin({
+    moduleType: 'component',
+  })
+  const pagesModuleGeneratorAngularPlugin = createAngularModulePlugin({ moduleType: 'page' })
 
   const generator = createProjectGenerator({
     components: {
-      generator: angularComponentGenerator,
-      moduleGenerator: angularComponentModuleGenerator,
+      generator: createAngularComponentGenerator,
+      mappings: [AngularProjectMapping as Mapping],
       path: ['src', 'app', 'components'],
+      module: {
+        generator: createComponentGenerator,
+        plugins: [componentModuleGeneratorAngularPlugin, importStatementsPlugin],
+        postprocessors: [prettierTS],
+      },
       options: {
         createFolderForEachComponent: true,
         customComponentFileName: (name: string) => `${name}.component`,
@@ -59,9 +43,14 @@ const createAngularProjectGenerator = () => {
       },
     },
     pages: {
-      generator: angularPageGenerator,
-      moduleGenerator: anuglarPageModuleGenerator,
+      generator: createAngularComponentGenerator,
+      mappings: [AngularMapping as Mapping],
       path: ['src', 'app', 'pages'],
+      module: {
+        generator: createComponentGenerator,
+        plugins: [pagesModuleGeneratorAngularPlugin, importStatementsPlugin],
+        postprocessors: [prettierTS],
+      },
       options: {
         createFolderForEachComponent: true,
         customComponentFileName: (name: string) => `${name}.component`,
@@ -70,17 +59,21 @@ const createAngularProjectGenerator = () => {
       },
     },
     projectStyleSheet: {
-      generator: styleSheetGenerator,
+      generator: createComponentGenerator,
+      plugins: [createStyleSheetPlugin({ fileName: 'styles' })],
       fileName: 'styles',
       path: ['src'],
     },
     router: {
-      generator: angularRootModuleGenerator,
+      generator: createComponentGenerator,
+      plugins: [rootModuleGeneratorAngularPlugin, importStatementsPlugin],
+      postprocessors: [prettierTS],
       path: ['src', 'app'],
       fileName: 'app.module',
     },
     entry: {
-      generator: htmlFileGenerator,
+      generator: createComponentGenerator,
+      postprocessors: [createPrettierHTMLPostProcessor()],
       path: ['src'],
       fileName: 'index',
       options: {
diff --git a/packages/teleport-project-generator-gatsby/package.json b/packages/teleport-project-generator-gatsby/package.json
index 7d846cfc..7a350daa 100644
--- a/packages/teleport-project-generator-gatsby/package.json
+++ b/packages/teleport-project-generator-gatsby/package.json
@@ -33,7 +33,6 @@
     "@teleporthq/teleport-plugin-import-statements": "^0.15.0",
     "@teleporthq/teleport-plugin-jsx-head-config": "^0.15.0",
     "@teleporthq/teleport-plugin-jsx-proptypes": "^0.15.0",
-    "@teleporthq/teleport-plugin-react-app-routing": "^0.15.0",
     "@teleporthq/teleport-plugin-react-base-component": "^0.15.0",
     "@teleporthq/teleport-plugin-react-styled-components": "^0.15.0",
     "@teleporthq/teleport-postprocessor-prettier-html": "^0.15.0",
@@ -42,8 +41,7 @@
     "@teleporthq/teleport-project-generator": "^0.15.0",
     "@teleporthq/teleport-shared": "^0.15.0",
     "@teleporthq/teleport-types": "^0.15.0",
-    "@teleporthq/teleport-uidl-validator": "^0.15.0",
-    "magic-string": "^0.25.4"
+    "@teleporthq/teleport-uidl-validator": "^0.15.0"
   },
   "gitHead": "b185c3fdb7dc94ff8c7eed63f7edba055fffa8d0"
 }
diff --git a/packages/teleport-project-generator-gatsby/src/index.ts b/packages/teleport-project-generator-gatsby/src/index.ts
index fb96dcec..fd076745 100644
--- a/packages/teleport-project-generator-gatsby/src/index.ts
+++ b/packages/teleport-project-generator-gatsby/src/index.ts
@@ -1,87 +1,46 @@
 import { createProjectGenerator } from '@teleporthq/teleport-project-generator'
 import { createComponentGenerator } from '@teleporthq/teleport-component-generator'
-import reactAppRoutingPlugin from '@teleporthq/teleport-plugin-react-app-routing'
 import reactBasePlugin from '@teleporthq/teleport-plugin-react-base-component'
+import {
+  GatsbyStyleVariation,
+  ComponentGenerator,
+  TeleportError,
+  ComponentGeneratorInstance,
+  Mapping,
+  GeneratorFactoryParams,
+  FileType,
+} from '@teleporthq/teleport-types'
 import {
   createCSSModulesPlugin,
   createStyleSheetPlugin,
 } from '@teleporthq/teleport-plugin-css-modules'
-import {
-  createReactStyledComponentsPlugin,
-  createStyleSheetPlugin as createStyledComponentsStyleSheetPlugin,
-} from '@teleporthq/teleport-plugin-react-styled-components'
+import reactStyledComponentsPlugin from '@teleporthq/teleport-plugin-react-styled-components'
 import reactProptypes from '@teleporthq/teleport-plugin-jsx-proptypes'
 import importStatementsPlugin from '@teleporthq/teleport-plugin-import-statements'
 import headConfigPlugin from '@teleporthq/teleport-plugin-jsx-head-config'
 import prettierJS from '@teleporthq/teleport-postprocessor-prettier-js'
 import prettierJSX from '@teleporthq/teleport-postprocessor-prettier-jsx'
-
-import {
-  Mapping,
-  ComponentPlugin,
-  FileType,
-  ReactStyleVariation,
-  ProjectStrategy,
-} from '@teleporthq/teleport-types'
-
 import GatsbyProjectMapping from './gatsby-mapping.json'
 import GatsbyTemplate from './project-template'
-import {
-  createCustomHTMLEntryFile,
-  appendToConfigFile,
-  styleSheetDependentConfigGenerator,
-} from './utils'
-
-const cssModulesPlugin = createCSSModulesPlugin({
-  moduleExtension: true,
-  camelCaseClassNames: true,
-})
-const styledComponentsPlugin = createReactStyledComponentsPlugin()
-
-interface GatsbyProjectConfig {
-  variation?: ReactStyleVariation
-}
-
-const createGatsbyProjectGenerator = (config?: GatsbyProjectConfig) => {
-  const variation = config?.variation || ReactStyleVariation.CSSModules
-  const reactComponentGenerator = createCustomReactComponentGenerator(variation)
-  const reactPagesGenerator = createCustomReactComponentGenerator(variation, [headConfigPlugin])
-
-  const routingComponentGenerator = createComponentGenerator()
-  routingComponentGenerator.addPlugin(reactAppRoutingPlugin)
-  routingComponentGenerator.addPlugin(importStatementsPlugin)
-  routingComponentGenerator.addPostProcessor(prettierJS)
-
-  const htmlFileGenerator = createComponentGenerator()
-  htmlFileGenerator.addPostProcessor(prettierJS)
-
-  const configGenerator = createComponentGenerator()
-  configGenerator.addPlugin(importStatementsPlugin)
-  configGenerator.addPostProcessor(prettierJS)
-
-  const styleSheetGenerator = createComponentGenerator()
-  if (variation === ReactStyleVariation.StyledComponents) {
-    styleSheetGenerator.addPlugin(createStyledComponentsStyleSheetPlugin())
-    styleSheetGenerator.addPlugin(importStatementsPlugin)
-    styleSheetGenerator.addPostProcessor(prettierJS)
-  } else {
-    styleSheetGenerator.addPlugin(createStyleSheetPlugin({ moduleExtension: true }))
-  }
+import { createCustomHTMLEntryFile, styleSheetDependentConfigGenerator } from './utils'
 
-  const strategy: ProjectStrategy = {
+const createGatsbyProjectGenerator = () => {
+  const generator = createProjectGenerator({
     components: {
-      generator: reactComponentGenerator,
+      generator: createCustomReactGatsbyComponentGenerator,
       path: ['src', 'components'],
     },
     pages: {
-      generator: reactPagesGenerator,
+      generator: createCustomReactGatsbyComponentGenerator,
       path: ['src', 'pages'],
+      plugins: [headConfigPlugin],
       options: {
         useFileNameForNavigation: true,
       },
     },
     entry: {
-      generator: htmlFileGenerator,
+      generator: createComponentGenerator,
+      postprocessors: [prettierJS],
       path: ['src'],
       fileName: 'html',
       chunkGenerationFunction: createCustomHTMLEntryFile,
@@ -91,59 +50,68 @@ const createGatsbyProjectGenerator = (config?: GatsbyProjectConfig) => {
       path: ['static'],
     },
     projectStyleSheet: {
-      generator: styleSheetGenerator,
+      generator: createComponentGenerator,
+      plugins: [createStyleSheetPlugin({ moduleExtension: true })],
       fileName: 'style',
       path: ['src'],
       importFile: true,
     },
-  }
-
-  if (variation === ReactStyleVariation.CSSModules) {
-    strategy.framework = {
+    framework: {
       config: {
         fileName: 'gatsby-browser',
         fileType: FileType.JS,
         path: [''],
-        generator: configGenerator,
+        generator: createComponentGenerator,
+        plugins: [importStatementsPlugin],
+        postprocessors: [prettierJS],
         configContentGenerator: styleSheetDependentConfigGenerator,
         isGlobalStylesDependent: true,
       },
-    }
-  }
-
-  if (variation === ReactStyleVariation.StyledComponents) {
-    strategy.framework = {
-      replace: {
-        fileName: 'gatsby-config',
-        fileType: FileType.JS,
-        path: [''],
-        replaceFile: appendToConfigFile,
-      },
-    }
-  }
-
-  const generator = createProjectGenerator(strategy)
+    },
+  })
 
   return generator
 }
 
-const createCustomReactComponentGenerator = (
-  styleVariation: string,
-  extraPlugins: ComponentPlugin[] = []
-) => {
+const createCustomReactGatsbyComponentGenerator: ComponentGeneratorInstance = ({
+  mappings = [],
+  plugins = [],
+  postprocessors = [],
+  variation = GatsbyStyleVariation.CSSModules,
+}: GeneratorFactoryParams): ComponentGenerator => {
+  const cssModulesPlugin = createCSSModulesPlugin({
+    moduleExtension: true,
+    camelCaseClassNames: true,
+  })
+  const stylePlugins = {
+    [GatsbyStyleVariation.StyledComponents]: reactStyledComponentsPlugin,
+    [GatsbyStyleVariation.CSSModules]: cssModulesPlugin,
+  }
+
+  const stylePlugin = stylePlugins[variation as GatsbyStyleVariation]
+  if (!stylePlugin) {
+    throw new TeleportError(`Un-supported style flavour selected - ${variation}`)
+  }
+
   const reactComponentGenerator = createComponentGenerator()
+
+  mappings.forEach((mapping) => reactComponentGenerator.addMapping(mapping))
   reactComponentGenerator.addPlugin(reactBasePlugin)
-  if (styleVariation === ReactStyleVariation.StyledComponents) {
-    reactComponentGenerator.addPlugin(styledComponentsPlugin)
-  } else {
-    reactComponentGenerator.addPlugin(cssModulesPlugin)
-  }
   reactComponentGenerator.addPlugin(reactProptypes)
-  extraPlugins.forEach((plugin) => reactComponentGenerator.addPlugin(plugin))
+  reactComponentGenerator.addPlugin(stylePlugin)
+
+  plugins.forEach((plugin) => reactComponentGenerator.addPlugin(plugin))
+
   reactComponentGenerator.addPlugin(importStatementsPlugin)
   reactComponentGenerator.addMapping(GatsbyProjectMapping as Mapping)
   reactComponentGenerator.addPostProcessor(prettierJSX)
+  postprocessors.forEach((postprocessor) => reactComponentGenerator.addPostProcessor(postprocessor))
   return reactComponentGenerator
 }
 
-export { createGatsbyProjectGenerator, GatsbyProjectMapping, GatsbyTemplate }
+export {
+  createGatsbyProjectGenerator,
+  GatsbyProjectMapping,
+  GatsbyTemplate,
+  createCustomReactGatsbyComponentGenerator,
+}
diff --git a/packages/teleport-project-generator-gatsby/src/utils.ts b/packages/teleport-project-generator-gatsby/src/utils.ts
index f733e797..38c84071 100644
--- a/packages/teleport-project-generator-gatsby/src/utils.ts
+++ b/packages/teleport-project-generator-gatsby/src/utils.ts
@@ -5,13 +5,10 @@ import {
   ChunkDefinition,
   FileType,
   ChunkType,
-  GeneratedFolder,
   FrameWorkConfigOptions,
 } from '@teleporthq/teleport-types'
 import { UIDLUtils } from '@teleporthq/teleport-shared'
 import { ASTBuilders, ASTUtils } from '@teleporthq/teleport-plugin-common'
-import MagicString from 'magic-string'
-import { STYLED_DEPENDENCIES } from './constants'
 
 export const createCustomHTMLEntryFile = (
   uidl: ProjectUIDL,
@@ -223,33 +220,6 @@ const createObjectpropertyAST = (
   )
 }
 
-export const appendToConfigFile = (
-  template: GeneratedFolder,
-  dependencies: Record<string, string>,
-  fileName: string,
-  fileType: string
-) => {
-  const configFile = template.files.find(
-    (file) => file.name === fileName && file.fileType === fileType
-  )
-
-  if (!configFile || !configFile.content) {
-    throw new Error(`${fileName} not found, while adding gatsby-plugin-styled-components`)
-  }
-
-  const parsedFile = configFile.content.replace('/n', '//n')
-
-  const magic = new MagicString(parsedFile)
-
-  magic.appendRight(parsedFile.length - 10, `,'gatsby-plugin-styled-components'`)
-  configFile.content = magic.toString()
-
-  return {
-    file: configFile,
-    dependencies: { ...dependencies, ...STYLED_DEPENDENCIES },
-  }
-}
-
 export const styleSheetDependentConfigGenerator = (options: FrameWorkConfigOptions, t = types) => {
   const chunks: ChunkDefinition[] = []
   const result = {
diff --git a/packages/teleport-project-generator-gridsome/src/index.ts b/packages/teleport-project-generator-gridsome/src/index.ts
index dc5c461a..bee6d9b5 100644
--- a/packages/teleport-project-generator-gridsome/src/index.ts
+++ b/packages/teleport-project-generator-gridsome/src/index.ts
@@ -1,60 +1,46 @@
 import { createProjectGenerator } from '@teleporthq/teleport-project-generator'
 import { createVueComponentGenerator } from '@teleporthq/teleport-component-generator-vue'
 import { createComponentGenerator } from '@teleporthq/teleport-component-generator'
-
 import { createVueHeadConfigPlugin } from '@teleporthq/teleport-plugin-vue-head-config'
 import prettierHTML from '@teleporthq/teleport-postprocessor-prettier-html'
 import prettierJS from '@teleporthq/teleport-postprocessor-prettier-js'
-
 import { createStyleSheetPlugin } from '@teleporthq/teleport-plugin-css'
 import { Mapping, FileType } from '@teleporthq/teleport-types'
 import { configContentGenerator } from './utils'
 import GridsomeTemplate from './gridsome-project-template'
-import GridsomeProjectMappng from './gridsome-project-mapping.json'
+import GridsomeProjectMapping from './gridsome-project-mapping.json'
 
 const createGridsomeProjectGenerator = () => {
-  const vueComponentGenerator = createVueComponentGenerator()
-  vueComponentGenerator.addMapping(GridsomeProjectMappng as Mapping)
-
   const vueHeadConfigPlugin = createVueHeadConfigPlugin({ metaObjectKey: 'metaInfo' })
-
-  const vuePageGenerator = createVueComponentGenerator()
-  vuePageGenerator.addMapping(GridsomeProjectMappng as Mapping)
-  vuePageGenerator.addPlugin(vueHeadConfigPlugin)
-
-  const htmlFileGenerator = createComponentGenerator()
-  htmlFileGenerator.addPostProcessor(prettierHTML)
-
-  const styleSheetGenerator = createComponentGenerator()
-  styleSheetGenerator.addPlugin(
-    createStyleSheetPlugin({
-      fileName: 'style',
-    })
-  )
-
-  const configGenerator = createComponentGenerator()
-  configGenerator.addPostProcessor(prettierJS)
+  const styleSheetPlugin = createStyleSheetPlugin({
+    fileName: 'style',
+  })
 
   const generator = createProjectGenerator({
     components: {
-      generator: vueComponentGenerator,
+      generator: createVueComponentGenerator,
+      mappings: [GridsomeProjectMapping as Mapping],
       path: ['src', 'components'],
     },
     pages: {
-      generator: vuePageGenerator,
+      generator: createVueComponentGenerator,
+      plugins: [vueHeadConfigPlugin],
+      mappings: [GridsomeProjectMapping as Mapping],
       path: ['src', 'pages'],
       options: {
         useFileNameForNavigation: true,
       },
     },
     projectStyleSheet: {
-      generator: styleSheetGenerator,
+      generator: createComponentGenerator,
+      plugins: [styleSheetPlugin],
       fileName: 'style',
       path: ['src', 'assets'],
     },
     framework: {
       config: {
-        generator: configGenerator,
+        generator: createComponentGenerator,
+        postprocessors: [prettierJS],
         configContentGenerator,
         fileName: 'main',
         fileType: FileType.JS,
@@ -63,7 +49,8 @@ const createGridsomeProjectGenerator = () => {
       },
     },
     entry: {
-      generator: htmlFileGenerator,
+      generator: createComponentGenerator,
+      postprocessors: [prettierHTML],
       path: ['src'],
     },
     static: {
@@ -75,4 +62,4 @@ const createGridsomeProjectGenerator = () => {
   return generator
 }
 
-export { createGridsomeProjectGenerator, GridsomeProjectMappng, GridsomeTemplate }
+export { createGridsomeProjectGenerator, GridsomeProjectMapping, GridsomeTemplate }
diff --git a/packages/teleport-project-generator-next/src/index.ts b/packages/teleport-project-generator-next/src/index.ts
index ca294016..025334ad 100644
--- a/packages/teleport-project-generator-next/src/index.ts
+++ b/packages/teleport-project-generator-next/src/index.ts
@@ -12,49 +12,40 @@ import NextMapping from './next-mapping.json'
 import NextTemplate from './project-template'
 
 const createNextProjectGenerator = () => {
-  const reactComponentGenerator = createReactComponentGenerator(ReactStyleVariation.StyledJSX)
-  reactComponentGenerator.addMapping(NextMapping as Mapping)
-
   const headConfigPlugin = createJSXHeadConfigPlugin({
     configTagIdentifier: 'Head',
     configTagDependencyPath: 'next/head',
     isExternalPackage: false,
   })
-
-  const reactPageGenerator = createReactComponentGenerator(ReactStyleVariation.StyledJSX, {
-    plugins: [headConfigPlugin],
-    mappings: [NextMapping as Mapping],
+  const styleSheetPlugin = createStyleSheetPlugin({
+    fileName: 'style',
   })
 
-  const documentFileGenerator = createComponentGenerator()
-  documentFileGenerator.addPostProcessor(prettierJS)
-
-  const styleSheetGenerator = createComponentGenerator()
-  styleSheetGenerator.addPlugin(createStyleSheetPlugin())
-
-  const configGenerator = createComponentGenerator()
-  configGenerator.addPlugin(importStatementsPlugin)
-  configGenerator.addPostProcessor(prettierJS)
-
   const generator = createProjectGenerator({
+    style: ReactStyleVariation.StyledJSX,
     components: {
-      generator: reactComponentGenerator,
+      generator: createReactComponentGenerator,
+      mappings: [NextMapping as Mapping],
       path: ['components'],
     },
     pages: {
-      generator: reactPageGenerator,
+      generator: createReactComponentGenerator,
       path: ['pages'],
+      plugins: [headConfigPlugin],
+      mappings: [NextMapping as Mapping],
       options: {
         useFileNameForNavigation: true,
       },
     },
     projectStyleSheet: {
-      generator: styleSheetGenerator,
+      generator: createComponentGenerator,
+      plugins: [styleSheetPlugin],
       fileName: 'style',
       path: ['pages'],
     },
     entry: {
-      generator: documentFileGenerator,
+      generator: createComponentGenerator,
+      postprocessors: [prettierJS],
       path: ['pages'],
       fileName: '_document',
       chunkGenerationFunction: createDocumentFileChunks,
@@ -64,7 +55,9 @@ const createNextProjectGenerator = () => {
         fileName: `_app`,
         fileType: FileType.JS,
         path: ['pages'],
-        generator: configGenerator,
+        generator: createComponentGenerator,
+        plugins: [importStatementsPlugin],
+        postprocessors: [prettierJS],
         configContentGenerator,
         isGlobalStylesDependent: true,
       },
diff --git a/packages/teleport-project-generator-next/src/utils.ts b/packages/teleport-project-generator-next/src/utils.ts
index baf09e5f..e521d627 100644
--- a/packages/teleport-project-generator-next/src/utils.ts
+++ b/packages/teleport-project-generator-next/src/utils.ts
@@ -16,7 +16,7 @@ import {
 export const createDocumentFileChunks = (uidl: ProjectUIDL, options: EntryFileOptions) => {
   const { settings, meta, assets, manifest, customCode } = uidl.globals
 
-  const htmlNode = ASTBuilders.createJSXTag('html')
+  const htmlNode = ASTBuilders.createJSXTag('Html')
   const headNode = ASTBuilders.createJSXTag('Head')
   const bodyNode = ASTBuilders.createJSXTag('body')
 
@@ -93,6 +93,7 @@ const createDocumentWrapperAST = (htmlNode: types.JSXElement, t = types) => {
     t.importDeclaration(
       [
         t.importDefaultSpecifier(t.identifier('Document')),
+        t.importSpecifier(t.identifier('Html'), t.identifier('Html')),
         t.importSpecifier(t.identifier('Head'), t.identifier('Head')),
         t.importSpecifier(t.identifier('Main'), t.identifier('Main')),
         t.importSpecifier(t.identifier('NextScript'), t.identifier('NextScript')),
diff --git a/packages/teleport-project-generator-nuxt/src/index.ts b/packages/teleport-project-generator-nuxt/src/index.ts
index ca30d76a..607e9527 100644
--- a/packages/teleport-project-generator-nuxt/src/index.ts
+++ b/packages/teleport-project-generator-nuxt/src/index.ts
@@ -12,39 +12,28 @@ import NuxtMapping from './nuxt-mapping.json'
 import NuxtTemplate from './project-template'
 
 const createNuxtProjectGenerator = () => {
-  const vueComponentGenerator = createVueComponentGenerator()
-  vueComponentGenerator.addMapping(NuxtMapping as Mapping)
-  const vuePageGenerator = createVueComponentGenerator()
-  vuePageGenerator.addMapping(NuxtMapping as Mapping)
-  vuePageGenerator.addPlugin(vueHeadConfigPlugin)
-
-  const htmlFileGenerator = createComponentGenerator()
-  htmlFileGenerator.addPostProcessor(prettierHTML)
-
-  const styleSheetGenerator = createComponentGenerator()
-  styleSheetGenerator.addPlugin(
-    createStyleSheetPlugin({
-      fileName: 'style',
-    })
-  )
-
-  const configGenerator = createComponentGenerator()
-  configGenerator.addPostProcessor(prettierJS)
+  const styleSheetPlugin = createStyleSheetPlugin({
+    fileName: 'style',
+  })
 
   const generator = createProjectGenerator({
     components: {
-      generator: vueComponentGenerator,
+      generator: createVueComponentGenerator,
+      mappings: [NuxtMapping as Mapping],
       path: ['components'],
     },
     pages: {
-      generator: vuePageGenerator,
+      generator: createVueComponentGenerator,
+      plugins: [vueHeadConfigPlugin],
+      mappings: [NuxtMapping as Mapping],
       path: ['pages'],
       options: {
         useFileNameForNavigation: true,
       },
     },
     entry: {
-      generator: htmlFileGenerator,
+      generator: createComponentGenerator,
+      postprocessors: [prettierHTML],
       fileName: 'app',
       path: [],
       options: {
@@ -52,7 +41,8 @@ const createNuxtProjectGenerator = () => {
       },
     },
     projectStyleSheet: {
-      generator: styleSheetGenerator,
+      generator: createComponentGenerator,
+      plugins: [styleSheetPlugin],
       fileName: 'style',
       path: [''],
     },
@@ -61,7 +51,8 @@ const createNuxtProjectGenerator = () => {
         fileName: 'nuxt.config',
         fileType: FileType.JS,
         path: [''],
-        generator: configGenerator,
+        generator: createComponentGenerator,
+        postprocessors: [prettierJS],
         configContentGenerator,
         isGlobalStylesDependent: true,
       },
diff --git a/packages/teleport-project-generator-preact/src/index.ts b/packages/teleport-project-generator-preact/src/index.ts
index c58433ec..02bd356c 100644
--- a/packages/teleport-project-generator-preact/src/index.ts
+++ b/packages/teleport-project-generator-preact/src/index.ts
@@ -1,5 +1,8 @@
 import { createProjectGenerator } from '@teleporthq/teleport-project-generator'
-import { createPreactComponentGenerator } from '@teleporthq/teleport-component-generator-preact'
+import {
+  createPreactComponentGenerator,
+  PreactMapping,
+} from '@teleporthq/teleport-component-generator-preact'
 import { createComponentGenerator } from '@teleporthq/teleport-component-generator'
 import { createReactAppRoutingPlugin } from '@teleporthq/teleport-plugin-react-app-routing'
 import headConfigPlugin from '@teleporthq/teleport-plugin-jsx-head-config'
@@ -17,56 +20,44 @@ import PreactProjectMapping from './preact-project-mapping.json'
 import { CUSTOM_HEAD_CONTENT, CUSTOM_BODY_CONTENT, POLYFILLS_TAG, ENTRY_CHUNK } from './constants'
 
 const createPreactProjectGenerator = () => {
-  const preactComponentGenerator = createPreactComponentGenerator(PreactStyleVariation.CSSModules, {
-    mappings: [PreactProjectMapping as Mapping],
-  })
-
-  const preactPageGenerator = createPreactComponentGenerator(PreactStyleVariation.CSSModules, {
-    plugins: [headConfigPlugin],
-    mappings: [PreactProjectMapping as Mapping],
+  const styleSheetPlugin = createStyleSheetPlugin({
+    fileName: 'style',
+    moduleExtension: false,
   })
-
-  const styleSheetGenerator = createComponentGenerator()
-  styleSheetGenerator.addPlugin(
-    createStyleSheetPlugin({
-      fileName: 'style',
-    })
-  )
-
   const routerPlugin = createReactAppRoutingPlugin({ flavor: 'preact' })
-  const routingComponentGenerator = createComponentGenerator()
-  routingComponentGenerator.addPlugin(routerPlugin)
-  routingComponentGenerator.addPlugin(createCSSModulesPlugin())
-  routingComponentGenerator.addPlugin(importStatementsPlugin)
-  routingComponentGenerator.addPostProcessor(prettierJS)
-
-  const htmlFileGenerator = createComponentGenerator()
 
   const generator = createProjectGenerator({
+    style: PreactStyleVariation.CSSModules,
     components: {
-      generator: preactComponentGenerator,
+      generator: createPreactComponentGenerator,
+      mappings: [PreactMapping as Mapping],
       path: ['src', 'components'],
     },
     pages: {
-      generator: preactPageGenerator,
+      generator: createPreactComponentGenerator,
       path: ['src', 'routes'],
+      plugins: [headConfigPlugin],
+      mappings: [PreactProjectMapping as Mapping],
       options: {
         createFolderForEachComponent: true,
       },
     },
     router: {
-      generator: routingComponentGenerator,
+      generator: createComponentGenerator,
+      plugins: [routerPlugin, createCSSModulesPlugin(), importStatementsPlugin],
+      postprocessors: [prettierJS],
       path: ['src', 'components'],
       fileName: 'app',
     },
     projectStyleSheet: {
-      generator: styleSheetGenerator,
+      generator: createComponentGenerator,
+      plugins: [styleSheetPlugin],
       fileName: 'style',
       path: ['src', 'routes'],
       importFile: true,
     },
     entry: {
-      generator: htmlFileGenerator,
+      generator: createComponentGenerator,
       path: ['src'],
       fileName: 'index',
       options: {
diff --git a/packages/teleport-project-generator-react/src/index.ts b/packages/teleport-project-generator-react/src/index.ts
index c390ccf1..f86aec3b 100644
--- a/packages/teleport-project-generator-react/src/index.ts
+++ b/packages/teleport-project-generator-react/src/index.ts
@@ -16,50 +16,42 @@ import ReactProjectMapping from './react-project-mapping.json'
 import ReactTemplate from './project-template'
 
 const createReactProjectGenerator = () => {
-  const reactComponentGenerator = createReactComponentGenerator(ReactStyleVariation.CSSModules)
-  reactComponentGenerator.addMapping(ReactProjectMapping as Mapping)
-
-  const reactPagesGenerator = createReactComponentGenerator(ReactStyleVariation.CSSModules, {
-    plugins: [headConfigPlugin],
-    mappings: [ReactProjectMapping as Mapping],
-  })
-
-  const routingComponentGenerator = createComponentGenerator()
-  routingComponentGenerator.addPlugin(reactAppRoutingPlugin)
-  routingComponentGenerator.addPlugin(createCSSModulesPlugin({ moduleExtension: true }))
-  routingComponentGenerator.addPlugin(importStatementsPlugin)
-  routingComponentGenerator.addPostProcessor(prettierJS)
-
-  const styleSheetGenerator = createComponentGenerator()
-  styleSheetGenerator.addPlugin(createStyleSheetPlugin({ moduleExtension: true }))
-
-  const htmlFileGenerator = createComponentGenerator()
-  htmlFileGenerator.addPostProcessor(prettierHTML)
-
   const generator = createProjectGenerator({
+    style: ReactStyleVariation.CSSModules,
     components: {
-      generator: reactComponentGenerator,
+      generator: createReactComponentGenerator,
+      mappings: [ReactProjectMapping as Mapping],
       path: ['src', 'components'],
     },
     pages: {
-      generator: reactPagesGenerator,
+      generator: createReactComponentGenerator,
+      mappings: [ReactProjectMapping as Mapping],
+      plugins: [headConfigPlugin],
       path: ['src', 'views'],
     },
     projectStyleSheet: {
-      generator: styleSheetGenerator,
+      generator: createComponentGenerator,
+      plugins: [createStyleSheetPlugin({ moduleExtension: true })],
       fileName: 'style',
       path: ['src'],
       importFile: true,
     },
     router: {
-      generator: routingComponentGenerator,
-      path: ['src'],
+      generator: createComponentGenerator,
+      plugins: [
+        reactAppRoutingPlugin,
+        createCSSModulesPlugin({ moduleExtension: true }),
+        importStatementsPlugin,
+      ],
+      postprocessors: [prettierJS],
       fileName: 'index',
+      path: ['src'],
     },
     entry: {
-      generator: htmlFileGenerator,
-      path: ['public'],
+      generator: createComponentGenerator,
+      postprocessors: [prettierHTML],
       fileName: 'index',
+      path: ['public'],
     },
     static: {
       prefix: '',
diff --git a/packages/teleport-project-generator-reactnative/package.json b/packages/teleport-project-generator-reactnative/package.json
index 23acc24e..2fe022aa 100644
--- a/packages/teleport-project-generator-reactnative/package.json
+++ b/packages/teleport-project-generator-reactnative/package.json
@@ -28,6 +28,7 @@
   "dependencies": {
     "@teleporthq/teleport-component-generator": "^0.15.0",
     "@teleporthq/teleport-component-generator-reactnative": "^0.15.0",
+    "@teleporthq/teleport-plugin-react-styled-components": "^0.15.0",
     "@teleporthq/teleport-plugin-import-statements": "^0.15.0",
     "@teleporthq/teleport-plugin-reactnative-app-routing": "^0.15.0",
     "@teleporthq/teleport-postprocessor-prettier-jsx": "^0.15.0",
diff --git a/packages/teleport-project-generator-reactnative/src/index.ts b/packages/teleport-project-generator-reactnative/src/index.ts
index ff499da0..11cf6581 100644
--- a/packages/teleport-project-generator-reactnative/src/index.ts
+++ b/packages/teleport-project-generator-reactnative/src/index.ts
@@ -1,42 +1,40 @@
 import { createProjectGenerator } from '@teleporthq/teleport-project-generator'
 import { createReactNativeComponentGenerator } from '@teleporthq/teleport-component-generator-reactnative'
+import { createStyleSheetPlugin } from '@teleporthq/teleport-plugin-react-styled-components'
 import { createComponentGenerator } from '@teleporthq/teleport-component-generator'
-
 import reactNativeAppRoutingPlugin from '@teleporthq/teleport-plugin-reactnative-app-routing'
 import importStatementsPlugin from '@teleporthq/teleport-plugin-import-statements'
 import prettierJSX from '@teleporthq/teleport-postprocessor-prettier-jsx'
-
 import { Mapping } from '@teleporthq/teleport-types'
 
 import ReactNativeProjectMapping from './reactnative-project-mapping.json'
 import ReactNativeTemplate from './reactnative-project-template'
 
 const createReactNativeProjectGenerator = () => {
-  const reactComponentGenerator = createReactNativeComponentGenerator()
-  reactComponentGenerator.addMapping(ReactNativeProjectMapping as Mapping)
-
-  const reactPagesGenerator = createReactNativeComponentGenerator()
-  reactPagesGenerator.addMapping(ReactNativeProjectMapping as Mapping)
-
-  const routingComponentGenerator = createComponentGenerator()
-  routingComponentGenerator.addPlugin(reactNativeAppRoutingPlugin)
-  routingComponentGenerator.addPlugin(importStatementsPlugin)
-  routingComponentGenerator.addPostProcessor(prettierJSX)
-
   const generator = createProjectGenerator({
     components: {
-      generator: reactComponentGenerator,
+      generator: createReactNativeComponentGenerator,
+      mappings: [ReactNativeProjectMapping as Mapping],
       path: ['src', 'components'],
     },
     pages: {
-      generator: reactPagesGenerator,
+      generator: createReactNativeComponentGenerator,
+      mappings: [ReactNativeProjectMapping as Mapping],
       path: ['src', 'screens'],
     },
     router: {
-      generator: routingComponentGenerator,
+      generator: createComponentGenerator,
+      plugins: [reactNativeAppRoutingPlugin, importStatementsPlugin],
+      postprocessors: [prettierJSX],
       path: ['src'],
       fileName: 'App',
     },
+    projectStyleSheet: {
+      generator: createComponentGenerator,
+      plugins: [createStyleSheetPlugin(), importStatementsPlugin],
+      fileName: 'style',
+      path: ['src'],
+    },
     static: {
       prefix: '/assets',
       path: ['src', 'assets'],
diff --git a/packages/teleport-project-generator-stencil/src/index.ts b/packages/teleport-project-generator-stencil/src/index.ts
index d8ac4939..7ede6cc3 100644
--- a/packages/teleport-project-generator-stencil/src/index.ts
+++ b/packages/teleport-project-generator-stencil/src/index.ts
@@ -13,55 +13,46 @@ import StencilProjectMapping from './stencil-mapping.json'
 import StencilTemplate from './project-template'
 
 const createStencilProjectGenerator = () => {
-  const prettierJS = createPrettierJSPostProcessor({ fileType: FileType.TSX })
+  const prettierTSX = createPrettierJSPostProcessor({ fileType: FileType.TSX })
   const importStatementsPlugin = createImportPlugin({ fileType: FileType.TSX })
-
-  const stencilComponentGenerator = createStencilComponentGenerator()
-  stencilComponentGenerator.addMapping(StencilProjectMapping as Mapping)
-
-  const routingComponentGenerator = createComponentGenerator()
-  routingComponentGenerator.addPlugin(stencilAppRouting)
-  routingComponentGenerator.addPlugin(importStatementsPlugin)
-  routingComponentGenerator.addPostProcessor(prettierJS)
-
-  const htmlFileGenerator = createComponentGenerator()
   const prettierHTML = createPrettierHTMLPostProcessor()
-  htmlFileGenerator.addPostProcessor(prettierHTML)
-
-  const styleSheetGenerator = createComponentGenerator()
-  styleSheetGenerator.addPlugin(
-    createStyleSheetPlugin({
-      fileName: 'style',
-    })
-  )
+  const styleSheetPlugin = createStyleSheetPlugin({
+    fileName: 'style',
+  })
 
   const generator = createProjectGenerator({
     components: {
-      generator: stencilComponentGenerator,
+      generator: createStencilComponentGenerator,
+      mappings: [StencilProjectMapping as Mapping],
       path: ['src', 'components'],
       options: {
         createFolderForEachComponent: true,
       },
     },
     pages: {
-      generator: stencilComponentGenerator,
+      generator: createStencilComponentGenerator,
+      mappings: [StencilProjectMapping as Mapping],
       path: ['src', 'components'],
       options: {
         createFolderForEachComponent: true,
       },
     },
     projectStyleSheet: {
-      generator: styleSheetGenerator,
+      generator: createComponentGenerator,
+      plugins: [styleSheetPlugin],
       fileName: 'style',
       path: ['src'],
     },
     router: {
-      generator: routingComponentGenerator,
+      generator: createComponentGenerator,
+      plugins: [stencilAppRouting, importStatementsPlugin],
+      postprocessors: [prettierTSX],
       path: ['src', 'components'],
       fileName: 'app-root',
     },
     entry: {
-      generator: htmlFileGenerator,
+      generator: createComponentGenerator,
+      postprocessors: [prettierHTML],
       path: ['src'],
       fileName: 'index',
       options: {
diff --git a/packages/teleport-project-generator-vue/src/index.ts b/packages/teleport-project-generator-vue/src/index.ts
index 804dc7ad..0d9b1567 100644
--- a/packages/teleport-project-generator-vue/src/index.ts
+++ b/packages/teleport-project-generator-vue/src/index.ts
@@ -13,49 +13,37 @@ import VueTemplate from './project-template'
 import VueProjectMapping from './vue-project-mapping.json'
 
 const createVueProjectGenerator = () => {
-  const vueComponentGenerator = createVueComponentGenerator()
-  vueComponentGenerator.addMapping(VueProjectMapping as Mapping)
-
   const vueHeadConfigPlugin = createVueHeadConfigPlugin({ metaObjectKey: 'metaInfo' })
 
-  const vuePageGenerator = createVueComponentGenerator()
-  vuePageGenerator.addMapping(VueProjectMapping as Mapping)
-  vuePageGenerator.addPlugin(vueHeadConfigPlugin)
-
-  const vueRouterGenerator = createComponentGenerator()
-  vueRouterGenerator.addPlugin(vueRoutingPlugin)
-  vueRouterGenerator.addPlugin(pluginCSS)
-  vueRouterGenerator.addPlugin(importStatementsPlugin)
-  vueRouterGenerator.addPostProcessor(prettierJS)
-
-  const htmlFileGenerator = createComponentGenerator()
-  htmlFileGenerator.addPostProcessor(prettierHTML)
-
-  const styleSheetGenerator = createComponentGenerator()
-  styleSheetGenerator.addPlugin(createStyleSheetPlugin())
-
   const generator = createProjectGenerator({
     components: {
-      generator: vueComponentGenerator,
+      generator: createVueComponentGenerator,
+      mappings: [VueProjectMapping as Mapping],
       path: ['src', 'components'],
     },
     pages: {
-      generator: vuePageGenerator,
+      generator: createVueComponentGenerator,
+      plugins: [vueHeadConfigPlugin],
+      mappings: [VueProjectMapping as Mapping],
       path: ['src', 'views'],
     },
     projectStyleSheet: {
-      generator: styleSheetGenerator,
+      generator: createComponentGenerator,
+      plugins: [createStyleSheetPlugin()],
       fileName: 'style',
       path: ['src'],
       importFile: true,
     },
     router: {
-      generator: vueRouterGenerator,
+      generator: createComponentGenerator,
+      plugins: [vueRoutingPlugin, pluginCSS, importStatementsPlugin],
+      postprocessors: [prettierJS],
       path: ['src'],
       fileName: 'router',
     },
     entry: {
-      generator: htmlFileGenerator,
+      generator: createComponentGenerator,
+      postprocessors: [prettierHTML],
       path: ['public'],
     },
     static: {
diff --git a/packages/teleport-project-generator/src/assembly-line/index.ts b/packages/teleport-project-generator/src/assembly-line/index.ts
new file mode 100644
index 00000000..76febf91
--- /dev/null
+++ b/packages/teleport-project-generator/src/assembly-line/index.ts
@@ -0,0 +1,66 @@
+import {
+  ProjectPlugin,
+  ProjectPluginStructure,
+  InMemoryFileRecord,
+  ProjectStrategy,
+} from '@teleporthq/teleport-types'
+
+interface ProjectAssemblyLineResult {
+  files: Map<string, InMemoryFileRecord>
+  strategy: ProjectStrategy
+  dependencies: Record<string, string>
+  devDependencies: Record<string, string>
+}
+
+class ProjectAssemblyLine {
+  private plugins: ProjectPlugin[]
+
+  constructor(plugins: ProjectPlugin[] = []) {
+    this.plugins = plugins
+  }
+
+  public async runBefore(structure: ProjectPluginStructure): Promise<ProjectAssemblyLineResult> {
+    const finalStructure = await this.plugins.reduce(
+      async (previousPluginOperation: Promise<ProjectPluginStructure>, plugin) => {
+        const modifiedStructure = await previousPluginOperation
+        return plugin.runBefore(modifiedStructure)
+      },
+      Promise.resolve(structure)
+    )
+
+    return {
+      files: finalStructure.files,
+      dependencies: finalStructure.dependencies,
+      devDependencies: finalStructure.devDependencies,
+      strategy: finalStructure.strategy,
+    }
+  }
+
+  public async runAfter(
+    structure: ProjectPluginStructure
+  ): Promise<Omit<ProjectAssemblyLineResult, 'strategy'>> {
+    const finalStructure = await this.plugins.reduce(
+      async (previousPluginOperation: Promise<ProjectPluginStructure>, plugin) => {
+        const modifiedStructure = await previousPluginOperation
+        return plugin.runAfter(modifiedStructure)
+      },
+      Promise.resolve(structure)
+    )
+
+    return {
+      files: finalStructure.files,
+      dependencies: finalStructure.dependencies,
+      devDependencies: finalStructure.devDependencies,
+    }
+  }
+
+  public getPlugins() {
+    return this.plugins
+  }
+
+  public addPlugin(plugin: ProjectPlugin) {
+    this.plugins.push(plugin)
+  }
+}
+
+export default ProjectAssemblyLine
diff --git a/packages/teleport-project-generator/src/file-handlers.ts b/packages/teleport-project-generator/src/file-handlers.ts
index 3833b09f..d22c4fca 100644
--- a/packages/teleport-project-generator/src/file-handlers.ts
+++ b/packages/teleport-project-generator/src/file-handlers.ts
@@ -14,6 +14,7 @@ import {
   Attribute,
   FileType,
   ChunkType,
+  ComponentGenerator,
 } from '@teleporthq/teleport-types'
 import PathResolver from 'path'
 import { DEFAULT_PACKAGE_JSON, DEFAULT_ROUTER_FILE_NAME } from './constants'
@@ -22,24 +23,27 @@ import { generateLocalDependenciesPrefix } from './utils'
 
 export const createPage = async (
   pageUIDL: ComponentUIDL,
-  strategy: ProjectStrategy,
+  generator: ComponentGenerator,
   options: GeneratorOptions
 ) => {
-  return strategy.pages.generator.generateComponent(pageUIDL, options)
+  return generator.generateComponent(pageUIDL, options)
 }
 
 export const createComponent = async (
   componentUIDL: ComponentUIDL,
-  strategy: ProjectStrategy,
+  generator: ComponentGenerator,
   options: GeneratorOptions
 ) => {
-  return strategy.components.generator.generateComponent(componentUIDL, options)
+  return generator.generateComponent(componentUIDL, options)
 }
 
-export const createComponentModule = async (uidl: ProjectUIDL, strategy: ProjectStrategy) => {
+export const createComponentModule = async (
+  uidl: ProjectUIDL,
+  strategy: ProjectStrategy,
+  generator: ComponentGenerator
+) => {
   const { root } = uidl
   const { path } = strategy.components
-  const { moduleGenerator } = strategy.components
   const componentLocalDependenciesPrefix = generateLocalDependenciesPrefix(
     path,
     strategy.components.path
@@ -54,24 +58,28 @@ export const createComponentModule = async (uidl: ProjectUIDL, strategy: Project
   root.outputOptions = root.outputOptions || {}
   root.outputOptions.fileName = 'components.module'
 
-  return moduleGenerator.generateComponent(root, options)
+  return generator.generateComponent(root, options)
 }
 
 export const createPageModule = async (
   pageUIDL: ComponentUIDL,
-  strategy: ProjectStrategy,
+  generator: ComponentGenerator,
   options: GeneratorOptions
 ) => {
   pageUIDL.outputOptions = pageUIDL.outputOptions || {}
   pageUIDL.outputOptions.moduleName = `${StringUtils.dashCaseToUpperCamelCase(
     pageUIDL.outputOptions.folderPath[0]
   )}Module`
-  return strategy.pages.moduleGenerator.generateComponent(pageUIDL, options)
+  return generator.generateComponent(pageUIDL, options)
 }
 
-export const createRouterFile = async (root: ComponentUIDL, strategy: ProjectStrategy) => {
-  const { projectStyleSheet } = strategy
-  const { generator: routerGenerator, path: routerFilePath, fileName } = strategy.router
+export const createRouterFile = async (
+  root: ComponentUIDL,
+  strategy: ProjectStrategy,
+  routerGenerator: ComponentGenerator
+) => {
+  const { projectStyleSheet, router } = strategy
+  const { path: routerFilePath, fileName } = router
   const routerLocalDependenciesPrefix = generateLocalDependenciesPrefix(
     routerFilePath,
     strategy.pages.path
@@ -112,14 +120,17 @@ export const createRouterFile = async (root: ComponentUIDL, strategy: ProjectStr
 export const createEntryFile = async (
   uidl: ProjectUIDL,
   strategy: ProjectStrategy,
-  { assetsPrefix }: GeneratorOptions
+  entryFileGenerator: ComponentGenerator,
+  entryFileOptions: GeneratorOptions
 ) => {
   // If no function is provided in the strategy, the createHTMLEntryFileChunks is used by default
   const chunkGenerationFunction =
     strategy.entry.chunkGenerationFunction || createHTMLEntryFileChunks
-  const { options } = strategy.entry
+  const { assetsPrefix } = entryFileOptions
+  const options = { ...strategy.entry?.options, ...entryFileOptions }
 
   const appRootOverride = (options && options.appRootOverride) || null
+
   const entryFileName = strategy.entry.fileName || 'index'
   const customHeadContent = (options && options.customHeadContent) || null
   const customTags = (options && options.customTags) || []
@@ -130,8 +141,8 @@ export const createEntryFile = async (
     customTags,
   })
 
-  const [entryFile] = strategy.entry.generator.linkCodeChunks(chunks, entryFileName)
-  return entryFile
+  const result = entryFileGenerator.linkCodeChunks(chunks, entryFileName)
+  return result
 }
 
 // Default function used to generate the html file based on the global settings in the ProjectUIDL
@@ -340,7 +351,8 @@ export const createManifestJSONFile = (uidl: ProjectUIDL, assetsPrefix?: string)
 export const handlePackageJSON = (
   template: GeneratedFolder,
   uidl: ProjectUIDL,
-  dependencies: Record<string, string>
+  dependencies: Record<string, string>,
+  devDependencies?: Record<string, string>
 ) => {
   const inputPackageJSONFile = template.files.find(
     (file) => file.name === 'package' && file.fileType === FileType.JSON
@@ -355,12 +367,18 @@ export const handlePackageJSON = (
       ...dependencies,
     }
 
+    packageJSONContent.devDependencies = {
+      ...packageJSONContent.devDependencies,
+      ...(Object.keys(devDependencies || {}).length > 0 && devDependencies),
+    }
+
     inputPackageJSONFile.content = JSON.stringify(packageJSONContent, null, 2)
   } else {
     const content: PackageJSON = {
       ...DEFAULT_PACKAGE_JSON,
       name: StringUtils.slugify(uidl.name),
       dependencies,
+      ...(Object.keys(devDependencies || {}).length > 0 && { devDependencies }),
     }
 
     template.files.push({
diff --git a/packages/teleport-project-generator/src/index.ts b/packages/teleport-project-generator/src/index.ts
index 492e6160..c992b489 100644
--- a/packages/teleport-project-generator/src/index.ts
+++ b/packages/teleport-project-generator/src/index.ts
@@ -11,7 +11,10 @@ import {
   ComponentGenerator,
   ProjectStrategyPageOptions,
   ConfigGeneratorResult,
-  GeneratedFile,
+  ProjectPlugin,
+  InMemoryFileRecord,
+  TeleportError,
+  GeneratorFactoryParams,
 } from '@teleporthq/teleport-types'
 import {
   injectFilesToPath,
@@ -20,6 +23,7 @@ import {
   prepareComponentOutputOptions,
   generateExternalCSSImports,
   fileFileAndReplaceContent,
+  bootstrapGenerator,
 } from './utils'
 import {
   createManifestJSONFile,
@@ -32,16 +36,24 @@ import {
   createPageModule,
 } from './file-handlers'
 import { DEFAULT_TEMPLATE } from './constants'
+import ProjectAssemblyLine from './assembly-line'
 
 type UpdateGeneratorCallback = (generator: ComponentGenerator) => void
 
 export class ProjectGenerator {
+  public componentGenerator: ComponentGenerator
+  public pageGenerator: ComponentGenerator
+  public entryGenerator: ComponentGenerator
+  public routerGenerator: ComponentGenerator
+  public styleSheetGenerator: ComponentGenerator
   private strategy: ProjectStrategy
   private validator: Validator
+  private assemblyLine: ProjectAssemblyLine
 
   constructor(strategy: ProjectStrategy) {
     this.validator = new Validator()
     this.strategy = strategy
+    this.assemblyLine = new ProjectAssemblyLine()
   }
 
   public getStrategy() {
@@ -59,13 +71,13 @@ export class ProjectGenerator {
 
   public updateComponentsGenerator(callback: UpdateGeneratorCallback) {
     if (typeof callback === 'function') {
-      callback(this.strategy.components.generator)
+      callback(this.strategy.components.generator())
     }
   }
 
   public updatePagesGenerator(callback: UpdateGeneratorCallback) {
     if (typeof callback === 'function') {
-      callback(this.strategy.pages.generator)
+      callback(this.strategy.pages.generator())
     }
   }
 
@@ -79,7 +91,7 @@ export class ProjectGenerator {
     options?: ProjectStrategyComponentOptions
   }) {
     if (generator) {
-      this.strategy.components.generator = generator
+      this.strategy.components.generator = () => generator
     }
 
     if (path) {
@@ -101,7 +113,7 @@ export class ProjectGenerator {
     options?: ProjectStrategyPageOptions
   }) {
     if (generator) {
-      this.strategy.pages.generator = generator
+      this.strategy.pages.generator = () => generator
     }
 
     if (path) {
@@ -119,11 +131,13 @@ export class ProjectGenerator {
     mapping: Mapping = {}
   ): Promise<GeneratedFolder> {
     let cleanedUIDL = input
-    const inMemoryFilesMap = new Map<
-      string,
-      { rootFolder: GeneratedFolder; path: string[]; files: GeneratedFile[] }
-    >()
-    // Validating and parsing the UIDL
+    let collectedDependencies: Record<string, string> = {}
+    let collectedDevDependencies: Record<string, string> = {}
+    let inMemoryFilesMap = new Map<string, InMemoryFileRecord>()
+
+    // Initialize output folder and other reusable structures
+    const rootFolder = UIDLUtils.cloneObject(template || DEFAULT_TEMPLATE)
+
     const schemaValidationResult = this.validator.validateProjectSchema(input)
     const { valid, projectUIDL } = schemaValidationResult
     if (valid && projectUIDL) {
@@ -146,6 +160,49 @@ export class ProjectGenerator {
       throw new Error(contentValidationResult.errorMsg)
     }
 
+    try {
+      const runBeforeResult = await this.assemblyLine.runBefore({
+        uidl,
+        template,
+        files: inMemoryFilesMap,
+        strategy: this.strategy,
+        dependencies: collectedDependencies,
+        devDependencies: collectedDevDependencies,
+        rootFolder,
+      })
+
+      collectedDependencies = { ...collectedDependencies, ...runBeforeResult.dependencies }
+      collectedDevDependencies = { ...collectedDevDependencies, ...runBeforeResult.devDependencies }
+
+      this.strategy = runBeforeResult.strategy
+      inMemoryFilesMap = runBeforeResult.files
+
+      if (this.strategy.components?.generator) {
+        this.componentGenerator = bootstrapGenerator(this.strategy.components, this.strategy.style)
+      }
+
+      if (this.strategy.pages?.generator) {
+        this.pageGenerator = bootstrapGenerator(this.strategy.pages, this.strategy.style)
+      }
+
+      if (this.strategy.entry?.generator) {
+        this.entryGenerator = bootstrapGenerator(this.strategy.entry, this.strategy.style)
+      }
+
+      if (this.strategy.projectStyleSheet?.generator) {
+        this.styleSheetGenerator = bootstrapGenerator(
+          this.strategy.projectStyleSheet,
+          this.strategy.style
+        )
+      }
+
+      if (this.strategy.router?.generator) {
+        this.routerGenerator = bootstrapGenerator(this.strategy.router, this.strategy.style)
+      }
+    } catch (e) {
+      throw new TeleportError(`Error in Generating Project after runBefore - ${e}`)
+    }
+
     const { components = {} } = uidl
     const { styleSetDefinitions = {}, designLanguage: { tokens = {} } = {} } = uidl.root
 
@@ -159,10 +216,6 @@ export class ProjectGenerator {
       resolveLocalDependencies(pageUIDLs, components, this.strategy)
     }
 
-    // Initialize output folder and other reusable structures
-    const rootFolder = UIDLUtils.cloneObject(template || DEFAULT_TEMPLATE)
-    let collectedDependencies: Record<string, string> = {}
-
     // If static prefix is not specified, compute it from the path, but if the string is empty it should work
     const assetsPrefix =
       typeof this.strategy.static.prefix === 'string'
@@ -181,14 +234,12 @@ export class ProjectGenerator {
       this.strategy.projectStyleSheet?.generator &&
       (Object.keys(styleSetDefinitions).length > 0 || Object.keys(tokens).length > 0)
     ) {
-      const { generator, path } = this.strategy.projectStyleSheet
-      const { files, dependencies } = await generator.generateComponent(uidl.root, {
+      const { files, dependencies } = await this.styleSheetGenerator.generateComponent(uidl.root, {
         isRootComponent: true,
       })
 
       inMemoryFilesMap.set('projectStyleSheet', {
-        rootFolder,
-        path,
+        path: this.strategy.projectStyleSheet.path,
         files,
       })
 
@@ -197,6 +248,12 @@ export class ProjectGenerator {
 
     // Handling pages
     for (const pageUIDL of pageUIDLs) {
+      if (!this.strategy?.pages?.generator) {
+        throw new TeleportError(
+          `Pages Generator is missing from the strategy - ${JSON.stringify(this.strategy.pages)}`
+        )
+      }
+
       let pageOptions = options
       const pagesPath = this.strategy.pages.path
       if (this.strategy.projectStyleSheet) {
@@ -209,7 +266,6 @@ export class ProjectGenerator {
               : pagesPath.join('/'),
             this.strategy.projectStyleSheet.path.join('/')
           ) || '.'
-
         /* If relative path resolver returns empty string, then both the files are in the same
         folder. */
 
@@ -225,24 +281,26 @@ export class ProjectGenerator {
         }
       }
 
-      const { files, dependencies } = await createPage(pageUIDL, this.strategy, pageOptions)
+      const { files, dependencies } = await createPage(pageUIDL, this.pageGenerator, pageOptions)
       // Pages might be generated inside subfolders in the main pages folder
       const relativePath = UIDLUtils.getComponentFolderPath(pageUIDL)
       const path = this.strategy.pages.path.concat(relativePath)
 
       inMemoryFilesMap.set(pageUIDL.name, {
-        rootFolder,
         path,
         files,
       })
 
       collectedDependencies = { ...collectedDependencies, ...dependencies }
 
-      if (this.strategy.pages.moduleGenerator) {
-        const pageModule = await createPageModule(pageUIDL, this.strategy, options)
+      if (this.strategy.pages?.module) {
+        const pageModuleGenerator = bootstrapGenerator(
+          this.strategy.pages.module,
+          this.strategy.style
+        )
+        const pageModule = await createPageModule(pageUIDL, pageModuleGenerator, options)
 
         inMemoryFilesMap.set(`${pageUIDL.name}Module`, {
-          rootFolder,
           path,
           files: pageModule.files,
         })
@@ -252,11 +310,18 @@ export class ProjectGenerator {
     }
 
     // Handling module generation for components
-    if (this.strategy.components.moduleGenerator) {
-      const componentsModule = await createComponentModule(uidl, this.strategy)
+    if (this.strategy?.components?.module) {
+      const componentModuleGenerator = bootstrapGenerator(
+        this.strategy.components.module,
+        this.strategy.style
+      )
+      const componentsModule = await createComponentModule(
+        uidl,
+        this.strategy,
+        componentModuleGenerator
+      )
 
       inMemoryFilesMap.set(componentsModule.files[0].name, {
-        rootFolder,
         path: this.strategy.components.path,
         files: componentsModule.files,
       })
@@ -266,6 +331,14 @@ export class ProjectGenerator {
 
     // Handling components
     for (const componentName of Object.keys(components)) {
+      if (!this.strategy?.components?.generator) {
+        throw new TeleportError(
+          `Component Generator is missing from the strategy - ${JSON.stringify(
+            this.strategy.components
+          )}`
+        )
+      }
+
       let componentOptions = options
       if (this.strategy.projectStyleSheet) {
         const relativePathForProjectStyleSheet =
@@ -296,7 +369,7 @@ export class ProjectGenerator {
       const componentUIDL = components[componentName]
       const { files, dependencies } = await createComponent(
         componentUIDL,
-        this.strategy,
+        this.componentGenerator,
         componentOptions
       )
 
@@ -305,7 +378,6 @@ export class ProjectGenerator {
       const path = this.strategy.components.path.concat(relativePath)
 
       inMemoryFilesMap.set(componentName, {
-        rootFolder,
         path,
         files,
       })
@@ -335,7 +407,6 @@ export class ProjectGenerator {
         collectedDependencies = result.dependencies
 
         inMemoryFilesMap.set(fileName, {
-          rootFolder,
           path: this.strategy.framework.replace.path,
           files: [result.file],
         })
@@ -344,7 +415,13 @@ export class ProjectGenerator {
 
     // If we want to generate a completly new file
     if (framework?.config) {
-      const { fileName, fileType, configContentGenerator, generator } = framework.config
+      const {
+        fileName,
+        fileType,
+        configContentGenerator,
+        generator,
+        plugins: frameworkConfigPlugins,
+      } = framework.config
 
       if (configContentGenerator && generator) {
         const result: ConfigGeneratorResult = configContentGenerator({
@@ -359,24 +436,27 @@ export class ProjectGenerator {
             sheetName: this.strategy.projectStyleSheet
               ? this.strategy.projectStyleSheet.fileName
               : '',
-            isGlobalStylesDependent: Boolean(
-              (framework.config?.isGlobalStylesDependent &&
-                Object.keys(styleSetDefinitions).length > 0) ||
-                Object.keys(uidl.root?.designLanguage?.tokens || {}).length > 0
-            ),
+            isGlobalStylesDependent:
+              framework.config?.isGlobalStylesDependent ??
+              Boolean(
+                Object.keys(styleSetDefinitions).length > 0 ||
+                  Object.keys(uidl.root?.designLanguage?.tokens || {}).length > 0
+              ),
           },
           dependencies: collectedDependencies,
         })
+
         collectedDependencies = result.dependencies
 
         if (Object.keys(result?.chunks).length > 0) {
-          const files = framework.config.generator.linkCodeChunks(
+          const configGenerator: (params: GeneratorFactoryParams) => ComponentGenerator =
+            framework.config.generator
+          const files = configGenerator({ plugins: frameworkConfigPlugins }).linkCodeChunks(
             result.chunks,
             framework.config.fileName
           )
 
           inMemoryFilesMap.set(fileName, {
-            rootFolder,
             path: this.strategy.framework.config.path,
             files,
           })
@@ -389,7 +469,6 @@ export class ProjectGenerator {
       const manifestFile = createManifestJSONFile(uidl, assetsPrefix)
 
       inMemoryFilesMap.set(manifestFile.name, {
-        rootFolder,
         path: this.strategy.static.path,
         files: [manifestFile],
       })
@@ -400,10 +479,13 @@ export class ProjectGenerator {
 
     // Create the routing component in case the project generator has a strategy for that
     if (this.strategy.router) {
-      const { routerFile, dependencies } = await createRouterFile(uidl.root, this.strategy)
+      const { routerFile, dependencies } = await createRouterFile(
+        uidl.root,
+        this.strategy,
+        this.routerGenerator
+      )
 
       inMemoryFilesMap.set('router', {
-        rootFolder,
         path: this.strategy.router.path,
         files: [routerFile],
       })
@@ -413,11 +495,12 @@ export class ProjectGenerator {
 
     // Create the entry file of the project (ex: index.html, _document.js)
     if (this.strategy.entry) {
-      const entryFile = await createEntryFile(uidl, this.strategy, { assetsPrefix })
+      const entryFile = await createEntryFile(uidl, this.strategy, this.entryGenerator, {
+        assetsPrefix,
+      })
       inMemoryFilesMap.set('entry', {
-        rootFolder,
         path: this.strategy.entry.path,
-        files: [entryFile],
+        files: entryFile,
       })
     }
 
@@ -434,34 +517,53 @@ export class ProjectGenerator {
       const files = fileFileAndReplaceContent(folder.files, fileName, resultFile.content)
 
       inMemoryFilesMap.set(fileName, {
-        rootFolder,
         path: folder.path,
         files,
       })
     }
 
+    try {
+      const runAfterResult = await this.assemblyLine.runAfter({
+        uidl,
+        template,
+        files: inMemoryFilesMap,
+        strategy: this.strategy,
+        dependencies: collectedDependencies,
+        devDependencies: collectedDevDependencies,
+        rootFolder,
+      })
+
+      collectedDependencies = { ...collectedDependencies, ...runAfterResult.dependencies }
+      collectedDevDependencies = { ...collectedDevDependencies, ...runAfterResult.devDependencies }
+      inMemoryFilesMap = runAfterResult.files
+    } catch (e) {
+      throw new TeleportError(`Error in generating project after runAfter - ${e}`)
+    }
+
     inMemoryFilesMap.forEach((stage) => {
-      injectFilesToPath(stage.rootFolder, stage.path, stage.files)
+      injectFilesToPath(rootFolder, stage.path, stage.files)
     })
 
     // Inject all the collected dependencies in the package.json file
-    handlePackageJSON(rootFolder, uidl, collectedDependencies)
+    handlePackageJSON(rootFolder, uidl, collectedDependencies, collectedDevDependencies)
 
     return rootFolder
   }
 
   public addMapping(mapping: Mapping) {
-    this.strategy.components.generator.addMapping(mapping)
-
-    if (this.strategy.components.generator !== this.strategy.pages.generator) {
-      this.strategy.pages.generator.addMapping(mapping)
-    }
+    this.strategy.components.mappings = [...this.strategy.components?.mappings, mapping]
+    this.strategy.pages.mappings = [...this.strategy.pages?.mappings, mapping]
 
     if (this.strategy.router) {
-      // TODO: Add mapping later if we decide to reference a generator object instead of a generator function for routing
+      /* TODO: Add mapping later if we decide to reference a generator object
+      instead of a generator function for routing */
     }
   }
 
+  public addPlugin(plugin: ProjectPlugin) {
+    this.assemblyLine.addPlugin(plugin)
+  }
+
   public getAssetsPath() {
     return this.strategy.static.path
   }
diff --git a/packages/teleport-project-generator/src/types.ts b/packages/teleport-project-generator/src/types.ts
index 810eb023..5873d511 100644
--- a/packages/teleport-project-generator/src/types.ts
+++ b/packages/teleport-project-generator/src/types.ts
@@ -7,5 +7,6 @@ export interface PackageJSON {
   license?: string
   scripts?: Record<string, string>
   dependencies?: Record<string, string>
+  devDependencies?: Record<string, string>
   [key: string]: unknown
 }
diff --git a/packages/teleport-project-generator/src/utils.ts b/packages/teleport-project-generator/src/utils.ts
index 5ba809d5..c1a4ee31 100644
--- a/packages/teleport-project-generator/src/utils.ts
+++ b/packages/teleport-project-generator/src/utils.ts
@@ -11,6 +11,12 @@ import {
   UIDLPageOptions,
   UIDLComponentOutputOptions,
   UIDLExternalDependency,
+  ComponentGenerator,
+  ComponentPlugin,
+  PostProcessor,
+  Mapping,
+  StyleVariation,
+  GeneratorFactoryParams,
 } from '@teleporthq/teleport-types'
 import { elementNode } from '@teleporthq/teleport-uidl-builders'
 import importStatementsPlugin from '@teleporthq/teleport-plugin-import-statements'
@@ -552,3 +558,20 @@ const findSubFolderByName = (rootFolder: GeneratedFolder, folderName: string): G
 const findFileInFolder = (file: GeneratedFile, folder: GeneratedFolder) => {
   return folder.files.find((f) => f.name === file.name && f.fileType === file.fileType)
 }
+
+export const bootstrapGenerator = (
+  {
+    generator,
+    plugins = [],
+    postprocessors = [],
+    mappings = [],
+  }: {
+    generator: (params: GeneratorFactoryParams) => ComponentGenerator
+    plugins?: ComponentPlugin[]
+    postprocessors?: PostProcessor[]
+    mappings?: Mapping[]
+  },
+  style?: StyleVariation
+): ComponentGenerator => {
+  return generator({ plugins, postprocessors, mappings, ...(style && { variation: style }) })
+}
diff --git a/packages/teleport-project-plugin-gatsby-styled-components/package.json b/packages/teleport-project-plugin-gatsby-styled-components/package.json
new file mode 100644
index 00000000..baf58dad
--- /dev/null
+++ b/packages/teleport-project-plugin-gatsby-styled-components/package.json
@@ -0,0 +1,36 @@
+{
+    "name": "@teleporthq/teleport-project-plugin-gatsby-styled-components",
+    "version": "0.15.0",
+    "description": "A plugin for generating a gatsby project using styled-components",
+    "author": "teleportHQ",
+    "license": "MIT",
+    "homepage": "https://teleporthq.io/",
+    "main": "dist/cjs/index.js",
+    "types": "dist/cjs/index.d.ts",
+    "module": "dist/esm/index.js",
+    "sideEffects": false,
+    "repository": {
+      "type": "git",
+      "url": "git+ssh://git@github.com/teleporthq/teleport-code-generators.git"
+    },
+    "bugs": {
+      "url": "https://github.com/teleporthq/teleport-code-generators/issues"
+    },
+    "publishConfig": {
+      "access": "public"
+    },
+    "scripts": {
+      "clean": "rimraf dist",
+      "build": "npm run build:cjs & npm run build:esm",
+      "build:cjs": "tsc -p tsconfig-cjs.json",
+      "build:esm": "tsc -p tsconfig-esm.json"
+    },
+    "dependencies": {
+      "magic-string": "^0.25.4",
+      "@teleporthq/teleport-types": "^0.15.0",
+      "@teleporthq/teleport-plugin-import-statements": "^0.15.0",
+      "@teleporthq/teleport-plugin-react-styled-components": "^0.15.0",
+      "@teleporthq/teleport-postprocessor-prettier-js": "^0.15.0"
+    }
+  }
+  
\ No newline at end of file
diff --git a/packages/teleport-project-generator-gatsby/src/constants.ts b/packages/teleport-project-plugin-gatsby-styled-components/src/constants.ts
similarity index 67%
rename from packages/teleport-project-generator-gatsby/src/constants.ts
rename to packages/teleport-project-plugin-gatsby-styled-components/src/constants.ts
index deeb692b..da163e0b 100644
--- a/packages/teleport-project-generator-gatsby/src/constants.ts
+++ b/packages/teleport-project-plugin-gatsby-styled-components/src/constants.ts
@@ -1,4 +1,4 @@
-export const STYLED_DEPENDENCIES = {
+export const STYLED_DEPENDENCIES: Record<string, string> = {
   'gatsby-plugin-styled-components': '^3.0.0',
   'babel-plugin-styled-components': '^1.10.6',
   'styled-components': '^4.4.0',
diff --git a/packages/teleport-project-plugin-gatsby-styled-components/src/index.ts b/packages/teleport-project-plugin-gatsby-styled-components/src/index.ts
new file mode 100644
index 00000000..ec61d8a4
--- /dev/null
+++ b/packages/teleport-project-plugin-gatsby-styled-components/src/index.ts
@@ -0,0 +1,59 @@
+import {
+  FileType,
+  ProjectPlugin,
+  ProjectPluginStructure,
+  GatsbyStyleVariation,
+} from '@teleporthq/teleport-types'
+import { createStyleSheetPlugin } from '@teleporthq/teleport-plugin-react-styled-components'
+import prettierJS from '@teleporthq/teleport-postprocessor-prettier-js'
+import importStatementsPlugin from '@teleporthq/teleport-plugin-import-statements'
+import MagicString from 'magic-string'
+import { STYLED_DEPENDENCIES } from './constants'
+
+class PluginGatsbyStyledComponents implements ProjectPlugin {
+  async runBefore(structure: ProjectPluginStructure) {
+    const { strategy } = structure
+
+    strategy.style = GatsbyStyleVariation.StyledComponents
+    delete strategy.framework.config
+    if (strategy?.projectStyleSheet?.generator) {
+      strategy.projectStyleSheet.plugins = [createStyleSheetPlugin(), importStatementsPlugin]
+    }
+    return structure
+  }
+
+  async runAfter(structure: ProjectPluginStructure) {
+    const { template, files, dependencies } = structure
+    const fileName = 'gatsby-config'
+    const configFile = template.files.find(
+      (file) => file.name === 'gatsby-config' && file.fileType === FileType.JS
+    )
+
+    if (!configFile || !configFile.content) {
+      throw new Error(`${fileName} not found, while adding gatsby-plugin-styled-components`)
+    }
+
+    const parsedFile = configFile.content.replace('/n', '//n')
+    const magic = new MagicString(parsedFile)
+    magic.appendRight(parsedFile.length - 10, `,'gatsby-plugin-styled-components'`)
+    const content = magic.toString()
+    const formattedCode = prettierJS({ [FileType.JS]: content })
+
+    files.set('gatsby-config', {
+      path: [],
+      files: [
+        { name: `gatsby-config`, fileType: FileType.JS, content: formattedCode[FileType.JS] },
+      ],
+    })
+
+    Object.keys(STYLED_DEPENDENCIES).forEach((dep: string) => {
+      dependencies[dep] = STYLED_DEPENDENCIES[dep]
+    })
+
+    return structure
+  }
+}
+
+const pluginGatsbyStyledComponents = new PluginGatsbyStyledComponents()
+export { PluginGatsbyStyledComponents }
+export default pluginGatsbyStyledComponents
diff --git a/packages/teleport-project-plugin-gatsby-styled-components/tsconfig-cjs.json b/packages/teleport-project-plugin-gatsby-styled-components/tsconfig-cjs.json
new file mode 100755
index 00000000..c66b615a
--- /dev/null
+++ b/packages/teleport-project-plugin-gatsby-styled-components/tsconfig-cjs.json
@@ -0,0 +1,11 @@
+{
+  "extends": "../../tsconfig.json",
+  "compilerOptions": {
+    "outDir": "dist/cjs",
+    "module": "commonjs",
+    "target": "es5"
+  },
+  "include": [
+    "./src"
+  ]
+}
\ No newline at end of file
diff --git a/packages/teleport-project-plugin-gatsby-styled-components/tsconfig-esm.json b/packages/teleport-project-plugin-gatsby-styled-components/tsconfig-esm.json
new file mode 100755
index 00000000..5d65f088
--- /dev/null
+++ b/packages/teleport-project-plugin-gatsby-styled-components/tsconfig-esm.json
@@ -0,0 +1,12 @@
+{
+  "extends": "../../tsconfig.json",
+  "compilerOptions": {
+    "outDir": "dist/esm",
+    "module": "esnext",
+    "target": "es2019",
+    "moduleResolution": "node"
+  },
+  "include": [
+    "./src"
+  ]
+}
\ No newline at end of file
diff --git a/packages/teleport-project-plugin-next-css-modules/package.json b/packages/teleport-project-plugin-next-css-modules/package.json
new file mode 100644
index 00000000..005acef8
--- /dev/null
+++ b/packages/teleport-project-plugin-next-css-modules/package.json
@@ -0,0 +1,34 @@
+{
+    "name": "@teleporthq/teleport-project-plugin-next-css-modules",
+    "version": "0.15.0",
+    "description": "A plugin for generating a next project using css modules",
+    "author": "teleportHQ",
+    "license": "MIT",
+    "homepage": "https://teleporthq.io/",
+    "main": "dist/cjs/index.js",
+    "types": "dist/cjs/index.d.ts",
+    "module": "dist/esm/index.js",
+    "sideEffects": false,
+    "repository": {
+      "type": "git",
+      "url": "git+ssh://git@github.com/teleporthq/teleport-code-generators.git"
+    },
+    "bugs": {
+      "url": "https://github.com/teleporthq/teleport-code-generators/issues"
+    },
+    "publishConfig": {
+      "access": "public"
+    },
+    "scripts": {
+      "clean": "rimraf dist",
+      "build": "npm run build:cjs & npm run build:esm",
+      "build:cjs": "tsc -p tsconfig-cjs.json",
+      "build:esm": "tsc -p tsconfig-esm.json"
+    },
+    "dependencies": {
+      "@teleporthq/teleport-types": "^0.15.0",
+      "@teleporthq/teleport-postprocessor-prettier-js": "^0.15.0",
+      "@teleporthq/teleport-plugin-css-modules": "^0.15.0"
+    }
+  }
+  
\ No newline at end of file
diff --git a/packages/teleport-project-plugin-next-css-modules/src/index.ts b/packages/teleport-project-plugin-next-css-modules/src/index.ts
new file mode 100644
index 00000000..3ca375eb
--- /dev/null
+++ b/packages/teleport-project-plugin-next-css-modules/src/index.ts
@@ -0,0 +1,67 @@
+import {
+  FileType,
+  ProjectPlugin,
+  ProjectPluginStructure,
+  ReactStyleVariation,
+} from '@teleporthq/teleport-types'
+import prettierJS from '@teleporthq/teleport-postprocessor-prettier-js'
+import { createStyleSheetPlugin } from '@teleporthq/teleport-plugin-css-modules'
+
+class PluginNextCSSModules implements ProjectPlugin {
+  async runBefore(structure: ProjectPluginStructure) {
+    const { strategy } = structure
+
+    strategy.style = ReactStyleVariation.CSSModules
+    if (strategy?.projectStyleSheet?.generator) {
+      strategy.projectStyleSheet.plugins = [createStyleSheetPlugin({ moduleExtension: true })]
+      strategy.framework.config.isGlobalStylesDependent = false
+    }
+    return structure
+  }
+
+  async runAfter(structure: ProjectPluginStructure) {
+    const { files, devDependencies } = structure
+    const appFileContent = files.get('_app').files[0].content
+    const content = `import "./style.module.css" \n
+    ${appFileContent}
+    `
+
+    const formattedCode = prettierJS({ [FileType.JS]: content })
+
+    files.set('_app', {
+      path: files.get('_app').path,
+      files: [
+        {
+          name: '_app',
+          fileType: FileType.JS,
+          content: formattedCode[FileType.JS],
+        },
+      ],
+    })
+
+    const nextContent = prettierJS({
+      [FileType.JS]: `const withCSS = require('@zeit/next-css')
+    module.exports = withCSS({
+      cssModules: true
+    })`,
+    })
+
+    files.set('next.config', {
+      path: [],
+      files: [
+        {
+          name: 'next.config',
+          fileType: FileType.JS,
+          content: nextContent[FileType.JS],
+        },
+      ],
+    })
+
+    devDependencies['@zeit/next-css'] = '^1.0.1'
+    return structure
+  }
+}
+
+const pluginNextCSSModules = new PluginNextCSSModules()
+export { PluginNextCSSModules }
+export default pluginNextCSSModules
diff --git a/packages/teleport-project-plugin-next-css-modules/tsconfig-cjs.json b/packages/teleport-project-plugin-next-css-modules/tsconfig-cjs.json
new file mode 100755
index 00000000..c66b615a
--- /dev/null
+++ b/packages/teleport-project-plugin-next-css-modules/tsconfig-cjs.json
@@ -0,0 +1,11 @@
+{
+  "extends": "../../tsconfig.json",
+  "compilerOptions": {
+    "outDir": "dist/cjs",
+    "module": "commonjs",
+    "target": "es5"
+  },
+  "include": [
+    "./src"
+  ]
+}
\ No newline at end of file
diff --git a/packages/teleport-project-plugin-next-css-modules/tsconfig-esm.json b/packages/teleport-project-plugin-next-css-modules/tsconfig-esm.json
new file mode 100755
index 00000000..5d65f088
--- /dev/null
+++ b/packages/teleport-project-plugin-next-css-modules/tsconfig-esm.json
@@ -0,0 +1,12 @@
+{
+  "extends": "../../tsconfig.json",
+  "compilerOptions": {
+    "outDir": "dist/esm",
+    "module": "esnext",
+    "target": "es2019",
+    "moduleResolution": "node"
+  },
+  "include": [
+    "./src"
+  ]
+}
\ No newline at end of file
diff --git a/packages/teleport-project-plugin-next-react-jss/package.json b/packages/teleport-project-plugin-next-react-jss/package.json
new file mode 100644
index 00000000..ce60ab2b
--- /dev/null
+++ b/packages/teleport-project-plugin-next-react-jss/package.json
@@ -0,0 +1,36 @@
+{
+    "name": "@teleporthq/teleport-project-plugin-next-react-jss",
+    "version": "0.15.0",
+    "description": "A plugin for generating a next project using react-jss",
+    "author": "teleportHQ",
+    "license": "MIT",
+    "homepage": "https://teleporthq.io/",
+    "main": "dist/cjs/index.js",
+    "types": "dist/cjs/index.d.ts",
+    "module": "dist/esm/index.js",
+    "sideEffects": false,
+    "repository": {
+      "type": "git",
+      "url": "git+ssh://git@github.com/teleporthq/teleport-code-generators.git"
+    },
+    "bugs": {
+      "url": "https://github.com/teleporthq/teleport-code-generators/issues"
+    },
+    "publishConfig": {
+      "access": "public"
+    },
+    "scripts": {
+      "clean": "rimraf dist",
+      "build": "npm run build:cjs & npm run build:esm",
+      "build:cjs": "tsc -p tsconfig-cjs.json",
+      "build:esm": "tsc -p tsconfig-esm.json"
+    },
+    "dependencies": {
+      "magic-string": "^0.25.4",
+      "@teleporthq/teleport-types": "^0.15.0",
+      "@teleporthq/teleport-plugin-import-statements": "^0.15.0",
+      "@teleporthq/teleport-postprocessor-prettier-js": "^0.15.0",
+      "@teleporthq/teleport-plugin-react-jss": "^0.15.0"
+    }
+  }
+  
\ No newline at end of file
diff --git a/packages/teleport-project-plugin-next-react-jss/src/index.ts b/packages/teleport-project-plugin-next-react-jss/src/index.ts
new file mode 100644
index 00000000..0954dcd3
--- /dev/null
+++ b/packages/teleport-project-plugin-next-react-jss/src/index.ts
@@ -0,0 +1,88 @@
+import {
+  ProjectPlugin,
+  ProjectPluginStructure,
+  ReactStyleVariation,
+  FileType,
+} from '@teleporthq/teleport-types'
+import importStatementsPlugin from '@teleporthq/teleport-plugin-import-statements'
+import { createStyleSheetPlugin } from '@teleporthq/teleport-plugin-react-jss'
+import prettierJS from '@teleporthq/teleport-postprocessor-prettier-js'
+import MagicString from 'magic-string'
+
+class PluginNextReactJSS implements ProjectPlugin {
+  async runBefore(structure: ProjectPluginStructure) {
+    const { strategy } = structure
+
+    strategy.style = ReactStyleVariation.ReactJSS
+    if (strategy?.projectStyleSheet?.generator) {
+      strategy.projectStyleSheet.plugins = [createStyleSheetPlugin(), importStatementsPlugin]
+      strategy.projectStyleSheet.postprocessors = [prettierJS]
+      strategy.framework.config.isGlobalStylesDependent = false
+    }
+
+    return structure
+  }
+
+  async runAfter(structure: ProjectPluginStructure) {
+    const { files } = structure
+
+    if (!files.get('entry')) {
+      throw new Error('Entry file is missing from the generated files')
+    }
+
+    const fileContent = files.get('entry').files[0].content
+    const magicString = new MagicString(fileContent.replace('/n', '//n'))
+
+    magicString.appendRight(
+      70,
+      `\nimport { SheetsRegistry, JssProvider, createGenerateId } from "react-jss"; \n`
+    )
+    magicString.appendRight(
+      114,
+      `\nstatic async getInitialProps(ctx) {
+        const registry = new SheetsRegistry();
+        const generateId = createGenerateId();
+        const originalRenderPage = ctx.renderPage;
+        ctx.renderPage = () =>
+          originalRenderPage({
+            enhanceApp: (App) => (props) => (
+              <JssProvider registry={registry} generateId={generateId}>
+                <App {...props} />
+              </JssProvider>
+            ),
+          });
+        const initialProps = await Document.getInitialProps(ctx);
+        return {
+          ...initialProps,
+          styles: (
+            <>
+              {initialProps.styles}
+              <style id="server-side-styles">{registry.toString()}</style>
+            </>
+          ),
+        };
+      }\n \n`
+    )
+
+    const formattedCode = prettierJS({
+      [FileType.JS]: magicString.toString(),
+    })
+
+    files.set('entry', {
+      path: ['pages'],
+      files: [
+        {
+          name: '_document',
+          fileType: FileType.JS,
+          content: formattedCode[FileType.JS],
+        },
+      ],
+    })
+
+    return structure
+  }
+}
+
+const pluginNextReactJSS = new PluginNextReactJSS()
+export { PluginNextReactJSS }
+export default pluginNextReactJSS
diff --git a/packages/teleport-project-plugin-next-react-jss/tsconfig-cjs.json b/packages/teleport-project-plugin-next-react-jss/tsconfig-cjs.json
new file mode 100755
index 00000000..c66b615a
--- /dev/null
+++ b/packages/teleport-project-plugin-next-react-jss/tsconfig-cjs.json
@@ -0,0 +1,11 @@
+{
+  "extends": "../../tsconfig.json",
+  "compilerOptions": {
+    "outDir": "dist/cjs",
+    "module": "commonjs",
+    "target": "es5"
+  },
+  "include": [
+    "./src"
+  ]
+}
\ No newline at end of file
diff --git a/packages/teleport-project-plugin-next-react-jss/tsconfig-esm.json b/packages/teleport-project-plugin-next-react-jss/tsconfig-esm.json
new file mode 100755
index 00000000..5d65f088
--- /dev/null
+++ b/packages/teleport-project-plugin-next-react-jss/tsconfig-esm.json
@@ -0,0 +1,12 @@
+{
+  "extends": "../../tsconfig.json",
+  "compilerOptions": {
+    "outDir": "dist/esm",
+    "module": "esnext",
+    "target": "es2019",
+    "moduleResolution": "node"
+  },
+  "include": [
+    "./src"
+  ]
+}
\ No newline at end of file
diff --git a/packages/teleport-project-plugin-next-styled-components/package.json b/packages/teleport-project-plugin-next-styled-components/package.json
new file mode 100644
index 00000000..cad33208
--- /dev/null
+++ b/packages/teleport-project-plugin-next-styled-components/package.json
@@ -0,0 +1,36 @@
+{
+    "name": "@teleporthq/teleport-project-plugin-next-styled-components",
+    "version": "0.15.0",
+    "description": "A plugin for generating a next project using styled-components",
+    "author": "teleportHQ",
+    "license": "MIT",
+    "homepage": "https://teleporthq.io/",
+    "main": "dist/cjs/index.js",
+    "types": "dist/cjs/index.d.ts",
+    "module": "dist/esm/index.js",
+    "sideEffects": false,
+    "repository": {
+      "type": "git",
+      "url": "git+ssh://git@github.com/teleporthq/teleport-code-generators.git"
+    },
+    "bugs": {
+      "url": "https://github.com/teleporthq/teleport-code-generators/issues"
+    },
+    "publishConfig": {
+      "access": "public"
+    },
+    "scripts": {
+      "clean": "rimraf dist",
+      "build": "npm run build:cjs & npm run build:esm",
+      "build:cjs": "tsc -p tsconfig-cjs.json",
+      "build:esm": "tsc -p tsconfig-esm.json"
+    },
+    "dependencies": {
+      "magic-string": "^0.25.4",
+      "@teleporthq/teleport-types": "^0.15.0",
+      "@teleporthq/teleport-plugin-import-statements": "^0.15.0",
+      "@teleporthq/teleport-postprocessor-prettier-js": "^0.15.0",
+      "@teleporthq/teleport-plugin-react-styled-components": "^0.15.0"
+    }
+  }
+  
\ No newline at end of file
diff --git a/packages/teleport-project-plugin-next-styled-components/src/index.ts b/packages/teleport-project-plugin-next-styled-components/src/index.ts
new file mode 100644
index 00000000..837aecb8
--- /dev/null
+++ b/packages/teleport-project-plugin-next-styled-components/src/index.ts
@@ -0,0 +1,97 @@
+import {
+  ProjectPlugin,
+  ProjectPluginStructure,
+  ReactStyleVariation,
+  FileType,
+} from '@teleporthq/teleport-types'
+import MagicString from 'magic-string'
+import { createStyleSheetPlugin } from '@teleporthq/teleport-plugin-react-styled-components'
+import importStatementsPlugin from '@teleporthq/teleport-plugin-import-statements'
+import prettierJS from '@teleporthq/teleport-postprocessor-prettier-js'
+
+class PluginNextStyledComponents implements ProjectPlugin {
+  async runBefore(structure: ProjectPluginStructure) {
+    const { strategy } = structure
+
+    strategy.style = ReactStyleVariation.StyledComponents
+    if (strategy?.projectStyleSheet?.generator) {
+      strategy.projectStyleSheet.plugins = [createStyleSheetPlugin(), importStatementsPlugin]
+      strategy.projectStyleSheet.postprocessors = [prettierJS]
+      strategy.framework.config.isGlobalStylesDependent = false
+    }
+
+    return structure
+  }
+
+  async runAfter(structure: ProjectPluginStructure) {
+    const { files } = structure
+
+    if (!files.get('entry')) {
+      throw new Error(`Entry File is missing from the generated project, _document file not found`)
+    }
+
+    const fileContent = files.get('entry').files[0].content
+    const magicString = new MagicString(fileContent.replace('/n', '//n'))
+
+    magicString.appendRight(70, `\nimport { ServerStyleSheet } from 'styled-components' \n`)
+    magicString.appendRight(
+      114,
+      `\nstatic getInitialProps({ renderPage }) {
+const sheet = new ServerStyleSheet();
+const page = renderPage((App) => (props) =>
+  sheet.collectStyles(<App {...props} />),
+);
+const styleTags = sheet.getStyleElement();
+
+return { ...page, styleTags };
+}\n\n`
+    )
+    magicString.appendRight(175, `\n{this.props.styleTags}`)
+
+    const formattedCode = prettierJS({
+      [FileType.JS]: magicString.toString(),
+    })
+
+    const babelRc = `{
+  "presets": [
+    "next/babel"
+  ],
+  "plugins": [
+    [
+      "styled-components",
+      {
+        "ssr": true,
+        "displayName": true,
+        "preprocess": false
+      }
+    ]
+  ]
+}`
+
+    files.set('entry', {
+      path: ['pages'],
+      files: [
+        {
+          name: '_document',
+          fileType: FileType.JS,
+          content: formattedCode[FileType.JS],
+        },
+      ],
+    })
+
+    files.set('.babelrc', {
+      path: [],
+      files: [
+        {
+          name: '.babelrc',
+          content: babelRc,
+        },
+      ],
+    })
+    return structure
+  }
+}
+
+const pluginNextStyledComponents = new PluginNextStyledComponents()
+export { PluginNextStyledComponents }
+export default pluginNextStyledComponents
diff --git a/packages/teleport-project-plugin-next-styled-components/tsconfig-cjs.json b/packages/teleport-project-plugin-next-styled-components/tsconfig-cjs.json
new file mode 100755
index 00000000..c66b615a
--- /dev/null
+++ b/packages/teleport-project-plugin-next-styled-components/tsconfig-cjs.json
@@ -0,0 +1,11 @@
+{
+  "extends": "../../tsconfig.json",
+  "compilerOptions": {
+    "outDir": "dist/cjs",
+    "module": "commonjs",
+    "target": "es5"
+  },
+  "include": [
+    "./src"
+  ]
+}
\ No newline at end of file
diff --git a/packages/teleport-project-plugin-next-styled-components/tsconfig-esm.json b/packages/teleport-project-plugin-next-styled-components/tsconfig-esm.json
new file mode 100755
index 00000000..5d65f088
--- /dev/null
+++ b/packages/teleport-project-plugin-next-styled-components/tsconfig-esm.json
@@ -0,0 +1,12 @@
+{
+  "extends": "../../tsconfig.json",
+  "compilerOptions": {
+    "outDir": "dist/esm",
+    "module": "esnext",
+    "target": "es2019",
+    "moduleResolution": "node"
+  },
+  "include": [
+    "./src"
+  ]
+}
\ No newline at end of file
diff --git a/packages/teleport-types/src/generators.ts b/packages/teleport-types/src/generators.ts
index 769e78b6..def4c4f8 100644
--- a/packages/teleport-types/src/generators.ts
+++ b/packages/teleport-types/src/generators.ts
@@ -54,6 +54,26 @@ export interface ComponentStructure {
 
 export type ComponentPlugin = (structure: ComponentStructure) => Promise<ComponentStructure>
 
+export type InMemoryFileRecord = {
+  path: string[]
+  files: GeneratedFile[]
+}
+
+export interface ProjectPluginStructure {
+  uidl: ProjectUIDL
+  template: GeneratedFolder
+  files: Map<string, InMemoryFileRecord>
+  dependencies: Record<string, string>
+  devDependencies: Record<string, string>
+  strategy: ProjectStrategy
+  rootFolder: GeneratedFolder
+}
+
+export interface ProjectPlugin {
+  runBefore: (structure: ProjectPluginStructure) => Promise<ProjectPluginStructure>
+  runAfter: (structure: ProjectPluginStructure) => Promise<ProjectPluginStructure>
+}
+
 export interface ComponentDefaultPluginParams {
   fileType: FileType
 }
@@ -135,32 +155,67 @@ export interface ProjectGenerator {
   getAssetsPath: () => string[]
 }
 
+export interface GeneratorFactoryParams {
+  mappings?: Mapping[]
+  plugins?: ComponentPlugin[]
+  postprocessors?: PostProcessor[]
+  variation?: StyleVariation
+}
+
+export type ComponentGeneratorInstance = (params?: GeneratorFactoryParams) => ComponentGenerator
+
 export interface ProjectStrategy {
+  style?: StyleVariation
   components: {
-    generator: ComponentGenerator
-    moduleGenerator?: ComponentGenerator
+    generator: ComponentGeneratorInstance
+    plugins?: ComponentPlugin[]
+    postprocessors?: PostProcessor[]
+    mappings?: Mapping[]
+    module?: {
+      generator: ComponentGeneratorInstance
+      plugins?: ComponentPlugin[]
+      postprocessors?: PostProcessor[]
+      mappings?: Mapping[]
+    }
     path: string[]
     options?: ProjectStrategyComponentOptions
   }
   pages: {
-    generator: ComponentGenerator
-    moduleGenerator?: ComponentGenerator
+    generator: ComponentGeneratorInstance
+    plugins?: ComponentPlugin[]
+    postprocessors?: PostProcessor[]
+    mappings?: Mapping[]
+    module?: {
+      generator: ComponentGeneratorInstance
+      plugins?: ComponentPlugin[]
+      postprocessors?: PostProcessor[]
+      mappings?: Mapping[]
+    }
     path: string[]
     options?: ProjectStrategyPageOptions
   }
   projectStyleSheet?: {
-    generator: ComponentGenerator
+    generator: ComponentGeneratorInstance
+    plugins?: ComponentPlugin[]
+    postprocessors?: PostProcessor[]
+    mappings?: Mapping[]
     path: string[]
     fileName: string
     importFile?: boolean
   }
   router?: {
-    generator: ComponentGenerator
+    generator: ComponentGeneratorInstance
+    plugins?: ComponentPlugin[]
+    postprocessors?: PostProcessor[]
+    mappings?: Mapping[]
     path: string[]
     fileName?: string
   }
   entry?: {
-    generator: ComponentGenerator
+    generator: ComponentGeneratorInstance
+    plugins?: ComponentPlugin[]
+    postprocessors?: PostProcessor[]
+    mappings?: Mapping[]
     path: string[]
     fileName?: string
     chunkGenerationFunction?: (
@@ -182,7 +237,9 @@ export interface ProjectStrategy {
       fileName: string
       fileType: string
       path: string[]
-      generator?: ComponentGenerator
+      generator?: ComponentGeneratorInstance
+      plugins?: ComponentPlugin[]
+      postprocessors?: PostProcessor[]
       configContentGenerator?: (options: FrameWorkConfigOptions) => ConfigGeneratorResult
       isGlobalStylesDependent?: boolean
     }
@@ -399,6 +456,11 @@ export enum PublisherType {
   CODESANDBOX = 'CodeSandbox',
 }
 
+export enum GatsbyStyleVariation {
+  CSSModules = 'CSS Modules',
+  StyledComponents = 'Styled Components',
+}
+
 export enum ProjectType {
   REACT = 'React',
   NEXT = 'Next',
@@ -410,6 +472,10 @@ export enum ProjectType {
   GATSBY = 'Gatsby',
   GRIDSOME = 'Gridsome',
   REACTNATIVE = 'React-Native',
+  NEXT_REACT_JSS = 'Next-React-JSS',
+  NEXT_CSS_MODULES = 'Next-CSSModules',
+  NEXT_STYLED_COMPONENTS = 'Next-StyledComponents',
+  GATSBY_STYLED_COMPONENTS = 'Gatsby-StyledComponents',
 }
 
 export enum ComponentType {
@@ -430,7 +496,11 @@ export const DefaultStyleVariation: Record<ComponentType, StyleVariation | null>
   [ComponentType.ANGULAR]: null,
 }
 
-export type StyleVariation = ReactStyleVariation | PreactStyleVariation | ReactNativeStyleVariation
+export type StyleVariation =
+  | ReactStyleVariation
+  | PreactStyleVariation
+  | ReactNativeStyleVariation
+  | GatsbyStyleVariation
 
 // The last two types are used by the teleport-code-generator package
 
diff --git a/yarn.lock b/yarn.lock
index 5984a63b..2361f337 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1417,10 +1417,10 @@
   version "2.4.0"
   resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e"
 
-"@types/prettier@^2.1.6":
-  version "2.1.6"
-  resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.1.6.tgz#f4b1efa784e8db479cdb8b14403e2144b1e9ff03"
-  integrity sha512-6gOkRe7OIioWAXfnO/2lFiv+SJichKVSys1mSsgyrYHSEjk8Ctv4tSR/Odvnu+HWlH2C8j53dahU03XmQdd5fA==
+"@types/prettier@^2.0.0":
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.0.0.tgz#dc85454b953178cc6043df5208b9e949b54a3bc4"
+  integrity sha512-/rM+sWiuOZ5dvuVzV37sUuklsbg+JPOP8d+nNFlo2ZtfpzPiPvh1/gc8liWOLBqe+sR+ZM7guPaIcTt6UZTo7Q==
 
 "@types/prismjs@^1.9.1":
   version "1.16.0"
@@ -4305,9 +4305,8 @@ inherits@2.0.3:
   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
 
 ini@^1.3.2, ini@^1.3.4, ini@^1.3.5:
-  version "1.3.7"
-  resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84"
-  integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==
+  version "1.3.5"
+  resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
 
 init-package-json@^1.10.3:
   version "1.10.3"
@@ -6783,10 +6782,10 @@ prettier@^1.17.0:
   version "1.19.1"
   resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
 
-prettier@^2.2.1:
-  version "2.2.1"
-  resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5"
-  integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==
+prettier@^2.0.4:
+  version "2.0.4"
+  resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.4.tgz#2d1bae173e355996ee355ec9830a7a1ee05457ef"
+  integrity sha512-SVJIQ51spzFDvh4fIbCLvciiDMCrRhlN3mbZvv/+ycjvmF5E73bKdGfU8QDLNmjYJf+lsGnDBC4UUnvTe5OO0w==
 
 pretty-format@^24.9.0:
   version "24.9.0"


Test patch:
diff --git a/packages/teleport-code-generator/__tests__/end2end/index.ts b/packages/teleport-code-generator/__tests__/end2end/index.ts
new file mode 100644
index 00000000..08979d6b
--- /dev/null
+++ b/packages/teleport-code-generator/__tests__/end2end/index.ts
@@ -0,0 +1,183 @@
+import {
+  createNextProjectGenerator,
+  NextTemplate,
+} from '@teleporthq/teleport-project-generator-next'
+import {
+  createGatsbyProjectGenerator,
+  GatsbyTemplate as template,
+} from '@teleporthq/teleport-project-generator-gatsby'
+import pluginNextCSSModules from '@teleporthq/teleport-project-plugin-next-css-modules'
+import pluginNextStyledComponents from '@teleporthq/teleport-project-plugin-next-styled-components'
+import pluginGatsbyStyledComponents from '@teleporthq/teleport-project-plugin-gatsby-styled-components'
+import projectUIDL from '../../../../examples/test-samples/project-with-import-global-styles.json'
+import { FileType } from '@teleporthq/teleport-types'
+import uidlSample from '../../../../examples/test-samples/project-sample.json'
+import uidlSampleWithExternalDependencies from '../../../../examples/test-samples/project-sample-with-dependency.json'
+import uidlSampleWithJustTokens from '../../../../examples/test-samples/project-with-only-tokens.json'
+import invalidUidlSample from '../../../../examples/test-samples/project-invalid-sample.json'
+
+describe('Generates NEXT-JS project with plugins', () => {
+  it('NEXT + css-modules plugin', async () => {
+    const generator = createNextProjectGenerator()
+    generator.addPlugin(pluginNextCSSModules)
+    const result = await generator.generateProject(projectUIDL, NextTemplate)
+
+    const nextConfig = result.files.find(
+      (file) => file.name === 'next.config' && file.fileType === FileType.JS
+    )
+    const packageJSON = result.files.find((file) => file.name === 'package')
+    const pages = result.subFolders.find((folder) => folder.name === 'pages')
+    const styleModule = pages.files.find((file) => file.fileType === FileType.CSS)
+    const appRoot = pages.files.find((file) => file.name === '_app')
+
+    expect(result.files.length).toBe(2)
+    expect(packageJSON).toBeDefined()
+    expect(packageJSON.content).toContain(`@zeit/next-css`)
+    expect(nextConfig).toBeDefined()
+    expect(nextConfig.content).toContain(`const withCSS = require('@zeit/next-css')`)
+    expect(pages.files.length).toBe(6)
+    expect(styleModule).toBeDefined()
+    expect(styleModule.name).toBe('style.module')
+    expect(appRoot).toBeDefined()
+    expect(appRoot.content).toContain(`import './style.module.css'`)
+  })
+
+  it('NEXT + StyledComponents', async () => {
+    const generator = createNextProjectGenerator()
+    generator.addPlugin(pluginNextStyledComponents)
+    const result = await generator.generateProject(projectUIDL, NextTemplate)
+
+    const babelRC = result.files.find((file) => file.name === `.babelrc`)
+    const packgeJSON = result.files.find((file) => file.name === 'package')
+    const pages = result.subFolders.find((folder) => folder.name === 'pages')
+    const styleModule = pages.files.find(
+      (file) => file.name === 'style' && file.fileType === FileType.JS
+    )
+    const document = pages.files.find(
+      (file) => file.name === '_document' && file.fileType === FileType.JS
+    )
+    const appFile = pages.files.find(
+      (file) => file.name === '_app' && file.fileType === FileType.JS
+    )
+
+    expect(babelRC).toBeDefined()
+    expect(babelRC.content).toContain(`styled-components`)
+    expect(packgeJSON).toBeDefined()
+    expect(packgeJSON.content).toContain(`"styled-components": "4.2.0"`)
+    expect(pages.files.length).toBe(6)
+    expect(styleModule).toBeDefined()
+    expect(styleModule.content).toContain(`import { css } from 'styled-components'`)
+    expect(document).toBeDefined()
+    expect(document.content).toContain(`import { ServerStyleSheet } from 'styled-components'`)
+    expect(document.content).toContain(`const sheet = new ServerStyleSheet()`)
+    expect(document.content).toContain(`{this.props.styleTags}`)
+    expect(appFile.content).not.toContain(`import "./style.css"`)
+  })
+})
+
+describe('Generates Gatsby Projects with plugins', () => {
+  it('runs without crashing', async () => {
+    const generator = createGatsbyProjectGenerator()
+    generator.addPlugin(pluginGatsbyStyledComponents)
+    const outputFolder = await generator.generateProject(uidlSample, template)
+    const assetsPath = generator.getAssetsPath()
+
+    const srcFolder = outputFolder.subFolders[0]
+    const pagesFolder = srcFolder.subFolders[1]
+    const componentsFolder = srcFolder.subFolders[2]
+    const gatsbyConfigFile = outputFolder.files.find((file) => file.name === 'gatsby-config')
+
+    expect(gatsbyConfigFile).toBeDefined()
+    expect(assetsPath).toBeDefined()
+    expect(outputFolder.name).toBe(template.name)
+    expect(outputFolder.files[0].name).toBe('package')
+    expect(srcFolder.files[0].name).toBe('html')
+    expect(srcFolder.files[0].fileType).toBe(FileType.JS)
+    expect(srcFolder.files[0].content).toBeDefined()
+    expect(pagesFolder.name).toBe('pages')
+    expect(pagesFolder.files.length).toBeGreaterThan(0)
+    expect(componentsFolder.files.length).toBeGreaterThan(0)
+    expect(componentsFolder.name).toBe('components')
+  })
+
+  it('runs without crashing with external dependencies', async () => {
+    const generator = createGatsbyProjectGenerator()
+    generator.addPlugin(pluginGatsbyStyledComponents)
+    const outputFolder = await generator.generateProject(
+      uidlSampleWithExternalDependencies,
+      template
+    )
+    const assetsPath = generator.getAssetsPath()
+
+    const srcFolder = outputFolder.subFolders[0]
+    const pagesFolder = srcFolder.subFolders[1]
+    const componentsFolder = srcFolder.subFolders[2]
+
+    expect(assetsPath).toBeDefined()
+    expect(outputFolder.name).toBe(template.name)
+    expect(outputFolder.files[0].name).toBe('package')
+    expect(outputFolder.files[0].content).toContain(`"antd": "4.5.4"`)
+    expect(srcFolder.files[0].name).toBe('html')
+    expect(srcFolder.files[0].fileType).toBe(FileType.JS)
+    expect(srcFolder.files[0].content).toBeDefined()
+    expect(pagesFolder.name).toBe('pages')
+    expect(pagesFolder.files.length).toBeGreaterThan(0)
+    expect(componentsFolder.files.length).toBeGreaterThan(0)
+    expect(componentsFolder.name).toBe('components')
+
+    /*
+     * Imports like css imports / or imports which are just inserted,
+     * are added in index file in pages
+     */
+    expect(pagesFolder.files[0].content).toContain(`import 'antd/dist/antd.css'`)
+  })
+
+  it('runs without crashing and using only tokens', async () => {
+    const generator = createGatsbyProjectGenerator()
+    generator.addPlugin(pluginGatsbyStyledComponents)
+    const result = await generator.generateProject(uidlSampleWithJustTokens, template)
+    const srcFolder = result.subFolders.find((folder) => folder.name === 'src')
+    const styleSheet = srcFolder.files.find(
+      (file) => file.name === 'style' && file.fileType === FileType.JS
+    )
+
+    expect(styleSheet).toBeDefined()
+    expect(styleSheet.content).toContain(`Greys700: "#999999"`)
+  })
+
+  it('throws error when conifg file is not found with custom framework config', async () => {
+    const generator = createGatsbyProjectGenerator()
+    generator.addPlugin(pluginGatsbyStyledComponents)
+    const result = generator.generateProject(invalidUidlSample, template)
+
+    await expect(result).rejects.toThrow(Error)
+  })
+
+  it('Gatsby + Styled Components', async () => {
+    const generator = createGatsbyProjectGenerator()
+    generator.addPlugin(pluginGatsbyStyledComponents)
+
+    const result = await generator.generateProject(projectUIDL, template)
+    const packageJSON = result.files.find(
+      (file) => file.name === 'package' && file.fileType === FileType.JSON
+    )
+    const gatsbyConfig = result.files.find(
+      (file) => file.name === 'gatsby-config' && file.fileType === FileType.JS
+    )
+    const [styleModule] = result.subFolders.map((file) => {
+      if (file.name === 'src') {
+        return file.files.find(
+          (subFile) => subFile.name === 'style' && subFile.fileType === FileType.JS
+        )
+      }
+    })
+
+    expect(gatsbyConfig).toBeDefined()
+    expect(gatsbyConfig.content).toContain(`gatsby-plugin-styled-components`)
+    expect(styleModule).toBeDefined()
+    expect(styleModule.content).toContain(`import { css } from "styled-components"`)
+    expect(packageJSON).toBeDefined()
+    expect(packageJSON.content).toContain(`"babel-plugin-styled-components": "^1.10.6"`)
+    expect(packageJSON.content).toContain(`"gatsby-plugin-styled-components": "^3.0.0"`)
+  })
+})
diff --git a/packages/teleport-component-generator-react/__tests__/end2end/index.ts b/packages/teleport-component-generator-react/__tests__/end2end/index.ts
index c9757694..37e5b144 100644
--- a/packages/teleport-component-generator-react/__tests__/end2end/index.ts
+++ b/packages/teleport-component-generator-react/__tests__/end2end/index.ts
@@ -14,7 +14,9 @@ const findFileByType = (files: GeneratedFile[], type: string = JS_FILE) =>
 
 describe('React Component Generator', () => {
   describe('with CSS Modules', () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.CSSModules)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.CSSModules,
+    })
 
     it('should return the files containing the code as string', async () => {
       const result = await generator.generateComponent(uidlSample)
@@ -30,7 +32,9 @@ describe('React Component Generator', () => {
   })
 
   describe('with JSS', () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.ReactJSS)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.ReactJSS,
+    })
 
     it('should return the files containing the code as string', async () => {
       const result = await generator.generateComponent(uidlSample)
@@ -44,7 +48,9 @@ describe('React Component Generator', () => {
   })
 
   describe('with StyledComponents', () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.StyledComponents)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.StyledComponents,
+    })
 
     it('should return the files containing the code as string', async () => {
       const result = await generator.generateComponent(uidlSample)
@@ -73,7 +79,8 @@ describe('React Component Generator', () => {
 
   describe('with Custom Mapping', () => {
     const mapping = { elements: { container: { elementType: 'fakediv' } } }
-    const generator = createReactComponentGenerator(ReactStyleVariation.InlineStyles, {
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.InlineStyles,
       mappings: [mapping],
     })
 
@@ -90,7 +97,9 @@ describe('React Component Generator', () => {
 })
 
 describe('React Component Validator', () => {
-  const generator = createReactComponentGenerator(ReactStyleVariation.CSSModules)
+  const generator = createReactComponentGenerator({
+    variation: ReactStyleVariation.CSSModules,
+  })
 
   it('works with valid UIDL sample', async () => {
     const result = await generator.generateComponent(uidlSample)
diff --git a/packages/teleport-component-generator-react/__tests__/integration/component-referenced-styles.ts b/packages/teleport-component-generator-react/__tests__/integration/component-referenced-styles.ts
index dd105039..50f6633f 100644
--- a/packages/teleport-component-generator-react/__tests__/integration/component-referenced-styles.ts
+++ b/packages/teleport-component-generator-react/__tests__/integration/component-referenced-styles.ts
@@ -50,7 +50,9 @@ describe('Generates media, pseudo and normal styles', () => {
   })
 
   it('Generates styles using CSS', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.CSS)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.CSS,
+    })
     const { files } = await generator.generateComponent(uidl)
     const cssFile = findFileByType(files, FileType.CSS)
     const jsFile = findFileByType(files, FileType.JS)
@@ -65,7 +67,9 @@ describe('Generates media, pseudo and normal styles', () => {
   })
 
   it('Generates styles using Styled-Components', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.StyledComponents)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.StyledComponents,
+    })
     const { files } = await generator.generateComponent(uidl)
     const cssFile = findFileByType(files, FileType.CSS)
     const jsFile = findFileByType(files, FileType.JS)
@@ -79,7 +83,9 @@ describe('Generates media, pseudo and normal styles', () => {
   })
 
   it('Generates styles using ReactJSS', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.ReactJSS)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.ReactJSS,
+    })
     const { files } = await generator.generateComponent(uidl)
     const cssFile = findFileByType(files, FileType.CSS)
     const jsFile = findFileByType(files, FileType.JS)
@@ -95,7 +101,9 @@ describe('Generates media, pseudo and normal styles', () => {
   })
 
   it('Generates styles using StyledJSX', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.StyledJSX)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.StyledJSX,
+    })
     const { files } = await generator.generateComponent(uidl)
     const cssFile = findFileByType(files, FileType.CSS)
     const jsFile = findFileByType(files, FileType.JS)
@@ -145,7 +153,9 @@ describe('Add referenced styles even when direct styles are not present on node'
   })
 
   it('Generates styles using CSS', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.CSS)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.CSS,
+    })
     const { files } = await generator.generateComponent(uidl)
     const cssFile = findFileByType(files, FileType.CSS)
     const jsFile = findFileByType(files, FileType.JS)
@@ -160,7 +170,9 @@ describe('Add referenced styles even when direct styles are not present on node'
   })
 
   it('Generates styles using Styled-Components', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.StyledComponents)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.StyledComponents,
+    })
     const { files } = await generator.generateComponent(uidl)
     const cssFile = findFileByType(files, FileType.CSS)
     const jsFile = findFileByType(files, FileType.JS)
@@ -174,7 +186,9 @@ describe('Add referenced styles even when direct styles are not present on node'
   })
 
   it('Generates styles using ReactJSS', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.ReactJSS)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.ReactJSS,
+    })
     const { files } = await generator.generateComponent(uidl)
     const cssFile = findFileByType(files, FileType.CSS)
     const jsFile = findFileByType(files, FileType.JS)
@@ -188,7 +202,9 @@ describe('Add referenced styles even when direct styles are not present on node'
   })
 
   it('Generates styles using StyledJSX', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.StyledJSX)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.StyledJSX,
+    })
     const { files } = await generator.generateComponent(uidl)
     const cssFile = findFileByType(files, FileType.CSS)
     const jsFile = findFileByType(files, FileType.JS)
@@ -224,22 +240,30 @@ describe('Throws Error when a node is using project-styles but not present in UI
   })
 
   it('CSS', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.CSS)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.CSS,
+    })
     await expect(generator.generateComponent(uidl)).rejects.toThrow(Error)
   })
 
   it('Styled Components', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.StyledComponents)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.StyledComponents,
+    })
     await expect(generator.generateComponent(uidl)).rejects.toThrow(Error)
   })
 
   it('Styled JSX', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.StyledJSX)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.StyledJSX,
+    })
     await expect(generator.generateComponent(uidl)).rejects.toThrow(Error)
   })
 
   it('React JSS', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.ReactJSS)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.ReactJSS,
+    })
     await expect(generator.generateComponent(uidl)).rejects.toThrow(Error)
   })
 })
@@ -277,7 +301,9 @@ describe('Referes from project style and adds it to the node, without any styles
   }
 
   it('CSS-Modules', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.CSSModules)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.CSSModules,
+    })
     const cssOptions: GeneratorOptions = {
       projectStyleSet: {
         ...options.projectStyleSet,
@@ -293,7 +319,9 @@ describe('Referes from project style and adds it to the node, without any styles
   })
 
   it('CSS', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.CSS)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.CSS,
+    })
     const cssOptions: GeneratorOptions = {
       projectStyleSet: {
         ...options.projectStyleSet,
@@ -310,7 +338,9 @@ describe('Referes from project style and adds it to the node, without any styles
   })
 
   it('StyledComponents', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.StyledComponents)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.StyledComponents,
+    })
 
     const { files } = await generator.generateComponent(uidl, options)
     const jsFile = findFileByType(files, FileType.JS)
@@ -322,7 +352,9 @@ describe('Referes from project style and adds it to the node, without any styles
   })
 
   it('Styled JSX', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.StyledJSX)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.StyledJSX,
+    })
 
     const { files } = await generator.generateComponent(uidl, options)
     const jsFile = findFileByType(files, FileType.JS)
@@ -331,7 +363,9 @@ describe('Referes from project style and adds it to the node, without any styles
   })
 
   it('React JSS', async () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.ReactJSS)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.ReactJSS,
+    })
 
     const { files } = await generator.generateComponent(uidl, options)
     const jsFile = findFileByType(files, FileType.JS)
diff --git a/packages/teleport-component-generator-react/__tests__/integration/component-style.ts b/packages/teleport-component-generator-react/__tests__/integration/component-style.ts
index 63ab45ad..5abc7f71 100644
--- a/packages/teleport-component-generator-react/__tests__/integration/component-style.ts
+++ b/packages/teleport-component-generator-react/__tests__/integration/component-style.ts
@@ -46,7 +46,9 @@ const findFileByType = (files: GeneratedFile[], type: string = FileType.JS) =>
 describe('React Styles in Component', () => {
   describe('supports usage of state in styles', () => {
     it('Inline Styles should refer state in styles when state is mapped', async () => {
-      const generator = createReactComponentGenerator(ReactStyleVariation.InlineStyles)
+      const generator = createReactComponentGenerator({
+        variation: ReactStyleVariation.InlineStyles,
+      })
       const result = await generator.generateComponent(ComponentWithStateReference)
       const jsFile = findFileByType(result.files, FileType.JS)
 
@@ -56,7 +58,9 @@ describe('React Styles in Component', () => {
     })
 
     it('CSSModules should refer state in styles when state is mapped', async () => {
-      const generator = createReactComponentGenerator(ReactStyleVariation.CSSModules)
+      const generator = createReactComponentGenerator({
+        variation: ReactStyleVariation.CSSModules,
+      })
       const result = await generator.generateComponent(ComponentWithStateReference)
       const jsFile = findFileByType(result.files, FileType.JS)
       const cssFile = findFileByType(result.files, FileType.CSS)
@@ -69,7 +73,9 @@ describe('React Styles in Component', () => {
     })
 
     it('Basic CSS should refer state in styles when state is mapped', async () => {
-      const generator = createReactComponentGenerator(ReactStyleVariation.CSS)
+      const generator = createReactComponentGenerator({
+        variation: ReactStyleVariation.CSS,
+      })
       const result = await generator.generateComponent(ComponentWithStateReference)
       const jsFile = findFileByType(result.files, FileType.JS)
       const cssFile = findFileByType(result.files, FileType.CSS)
@@ -82,7 +88,9 @@ describe('React Styles in Component', () => {
     })
 
     it('JSS should through error when state is refered', async () => {
-      const generator = createReactComponentGenerator(ReactStyleVariation.ReactJSS)
+      const generator = createReactComponentGenerator({
+        variation: ReactStyleVariation.ReactJSS,
+      })
       try {
         await generator.generateComponent(ComponentWithStateReference)
       } catch (e) {
@@ -93,7 +101,9 @@ describe('React Styles in Component', () => {
   })
 
   describe('supports props json declaration in styles', () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.InlineStyles)
+    const generator = createReactComponentGenerator({
+      variation: ReactStyleVariation.InlineStyles,
+    })
 
     it('should add attributes on component', async () => {
       const result = await generator.generateComponent(ComponentWithValidStyle)
@@ -105,7 +115,9 @@ describe('React Styles in Component', () => {
     })
 
     it('should support object props in styledjsx', async () => {
-      const styledJSXGenerator = createReactComponentGenerator(ReactStyleVariation.StyledJSX)
+      const styledJSXGenerator = createReactComponentGenerator({
+        variation: ReactStyleVariation.StyledJSX,
+      })
       const result = await styledJSXGenerator.generateComponent(ComponentWithValidStyle)
       const jsFile = findFileByType(result.files, FileType.JS)
 
@@ -114,7 +126,9 @@ describe('React Styles in Component', () => {
     })
 
     it('should throw error when a state is being refered in generated StyledJSX ', async () => {
-      const styledJSXGenerator = createReactComponentGenerator(ReactStyleVariation.StyledJSX)
+      const styledJSXGenerator = createReactComponentGenerator({
+        variation: ReactStyleVariation.StyledJSX,
+      })
       try {
         await styledJSXGenerator.generateComponent(ComponentWithInvalidStateStyles)
         expect(true).toBe(false)
@@ -126,9 +140,9 @@ describe('React Styles in Component', () => {
     })
 
     it('should explicitly send prop if style is using one prop variable', async () => {
-      const styledComponentsGenerator = createReactComponentGenerator(
-        ReactStyleVariation.StyledComponents
-      )
+      const styledComponentsGenerator = createReactComponentGenerator({
+        variation: ReactStyleVariation.StyledComponents,
+      })
       const result = await styledComponentsGenerator.generateComponent(
         ComponentWithValidSingleStlye
       )
@@ -157,9 +171,9 @@ describe('React Styles in Component', () => {
         {}
       )
 
-      const styledComponentsGenerator = createReactComponentGenerator(
-        ReactStyleVariation.StyledComponents
-      )
+      const styledComponentsGenerator = createReactComponentGenerator({
+        variation: ReactStyleVariation.StyledComponents,
+      })
       const result = await styledComponentsGenerator.generateComponent(uidl)
       const jsFile = findFileByType(result.files, FileType.JS)
 
@@ -191,9 +205,9 @@ describe('React Styles in Component', () => {
         {}
       )
 
-      const styledComponentsGenerator = createReactComponentGenerator(
-        ReactStyleVariation.StyledComponents
-      )
+      const styledComponentsGenerator = createReactComponentGenerator({
+        variation: ReactStyleVariation.StyledComponents,
+      })
       const result = await styledComponentsGenerator.generateComponent(uidl)
 
       const jsFile = findFileByType(result.files, FileType.JS)
@@ -207,7 +221,9 @@ describe('React Styles in Component', () => {
     })
 
     it('should inject props only once for styled components', async () => {
-      const styledJSXGenerator = createReactComponentGenerator(ReactStyleVariation.StyledComponents)
+      const styledJSXGenerator = createReactComponentGenerator({
+        variation: ReactStyleVariation.StyledComponents,
+      })
       const result = await styledJSXGenerator.generateComponent(ComponentWithValidStyle)
 
       const jsFile = findFileByType(result.files, FileType.JS)
@@ -215,7 +231,9 @@ describe('React Styles in Component', () => {
     })
 
     it('should throw error when a state is being refered in generated StyledComponents ', async () => {
-      const styledJSXGenerator = createReactComponentGenerator(ReactStyleVariation.StyledComponents)
+      const styledJSXGenerator = createReactComponentGenerator({
+        variation: ReactStyleVariation.StyledComponents,
+      })
       try {
         await styledJSXGenerator.generateComponent(ComponentWithInvalidStateStyles)
         expect(true).toBe(false)
@@ -228,7 +246,7 @@ describe('React Styles in Component', () => {
   })
 
   describe('React CSS file using CSS Modules', () => {
-    const generator = createReactComponentGenerator(ReactStyleVariation.CSSModules)
+    const generator = createReactComponentGenerator({ variation: ReactStyleVariation.CSSModules })
 
     it('should return code in an array of files', async () => {
       const result = await generator.generateComponent(ComponentWithValidStyle)
diff --git a/packages/teleport-project-generator-angular/__tests__/end2end/index.ts b/packages/teleport-project-generator-angular/__tests__/end2end/index.ts
index 42d80299..af161d38 100644
--- a/packages/teleport-project-generator-angular/__tests__/end2end/index.ts
+++ b/packages/teleport-project-generator-angular/__tests__/end2end/index.ts
@@ -69,7 +69,7 @@ import { ModalWindow } from './modal-window/modal-window.component'`)
   it('creates style sheet and adds to the webpack file', async () => {
     const result = await generator.generateProject(uidlSampleWithJustTokens, template)
     const styleSheet = result.subFolders[0].files.find(
-      (file) => file.name === 'style' && file.fileType === FileType.CSS
+      (file) => file.name === 'styles' && file.fileType === FileType.CSS
     )
 
     expect(styleSheet).toBeDefined()
diff --git a/packages/teleport-project-generator-gatsby/__tests__/end2end/index.ts b/packages/teleport-project-generator-gatsby/__tests__/end2end/index.ts
index 0ff9a6f9..644718c6 100644
--- a/packages/teleport-project-generator-gatsby/__tests__/end2end/index.ts
+++ b/packages/teleport-project-generator-gatsby/__tests__/end2end/index.ts
@@ -1,4 +1,4 @@
-import { FileType, ReactStyleVariation } from '@teleporthq/teleport-types'
+import { FileType } from '@teleporthq/teleport-types'
 import uidlSample from '../../../../examples/test-samples/project-sample.json'
 import uidlSampleWithExternalDependencies from '../../../../examples/test-samples/project-sample-with-dependency.json'
 import uidlSampleWithJustTokens from '../../../../examples/test-samples/project-with-only-tokens.json'
@@ -75,67 +75,4 @@ describe('Gatsby Project Generator', () => {
 
     await expect(result).rejects.toThrow(Error)
   })
-
-  it('throws error when conifg file is not found with custom framework config', async () => {
-    const generatorGatsbyStyledComponents = createGatsbyProjectGenerator({
-      variation: ReactStyleVariation.StyledComponents,
-    })
-    const result = generatorGatsbyStyledComponents.generateProject(invalidUidlSample, template)
-
-    await expect(result).rejects.toThrow(Error)
-  })
-})
-
-describe('Gatsby Project Generator with Styled Components', () => {
-  const generator = createGatsbyProjectGenerator({
-    variation: ReactStyleVariation.StyledComponents,
-  })
-
-  it('runs without crashing', async () => {
-    const outputFolder = await generator.generateProject(uidlSample, template)
-    const assetsPath = generator.getAssetsPath()
-
-    const srcFolder = outputFolder.subFolders[0]
-    const pagesFolder = srcFolder.subFolders[1]
-    const componentsFolder = srcFolder.subFolders[2]
-    const gatsbyConfigFile = outputFolder.files.find((file) => file.name === 'gatsby-config')
-
-    expect(gatsbyConfigFile).toBeDefined()
-    expect(assetsPath).toBeDefined()
-    expect(outputFolder.name).toBe(template.name)
-    expect(outputFolder.files[0].name).toBe('package')
-    expect(srcFolder.files[0].name).toBe('html')
-    expect(srcFolder.files[0].fileType).toBe(FileType.JS)
-    expect(srcFolder.files[0].content).toBeDefined()
-    expect(pagesFolder.name).toBe('pages')
-    expect(pagesFolder.files.length).toBeGreaterThan(0)
-    expect(componentsFolder.files.length).toBeGreaterThan(0)
-    expect(componentsFolder.name).toBe('components')
-  })
-
-  it('runs without crashing and using only tokens', async () => {
-    const result = await generator.generateProject(uidlSampleWithJustTokens, template)
-    const srcFolder = result.subFolders.find((folder) => folder.name === 'src')
-    const styleSheet = srcFolder.files.find(
-      (file) => file.name === 'style' && file.fileType === FileType.JS
-    )
-
-    expect(styleSheet).toBeDefined()
-    expect(styleSheet.content).toContain(`Greys700: '#999999'`)
-  })
-
-  it('throws error when invalid UIDL sample is used', async () => {
-    const result = generator.generateProject(invalidUidlSample, template)
-
-    await expect(result).rejects.toThrow(Error)
-  })
-
-  it('throws error when conifg file is not found with custom framework config', async () => {
-    const generatorGatsbyStyledComponents = createGatsbyProjectGenerator({
-      variation: ReactStyleVariation.StyledComponents,
-    })
-    const result = generatorGatsbyStyledComponents.generateProject(invalidUidlSample, template)
-
-    await expect(result).rejects.toThrow(Error)
-  })
 })
diff --git a/packages/teleport-project-generator-gridsome/__tests__/end2end/index.ts b/packages/teleport-project-generator-gridsome/__tests__/end2end/index.ts
index 3d87c999..ee5a4d9f 100644
--- a/packages/teleport-project-generator-gridsome/__tests__/end2end/index.ts
+++ b/packages/teleport-project-generator-gridsome/__tests__/end2end/index.ts
@@ -34,7 +34,7 @@ describe('Gridsome Project Generator', () => {
     expect(outputFolder.name).toBe(template.name)
     expect(srcFolder.files[0].name).toBe('main')
     expect(srcFolder.files[0].fileType).toBe('js')
-    expect(mainFile.content).toContain(`import '~/assets/style.css'`)
+    expect(mainFile.content).toContain(`import "~/assets/style.css"`)
     expect(assetsFoler.files.length).toBe(1)
     expect(assetsFoler.files[0].name).toBe('style')
     expect(assetsFoler.files[0].content).toContain(`.primaryButton`)
diff --git a/packages/teleport-project-generator-next/__tests__/end2end/index.ts b/packages/teleport-project-generator-next/__tests__/end2end/index.ts
index 7b88aa29..1294fb95 100644
--- a/packages/teleport-project-generator-next/__tests__/end2end/index.ts
+++ b/packages/teleport-project-generator-next/__tests__/end2end/index.ts
@@ -40,7 +40,7 @@ describe('React Next Project Generator', () => {
     expect(outputFolder.files[0].name).toBe('package')
     expect(appFile).toBeDefined()
     expect(appFile.content).not.toContain(`import "antd/dist/antd.css`)
-    expect(appFile.content).toContain(`import './style.css'`)
+    expect(appFile.content).toContain(`import "./style.css"`)
   })
 
   it('runs without crashing', async () => {
@@ -73,7 +73,7 @@ describe('React Next Project Generator', () => {
     expect(styleSheet).toBeDefined()
     expect(styleSheet.content).toContain(`--greys-500: #595959`)
     expect(appFile).toBeDefined()
-    expect(appFile.content).toContain(`import './style.css'`)
+    expect(appFile.content).toContain(`import "./style.css"`)
   })
 
   it('throws error when invalid UIDL sample is used', async () => {
diff --git a/packages/teleport-project-generator/__tests__/assembly-line.ts b/packages/teleport-project-generator/__tests__/assembly-line.ts
new file mode 100644
index 00000000..441525e0
--- /dev/null
+++ b/packages/teleport-project-generator/__tests__/assembly-line.ts
@@ -0,0 +1,39 @@
+import { ReactStyleVariation } from '@teleporthq/teleport-types'
+import AssemblyLine from '../src/assembly-line'
+import { mockAssemblyLineStructure, simplePluginMock, simplePluginMockToInjectFiles } from './mocks'
+
+describe('Tests Project Aseembly line', () => {
+  const assembly = new AssemblyLine([simplePluginMock])
+
+  it('Plugin returns structure with style modified in runBefore life-cycle', async () => {
+    const result = await assembly.runBefore(mockAssemblyLineStructure())
+
+    expect(result).toBeDefined()
+    expect(result.strategy.style).toBe(ReactStyleVariation.CSS)
+    expect(Object.keys(result.dependencies).length).not.toBe(1)
+    expect(Object.keys(result.devDependencies).length).not.toBe(1)
+  })
+
+  it('Plugin returns structure with dependencies modified in run-after life-cycle', async () => {
+    const result = await assembly.runAfter(mockAssemblyLineStructure())
+
+    expect(result).toBeDefined()
+    expect(Object.keys(result.dependencies).length).toBe(1)
+    expect(Object.keys(result.devDependencies).length).toBe(1)
+  })
+
+  it('Adds multiple plugins to assembly-line', async () => {
+    assembly.addPlugin(simplePluginMockToInjectFiles)
+    const result = await assembly.runAfter(mockAssemblyLineStructure())
+    const { dependencies, devDependencies, files } = result
+    const configFile = files.get('config')
+
+    expect(result).toBeDefined()
+    expect(Object.keys(dependencies).length).toBe(1)
+    expect(Object.keys(devDependencies).length).toBe(1)
+    /* tslint:disable:no-string-literal */
+    expect(dependencies['react']).toBe(`^16.0.8`)
+    expect(configFile).toBeDefined()
+    expect(configFile.files[0].content).toContain(`cssModules: true`)
+  })
+})
diff --git a/packages/teleport-project-generator/__tests__/file-handlers.ts b/packages/teleport-project-generator/__tests__/file-handlers.ts
index 305f78ee..e15f6b0b 100644
--- a/packages/teleport-project-generator/__tests__/file-handlers.ts
+++ b/packages/teleport-project-generator/__tests__/file-handlers.ts
@@ -2,7 +2,7 @@ import { handlePackageJSON, createEntryFile, createManifestJSONFile } from '../s
 import { PackageJSON } from '../src/types'
 import { GeneratedFolder, ProjectUIDL, FileType } from '@teleporthq/teleport-types'
 import { component, elementNode } from '@teleporthq/teleport-uidl-builders'
-
+import { createComponentGenerator } from '@teleporthq/teleport-component-generator'
 import { createStrategyWithCommonGenerator } from './mocks'
 
 import uidlSample from '../../../examples/test-samples/project-sample.json'
@@ -13,10 +13,15 @@ describe('createHtmlIndexFile', () => {
       assetsPrefix: '/static',
       appRootOverride: '{{root-placeholder}}',
     }
-    const result = await createEntryFile(uidlSample, createStrategyWithCommonGenerator(), options)
-
-    expect(result.content).toContain('<html')
-    expect(result.content).toContain('{{root-placeholder}}')
+    const [entryFile] = await createEntryFile(
+      (uidlSample as unknown) as ProjectUIDL,
+      createStrategyWithCommonGenerator(),
+      createComponentGenerator(),
+      options
+    )
+
+    expect(entryFile.content).toContain('<html')
+    expect(entryFile.content).toContain('{{root-placeholder}}')
   })
 })
 
diff --git a/packages/teleport-project-generator/__tests__/index.ts b/packages/teleport-project-generator/__tests__/index.ts
index 2a7ce19d..bc64d80f 100644
--- a/packages/teleport-project-generator/__tests__/index.ts
+++ b/packages/teleport-project-generator/__tests__/index.ts
@@ -13,9 +13,6 @@ describe('Generic Project Generator', () => {
   describe('with the same component generator for pages and components', () => {
     const strategy = createStrategyWithCommonGenerator()
     const generator = createProjectGenerator(strategy)
-    const { generator: componentsGenerator } = strategy.components
-    const { generator: routerGenerator } = strategy.router
-    const { generator: entryGenerator } = strategy.entry
 
     it('creates an instance of a project generator', () => {
       expect(generator.generateProject).toBeDefined()
@@ -30,20 +27,24 @@ describe('Generic Project Generator', () => {
 
     it('sends the mapping to the component generators', () => {
       generator.addMapping(mockMapping)
-      expect(componentsGenerator.addMapping).toBeCalledTimes(1)
-      expect(componentsGenerator.addMapping).toBeCalledWith(mockMapping)
+
+      expect(strategy.components.mappings.length).toBe(1)
+      expect(strategy.components.mappings[0]).toBe(mockMapping)
+      expect(strategy.pages.mappings.length).toBe(1)
+      expect(strategy.pages.mappings[0]).toBe(mockMapping)
     })
 
     it('calls the generators according to the strategy', async () => {
       const result = await generator.generateProject(projectUIDL)
-
-      const uidl = projectUIDL as ProjectUIDL
+      const uidl = (projectUIDL as unknown) as ProjectUIDL
 
       // This adds the local dependencies on the UIDL, so we can proper assert below
       resolveLocalDependencies([], uidl.components, strategy)
-
-      expect(componentsGenerator.generateComponent).toBeCalledTimes(7)
-      expect(componentsGenerator.generateComponent).toBeCalledWith(
+      expect(generator.componentGenerator).toBeDefined()
+      expect(generator.pageGenerator).toBeDefined()
+      expect(generator.pageGenerator.generateComponent).toBeCalledTimes(3)
+      expect(generator.componentGenerator.generateComponent).toBeCalledTimes(4)
+      expect(generator.componentGenerator.generateComponent).toBeCalledWith(
         expect.objectContaining({ name: 'ExpandableArea' }),
         expect.objectContaining({
           assetsPrefix: '/test/static',
@@ -51,8 +52,8 @@ describe('Generic Project Generator', () => {
           skipValidation: true,
         })
       )
-      expect(entryGenerator.linkCodeChunks).toBeCalledTimes(1)
-      expect(routerGenerator.generateComponent).toBeCalledTimes(1)
+      expect(generator.entryGenerator.linkCodeChunks).toBeCalledTimes(1)
+      expect(generator.routerGenerator.generateComponent).toBeCalledTimes(1)
 
       const routerUIDL = {
         ...uidl.root,
@@ -61,7 +62,7 @@ describe('Generic Project Generator', () => {
         },
       }
 
-      expect(routerGenerator.generateComponent).toBeCalledWith(
+      expect(generator.routerGenerator.generateComponent).toBeCalledWith(
         routerUIDL,
         expect.objectContaining({
           localDependenciesPrefix: './pages/',
@@ -76,10 +77,6 @@ describe('Generic Project Generator', () => {
   describe('with the different component generators', () => {
     const strategy = createStrategyWithSeparateGenerators()
     const generator = createProjectGenerator(strategy)
-    const { generator: componentsGenerator } = strategy.components
-    const { generator: pagesGenerator } = strategy.pages
-    const { generator: routerGenerator } = strategy.router
-    const { generator: entryGenerator } = strategy.entry
 
     it('creates an instance of a project generator', () => {
       expect(generator.generateProject).toBeDefined()
@@ -94,22 +91,19 @@ describe('Generic Project Generator', () => {
 
     it('sends the mapping to the component generators', () => {
       generator.addMapping(mockMapping)
-      expect(componentsGenerator.addMapping).toBeCalledTimes(1)
-      expect(componentsGenerator.addMapping).toBeCalledWith(mockMapping)
-      expect(pagesGenerator.addMapping).toBeCalledTimes(1)
-      expect(pagesGenerator.addMapping).toBeCalledWith(mockMapping)
+      expect(strategy.components.mappings.length).toBe(1)
+      expect(strategy.components.mappings[0]).toBe(mockMapping)
     })
 
     it('calls the generators according to the strategy', async () => {
       await generator.generateProject(projectUIDL)
-
       const uidl = (projectUIDL as unknown) as ProjectUIDL
 
       // This adds the local dependencies on the UIDL, so we can proper assert below
       resolveLocalDependencies([], uidl.components, strategy)
 
-      expect(componentsGenerator.generateComponent).toBeCalledTimes(4)
-      expect(componentsGenerator.generateComponent).toBeCalledWith(
+      expect(generator.componentGenerator.generateComponent).toBeCalledTimes(4)
+      expect(generator.componentGenerator.generateComponent).toBeCalledWith(
         expect.objectContaining({ name: 'ExpandableArea' }),
         {
           assetsPrefix: '/static',
@@ -118,8 +112,8 @@ describe('Generic Project Generator', () => {
           skipValidation: true,
         }
       )
-      expect(pagesGenerator.generateComponent).toBeCalledTimes(3)
-      expect(pagesGenerator.generateComponent).toBeCalledWith(
+      expect(generator.pageGenerator.generateComponent).toBeCalledTimes(3)
+      expect(generator.pageGenerator.generateComponent).toBeCalledWith(
         expect.objectContaining({
           name: 'Home',
         }),
@@ -130,7 +124,7 @@ describe('Generic Project Generator', () => {
           skipValidation: true,
         }
       )
-      expect(entryGenerator.linkCodeChunks).toBeCalledTimes(1)
+      expect(generator.entryGenerator.linkCodeChunks).toBeCalledTimes(1)
 
       const routerUIDL = {
         ...uidl.root,
@@ -139,8 +133,8 @@ describe('Generic Project Generator', () => {
         },
       }
 
-      expect(routerGenerator.generateComponent).toBeCalledTimes(1)
-      expect(routerGenerator.generateComponent).toBeCalledWith(
+      expect(generator.routerGenerator.generateComponent).toBeCalledTimes(1)
+      expect(generator.routerGenerator.generateComponent).toBeCalledWith(
         routerUIDL,
         expect.objectContaining({
           localDependenciesPrefix: './pages/',
@@ -153,14 +147,10 @@ describe('Generic Project Generator', () => {
     const strategy = createStrategyWithCommonGenerator()
     strategy.components.options = {
       createFolderForEachComponent: true,
-      customComponentFileName: (name) => 'component',
-      customStyleFileName: (name) => 'style',
+      customComponentFileName: (_) => 'component',
+      customStyleFileName: (_) => 'style',
     }
-
     const generator = createProjectGenerator(strategy)
-    const { generator: componentsGenerator } = strategy.components
-    const { generator: routerGenerator } = strategy.router
-    const { generator: entryGenerator } = strategy.entry
 
     it('calls the generators according to the strategy', async () => {
       const result = await generator.generateProject(projectUIDL)
@@ -169,9 +159,11 @@ describe('Generic Project Generator', () => {
 
       // This adds the local dependencies on the UIDL, so we can proper assert below
       resolveLocalDependencies([], uidl.components, strategy)
-
-      expect(componentsGenerator.generateComponent).toBeCalledTimes(7)
-      expect(componentsGenerator.generateComponent).toBeCalledWith(
+      expect(generator.componentGenerator).toBeDefined()
+      expect(generator.pageGenerator).toBeDefined()
+      expect(generator.componentGenerator.generateComponent).toBeCalledTimes(4)
+      expect(generator.pageGenerator.generateComponent).toBeCalledTimes(3)
+      expect(generator.componentGenerator.generateComponent).toBeCalledWith(
         expect.objectContaining({ name: 'ExpandableArea' }),
         {
           assetsPrefix: '/test/static',
@@ -180,8 +172,8 @@ describe('Generic Project Generator', () => {
           skipValidation: true,
         }
       )
-      expect(entryGenerator.linkCodeChunks).toBeCalledTimes(1)
-      expect(routerGenerator.generateComponent).toBeCalledTimes(1)
+      expect(generator.entryGenerator.linkCodeChunks).toBeCalledTimes(1)
+      expect(generator.routerGenerator.generateComponent).toBeCalledTimes(1)
 
       const routerUIDL = {
         ...uidl.root,
@@ -190,7 +182,7 @@ describe('Generic Project Generator', () => {
         },
       }
 
-      expect(routerGenerator.generateComponent).toBeCalledWith(
+      expect(generator.routerGenerator.generateComponent).toBeCalledWith(
         routerUIDL,
         expect.objectContaining({
           localDependenciesPrefix: './pages/',
diff --git a/packages/teleport-project-generator/__tests__/mocks.ts b/packages/teleport-project-generator/__tests__/mocks.ts
index 177bb5bd..1c971539 100644
--- a/packages/teleport-project-generator/__tests__/mocks.ts
+++ b/packages/teleport-project-generator/__tests__/mocks.ts
@@ -3,7 +3,16 @@ import {
   CompiledComponent,
   GeneratedFolder,
   ProjectStrategy,
+  ProjectPluginStructure,
+  InMemoryFileRecord,
+  ProjectUIDL,
+  ReactStyleVariation,
+  ProjectPlugin,
+  FileType,
 } from '@teleporthq/teleport-types'
+import { UIDLUtils } from '@teleporthq/teleport-shared'
+import projectUIDL from '../../../examples/test-samples/project-sample.json'
+import { DEFAULT_TEMPLATE } from '../src/constants'
 
 export const mockMapping: Mapping = {
   elements: {
@@ -24,7 +33,7 @@ const mockedCompiledComponent: CompiledComponent = {
   dependencies: {},
 }
 
-const mockComponentGenerator = () => ({
+export const mockComponentGenerator = () => ({
   addMapping: jest.fn(),
   addPlugin: jest.fn(),
   addPostProcessor: jest.fn(),
@@ -58,23 +67,34 @@ const mockEntryFileGenerator = () => ({
 })
 
 export const createStrategyWithCommonGenerator = () => {
-  const commonGenerator = mockComponentGenerator()
   const strategy: ProjectStrategy = {
     components: {
-      generator: commonGenerator,
+      generator: mockComponentGenerator,
       path: ['test', 'components'],
+      plugins: [],
+      postprocessors: [],
+      mappings: [],
     },
     pages: {
-      generator: commonGenerator,
+      generator: mockComponentGenerator,
       path: ['test', 'pages'],
+      plugins: [],
+      postprocessors: [],
+      mappings: [],
     },
     entry: {
-      generator: mockEntryFileGenerator(),
+      generator: mockEntryFileGenerator,
       path: ['test'],
+      plugins: [],
+      postprocessors: [],
+      mappings: [],
     },
     router: {
-      generator: mockRouterGenerator(),
+      generator: mockRouterGenerator,
       path: ['test'],
+      plugins: [],
+      postprocessors: [],
+      mappings: [],
     },
     static: {
       path: ['test', 'static'],
@@ -85,23 +105,36 @@ export const createStrategyWithCommonGenerator = () => {
 
 export const createStrategyWithSeparateGenerators = () => {
   const strategy: ProjectStrategy = {
+    style: ReactStyleVariation.CSSModules,
     components: {
-      generator: mockComponentGenerator(),
+      generator: mockComponentGenerator,
       path: ['test', 'components'],
+      plugins: [],
+      postprocessors: [],
+      mappings: [],
     },
     pages: {
-      generator: mockComponentGenerator(),
+      generator: mockComponentGenerator,
       path: ['test', 'pages'],
+      plugins: [],
+      postprocessors: [],
+      mappings: [],
     },
     entry: {
-      generator: mockEntryFileGenerator(),
+      generator: mockEntryFileGenerator,
       path: ['test'],
       fileName: 'mock-filename',
+      plugins: [],
+      postprocessors: [],
+      mappings: [],
     },
     router: {
-      generator: mockRouterGenerator(),
+      generator: mockRouterGenerator,
       path: ['test'],
       fileName: 'mock-filename',
+      plugins: [],
+      postprocessors: [],
+      mappings: [],
     },
     static: {
       prefix: '/static',
@@ -137,3 +170,64 @@ export const folderWithFiles = (name: string = 'test'): GeneratedFolder => {
     subFolders: [],
   }
 }
+
+export const mockAssemblyLineStructure = (): ProjectPluginStructure => {
+  const rootFolder = UIDLUtils.cloneObject(DEFAULT_TEMPLATE)
+
+  return {
+    uidl: (projectUIDL as unknown) as ProjectUIDL,
+    template: DEFAULT_TEMPLATE,
+    files: new Map<string, InMemoryFileRecord>(),
+    dependencies: {},
+    devDependencies: {},
+    strategy: createStrategyWithCommonGenerator(),
+    rootFolder,
+  }
+}
+
+class SimpleProjectPluginMock implements ProjectPlugin {
+  async runBefore(structure: ProjectPluginStructure) {
+    const { strategy } = structure
+    strategy.style = ReactStyleVariation.CSS
+    return structure
+  }
+
+  async runAfter(structure: ProjectPluginStructure) {
+    const { dependencies, devDependencies } = structure
+    /* tslint:disable:no-string-literal */
+    dependencies['react'] = '^16.0.8'
+    /* tslint:disable:no-string-literal */
+    devDependencies['prop-types'] = '15.7.2'
+    return structure
+  }
+}
+export const simplePluginMock = new SimpleProjectPluginMock()
+
+class SimpleProjectPluginMockToInjectFiles implements ProjectPlugin {
+  async runBefore(structure: ProjectPluginStructure) {
+    const { strategy } = structure
+    strategy.style = ReactStyleVariation.CSS
+    return structure
+  }
+
+  async runAfter(structure: ProjectPluginStructure) {
+    const { files } = structure
+
+    files.set('config', {
+      path: [],
+      files: [
+        {
+          name: 'next.config',
+          fileType: FileType.JSON,
+          content: `const withCSS = require('@zeit/next-css')
+        module.exports = withCSS({
+          cssModules: true
+        })`,
+        },
+      ],
+    })
+
+    return structure
+  }
+}
+export const simplePluginMockToInjectFiles = new SimpleProjectPluginMockToInjectFiles()
diff --git a/packages/teleport-test/src/standalone.ts b/packages/teleport-test/src/standalone.ts
index 88b1a0a1..6114f5c0 100644
--- a/packages/teleport-test/src/standalone.ts
+++ b/packages/teleport-test/src/standalone.ts
@@ -11,7 +11,7 @@ const reactProjectUIDL = (reactProjectJSON as unknown) as ProjectUIDL
 const assetFile = readFileSync(join(__dirname, 'asset.png'))
 const base64File = Buffer.from(assetFile).toString('base64')
 const packerOptions: PackerOptions = {
-  publisher: PublisherType.DISK,
+  publisher: PublisherType.CODESANDBOX,
   projectType: ProjectType.REACT,
   publishOptions: {
     outputPath: 'dist',
@@ -38,11 +38,11 @@ const run = async () => {
     }
 
     let result
-    // result = await packProject(projectUIDL, {
-    //   ...packerOptions,
-    //   projectType: ProjectType.REACTNATIVE,
-    // })
-    // console.info(ProjectType.REACTNATIVE, '-', result.payload)
+    result = await packProject(projectUIDL, {
+      ...packerOptions,
+      projectType: ProjectType.REACTNATIVE,
+    })
+    console.info(ProjectType.REACTNATIVE, '-', result.payload)
     result = await packProject(reactProjectUIDL, {
       ...packerOptions,
       projectType: ProjectType.REACT,
@@ -53,6 +53,21 @@ const run = async () => {
       projectType: ProjectType.NEXT,
     })
     console.info(ProjectType.NEXT, '-', result.payload)
+    result = await packProject(projectUIDL, {
+      ...packerOptions,
+      projectType: ProjectType.NEXT_CSS_MODULES,
+    })
+    console.info(ProjectType.NEXT_CSS_MODULES, '-', result.payload)
+    result = await packProject(projectUIDL, {
+      ...packerOptions,
+      projectType: ProjectType.NEXT_REACT_JSS,
+    })
+    console.info(ProjectType.NEXT_REACT_JSS, '-', result.payload)
+    result = await packProject(projectUIDL, {
+      ...packerOptions,
+      projectType: ProjectType.NEXT_STYLED_COMPONENTS,
+    })
+    console.info(ProjectType.NEXT_STYLED_COMPONENTS, '-', result.payload)
     result = await packProject(projectUIDL, { ...packerOptions, projectType: ProjectType.NUXT })
     console.info(ProjectType.NUXT, '-', result.payload)
     result = await packProject(projectUIDL, { ...packerOptions, projectType: ProjectType.VUE })
@@ -76,6 +91,11 @@ const run = async () => {
       projectType: ProjectType.GATSBY,
     })
     console.info(ProjectType.GATSBY, '-', result.payload)
+    result = await packProject(reactProjectUIDL, {
+      ...packerOptions,
+      projectType: ProjectType.GATSBY_STYLED_COMPONENTS,
+    })
+    console.info(ProjectType.GATSBY_STYLED_COMPONENTS, '-', result.payload)
   } catch (e) {
     console.info(e)
   }
diff --git a/packages/teleport-uidl-resolver/__tests__/reusable-styles/index.ts b/packages/teleport-uidl-resolver/__tests__/referenced-styles/index.ts
similarity index 61%
rename from packages/teleport-uidl-resolver/__tests__/reusable-styles/index.ts
rename to packages/teleport-uidl-resolver/__tests__/referenced-styles/index.ts
index 2a3b3e90..224aa0c4 100644
--- a/packages/teleport-uidl-resolver/__tests__/reusable-styles/index.ts
+++ b/packages/teleport-uidl-resolver/__tests__/referenced-styles/index.ts
@@ -1,3 +1,4 @@
+import { UIDLStyleMediaQueryScreenSizeCondition } from '@teleporthq/teleport-types'
 import { component, elementNode, staticNode } from '@teleporthq/teleport-uidl-builders'
 import { resolveReferencedStyle } from '../../src/resolvers/referenced-styles'
 
@@ -9,10 +10,10 @@ describe('Resolves referenced styles and sorts media styles in order', () => {
     const referencedStyles = {
       '5ed66ec0b98ab344e6299c7d': {
         id: '5ed66ec0b98ab344e6299c7d',
-        type: 'style-map',
+        type: 'style-map' as const,
         content: {
-          mapType: 'inlined',
-          conditions: [{ conditionType: 'screen-size', maxWidth: 767 }],
+          mapType: 'inlined' as const,
+          conditions: [{ conditionType: 'screen-size' as const, maxWidth: 767 }],
           styles: {
             display: staticNode('block'),
           },
@@ -20,10 +21,10 @@ describe('Resolves referenced styles and sorts media styles in order', () => {
       },
       '5ed66ec0b98ab344e6299c7c': {
         id: '5ed66ec0b98ab344e6299c7c',
-        type: 'style-map',
+        type: 'style-map' as const,
         content: {
-          mapType: 'inlined',
-          conditions: [{ conditionType: 'screen-size', maxWidth: 991 }],
+          mapType: 'inlined' as const,
+          conditions: [{ conditionType: 'screen-size' as const, maxWidth: 991 }],
           styles: {
             display: staticNode('block'),
           },
@@ -35,7 +36,11 @@ describe('Resolves referenced styles and sorts media styles in order', () => {
     resolveReferencedStyle(uidl)
     const styles = Object.values(uidl.node.content.referencedStyles)
 
-    expect(styles[0].content.conditions[0].maxWidth).toBe(991)
-    expect(styles[1].content.conditions[0].maxWidth).toBe(767)
+    expect(
+      (styles[0].content.conditions[0] as UIDLStyleMediaQueryScreenSizeCondition).maxWidth
+    ).toBe(991)
+    expect(
+      (styles[1].content.conditions[0] as UIDLStyleMediaQueryScreenSizeCondition).maxWidth
+    ).toBe(767)
   })
 })
diff --git a/packages/teleport-uidl-resolver/__tests__/style-set-definitions/index.ts b/packages/teleport-uidl-resolver/__tests__/style-set-definitions/index.ts
new file mode 100644
index 00000000..244c6a3f
--- /dev/null
+++ b/packages/teleport-uidl-resolver/__tests__/style-set-definitions/index.ts
@@ -0,0 +1,81 @@
+import { resolveStyleSetDefinitions } from '../../src/resolvers/style-set-definitions'
+import { staticNode } from '@teleporthq/teleport-uidl-builders'
+import { UIDLStyleSetDefinition, UIDLStyleSetMediaCondition } from '@teleporthq/teleport-types'
+
+describe('Resolves style-sheet', () => {
+  const styleSheet: Record<string, UIDLStyleSetDefinition> = {
+    '5ed66ec0b98ab344e6299c7d': {
+      id: '5ed66ec0b98ab344e6299c7d',
+      name: 'primaryButton',
+      type: 'reusable-project-style-map' as const,
+      conditions: [
+        {
+          type: 'screen-size' as const,
+          content: {
+            display: staticNode('block'),
+          },
+          meta: {
+            maxWidth: 767,
+          },
+        },
+        {
+          type: 'screen-size' as const,
+          content: {
+            display: staticNode('none'),
+          },
+          meta: {
+            maxWidth: 991,
+          },
+        },
+      ],
+      content: {
+        display: staticNode('block'),
+      },
+    },
+    '5ed66ec0b98ab344e6299c7c': {
+      id: '5ed66ec0b98ab344e6299c7c',
+      name: 'secondaryButton',
+      type: 'reusable-project-style-map' as const,
+      conditions: [
+        {
+          type: 'screen-size' as const,
+          content: {
+            display: staticNode('block'),
+          },
+          meta: {
+            maxWidth: 767,
+          },
+        },
+        {
+          type: 'screen-size' as const,
+          content: {
+            display: staticNode('none'),
+          },
+          meta: {
+            maxWidth: 991,
+          },
+        },
+      ],
+      content: {
+        display: staticNode('block'),
+      },
+    },
+  }
+
+  it('Sorts the style-sheet in order', () => {
+    const result = resolveStyleSetDefinitions(styleSheet)
+
+    expect(
+      (result['5ed66ec0b98ab344e6299c7d'].conditions[0] as UIDLStyleSetMediaCondition).meta.maxWidth
+    ).toBe(991)
+    expect(
+      (result['5ed66ec0b98ab344e6299c7d'].conditions[1] as UIDLStyleSetMediaCondition).meta.maxWidth
+    ).toBe(767)
+    expect(
+      (result['5ed66ec0b98ab344e6299c7c'].conditions[0] as UIDLStyleSetMediaCondition).meta.maxWidth
+    ).toBe(991)
+    expect(
+      (result['5ed66ec0b98ab344e6299c7c'].conditions[1] as UIDLStyleSetMediaCondition).meta.maxWidth
+    ).toBe(767)
+  })
+})