diff --git a/Generator/Package.swift b/Generator/Package.swift
index f85e6cc4..915889b1 100644
--- a/Generator/Package.swift
+++ b/Generator/Package.swift
@@ -1,8 +1,8 @@
-// swift-tools-version:5.1
+// swift-tools-version:5.5
 import PackageDescription
 
 // Based on https://github.com/apple/swift-syntax#readme
-#if swift(>=5.6) && swift(<5.7)
+#if swift(>=5.6) && swift(<5.8)
 let swiftSyntaxVersion: Version = "0.50600.1"
 #elseif swift(>=5.5)
 let swiftSyntaxVersion: Version = "0.50500.0"
@@ -47,7 +47,7 @@ let package = Package(
             exclude: [
                 "Fixtures",
             ]),
-        .target(
+        .executableTarget(
             name: "needle",
             dependencies: [
                 "NeedleFramework",
diff --git a/Generator/Sources/NeedleFramework/Generating/DependencyGraphExporter.swift b/Generator/Sources/NeedleFramework/Generating/DependencyGraphExporter.swift
index 9283bc58..2a5b524f 100644
--- a/Generator/Sources/NeedleFramework/Generating/DependencyGraphExporter.swift
+++ b/Generator/Sources/NeedleFramework/Generating/DependencyGraphExporter.swift
@@ -46,13 +46,15 @@ class DependencyGraphExporter {
     func export(_ components: [Component], with imports: [String], to path: String, using executor: SequenceExecutor, withTimeout timeout: TimeInterval, include headerDocPath: String?) throws {
         // Enqueue tasks.
         let taskHandleTuples = enqueueExportDependencyProviders(for: components, using: executor)
+        let dynamicTtaskHandleTuples = enqueueExportDynamicDependencyProviders(for: components, using: executor)
         let headerDocContentHandle = try enqueueLoadHeaderDoc(from: headerDocPath, using: executor)
 
         // Wait for execution to complete.
         let providers = try awaitSerialization(using: taskHandleTuples, withTimeout: timeout)
+        let dynamicProviders = try awaitSerialization(using: dynamicTtaskHandleTuples, withTimeout: timeout)
         let headerDocContent = try headerDocContentHandle?.await(withTimeout: timeout) ?? ""
 
-        let fileContents = OutputSerializer(providers: providers, imports: imports, headerDocContent: headerDocContent).serialize()
+        let fileContents = OutputSerializer(providers: providers, dynamicProviders: dynamicProviders, imports: imports, headerDocContent: headerDocContent).serialize()
         let currentFileContents = try? String(contentsOfFile: path, encoding: .utf8)
         guard currentFileContents != fileContents else {
             info("Not writing the file as content is unchanged")
@@ -96,6 +98,28 @@ class DependencyGraphExporter {
 
         return taskHandleTuples
     }
+    
+    private func enqueueExportDynamicDependencyProviders(for components: [Component], using executor: SequenceExecutor) -> [(SequenceExecutionHandle<[SerializedProvider]>, String)] {
+
+        var taskHandleTuples = [(handle: SequenceExecutionHandle<[SerializedProvider]>, componentName: String)]()
+        for component in components {
+            let initialTask = DependencyProviderDeclarerTask(component: component)
+            let taskHandle = executor.executeSequence(from: initialTask) { (currentTask: Task, currentResult: Any) -> SequenceExecution<[SerializedProvider]> in
+                if currentTask is DependencyProviderDeclarerTask, let providers = currentResult as? [DependencyProvider] {
+                    return .continueSequence(PluginizedDependencyProviderContentTask(providers: providers, pluginizedComponents: []))
+                } else if currentTask is PluginizedDependencyProviderContentTask, let processedProviders = currentResult as? [PluginizedProcessedDependencyProvider] {
+                    return .continueSequence(PluginizedDynamicDependencyProviderSerializerTask(component: component, providers: processedProviders))
+                } else if currentTask is PluginizedDynamicDependencyProviderSerializerTask, let serializedProviders = currentResult as? [SerializedProvider] {
+                    return .endOfSequence(serializedProviders)
+                } else {
+                    error("Unhandled task \(currentTask) with result \(currentResult)")
+                }
+            }
+            taskHandleTuples.append((taskHandle, component.name))
+        }
+
+        return taskHandleTuples
+    }
 
     private func awaitSerialization(using taskHandleTuples: [(SequenceExecutionHandle<[SerializedProvider]>, String)], withTimeout timeout: TimeInterval) throws -> [SerializedProvider] {
         // Wait for all the generation to complete so we can write all the output into a single file
diff --git a/Generator/Sources/NeedleFramework/Generating/Pluginized/PluginExtensionDynamicSerializerTask.swift b/Generator/Sources/NeedleFramework/Generating/Pluginized/PluginExtensionDynamicSerializerTask.swift
new file mode 100644
index 00000000..a7a25c20
--- /dev/null
+++ b/Generator/Sources/NeedleFramework/Generating/Pluginized/PluginExtensionDynamicSerializerTask.swift
@@ -0,0 +1,44 @@
+//
+//  Copyright (c) 2018. Uber Technologies
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//  http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+
+import Concurrency
+import Foundation
+
+/// The task that generates the declaration and registration of the
+/// plugin extension provider for a specific pluginized component.
+class PluginExtensionDynamicSerializerTask : AbstractTask<SerializedProvider> {
+
+    /// Initializer.
+    ///
+    /// - parameter component: The pluginized component that requires the
+    /// plugin extension provider.
+    init(component: PluginizedComponent) {
+        self.component = component
+        super.init(id: TaskIds.pluginExtensionSerializerTask.rawValue)
+    }
+
+    /// Execute the task and returns the data model.
+    ///
+    /// - returns: The `SerializedProvider`.
+    override func execute() -> SerializedProvider {
+        let content = PluginExtensionDynamicContentSerializer(component: component).serialize()
+        return SerializedProvider(content: content, registration: "", attributes: ProviderAttributes())
+    }
+
+    // MARK: - Private
+
+    private let component: PluginizedComponent
+}
diff --git a/Generator/Sources/NeedleFramework/Generating/Pluginized/PluginizedDependencyGraphExporter.swift b/Generator/Sources/NeedleFramework/Generating/Pluginized/PluginizedDependencyGraphExporter.swift
index c94705b6..104c8ba2 100644
--- a/Generator/Sources/NeedleFramework/Generating/Pluginized/PluginizedDependencyGraphExporter.swift
+++ b/Generator/Sources/NeedleFramework/Generating/Pluginized/PluginizedDependencyGraphExporter.swift
@@ -48,14 +48,17 @@ class PluginizedDependencyGraphExporter {
     func export(_ components: [Component], _ pluginizedComponents: [PluginizedComponent], with imports: [String], to path: String, using executor: SequenceExecutor, withTimeout timeout: TimeInterval, include headerDocPath: String?, needleVersionHash: String?) throws {
         // Enqueue tasks.
         let dependencyProviderHandleTuples = enqueueExportDependencyProviders(for: components, pluginizedComponents, using: executor)
+        let dynamicDependencyProviderHandleTuples = enqueueExportDynamicDependencyProviders(for: components, pluginizedComponents, using: executor)
         let pluginExtensionHandleTuples = enqueueExportPluginExtensions(for: pluginizedComponents, using: executor)
+        let dynamicpluginExtensionHandleTuples = enqueueExportDynamicPluginExtensions(for: pluginizedComponents, using: executor)
         let headerDocContentHandle = enqueueLoadHeaderDoc(from: headerDocPath, using: executor)
 
         // Wait for execution to complete.
         let serializedProviders = try awaitSerialization(using: dependencyProviderHandleTuples + pluginExtensionHandleTuples, withTimeout: timeout)
+        let serializedDynamicProviders = try awaitSerialization(using: dynamicDependencyProviderHandleTuples + dynamicpluginExtensionHandleTuples, withTimeout: timeout)
         let headerDocContent = try headerDocContentHandle?.await(withTimeout: timeout) ?? ""
 
-        let fileContents = OutputSerializer(providers: serializedProviders, imports: imports, headerDocContent: headerDocContent, needleVersionHash: needleVersionHash).serialize()
+        let fileContents = OutputSerializer(providers: serializedProviders, dynamicProviders: serializedDynamicProviders, imports: imports, headerDocContent: headerDocContent, needleVersionHash: needleVersionHash).serialize()
         let currentFileContents = try? String(contentsOfFile: path, encoding: .utf8)
         guard currentFileContents != fileContents else {
             info("Not writing the file as content is unchanged")
@@ -104,6 +107,33 @@ class PluginizedDependencyGraphExporter {
         return taskHandleTuples
     }
 
+    private func enqueueExportDynamicDependencyProviders(for components: [Component], _ pluginizedComponents: [PluginizedComponent], using executor: SequenceExecutor) -> [(SequenceExecutionHandle<[SerializedProvider]>, String)] {
+        let pluginizedData = pluginizedComponents.map { (component: PluginizedComponent) -> Component in
+            component.data
+        }
+        let allComponents = components + pluginizedData
+
+        var taskHandleTuples = [(handle: SequenceExecutionHandle<[SerializedProvider]>, componentName: String)]()
+        for component in allComponents {
+            let initialTask = DependencyProviderDeclarerTask(component: component)
+            let taskHandle = executor.executeSequence(from: initialTask) { (currentTask: Task, currentResult: Any) -> SequenceExecution<[SerializedProvider]> in
+                if currentTask is DependencyProviderDeclarerTask, let providers = currentResult as? [DependencyProvider] {
+                    return .continueSequence(PluginizedDependencyProviderContentTask(providers: providers, pluginizedComponents: pluginizedComponents))
+                } else if currentTask is PluginizedDependencyProviderContentTask, let processedProviders = currentResult as? [PluginizedProcessedDependencyProvider] {
+                    return .continueSequence(PluginizedDynamicDependencyProviderSerializerTask(component: component, providers: processedProviders))
+                } else if currentTask is PluginizedDynamicDependencyProviderSerializerTask, let serializedProviders = currentResult as? [SerializedProvider] {
+                    return .endOfSequence(serializedProviders)
+                } else {
+                    error("Unhandled task \(currentTask) with result \(currentResult)")
+                }
+            }
+            taskHandleTuples.append((taskHandle, component.name))
+        }
+
+        return taskHandleTuples
+    }
+
+    
     private func enqueueExportPluginExtensions(for pluginizedComponents: [PluginizedComponent], using executor: SequenceExecutor) -> [(SequenceExecutionHandle<[SerializedProvider]>, String)] {
         var taskHandleTuples = [(handle: SequenceExecutionHandle<[SerializedProvider]>, pluginExtensionName: String)]()
         for component in pluginizedComponents {
@@ -117,6 +147,19 @@ class PluginizedDependencyGraphExporter {
         return taskHandleTuples
     }
 
+    private func enqueueExportDynamicPluginExtensions(for pluginizedComponents: [PluginizedComponent], using executor: SequenceExecutor) -> [(SequenceExecutionHandle<[SerializedProvider]>, String)] {
+        var taskHandleTuples = [(handle: SequenceExecutionHandle<[SerializedProvider]>, pluginExtensionName: String)]()
+        for component in pluginizedComponents {
+            let task = PluginExtensionDynamicSerializerTask(component: component)
+            let taskHandle = executor.executeSequence(from: task) { (currentTask: Task, currentResult: Any) -> SequenceExecution<[SerializedProvider]> in
+                return .endOfSequence([currentResult as! SerializedProvider])
+            }
+            taskHandleTuples.append((taskHandle, component.pluginExtension.name))
+        }
+
+        return taskHandleTuples
+    }
+
     private func awaitSerialization(using taskHandleTuples: [(SequenceExecutionHandle<[SerializedProvider]>, String)], withTimeout timeout: TimeInterval) throws -> [SerializedProvider] {
         var providers = [SerializedProvider]()
         var isMissingDependencies = false
diff --git a/Generator/Sources/NeedleFramework/Generating/Pluginized/PluginizedDynamicDependencyProviderSerializerTask.swift b/Generator/Sources/NeedleFramework/Generating/Pluginized/PluginizedDynamicDependencyProviderSerializerTask.swift
new file mode 100644
index 00000000..40ac4e22
--- /dev/null
+++ b/Generator/Sources/NeedleFramework/Generating/Pluginized/PluginizedDynamicDependencyProviderSerializerTask.swift
@@ -0,0 +1,51 @@
+//
+//  Copyright (c) 2018. Uber Technologies
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//  http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+
+import Concurrency
+import Foundation
+
+/// The task that serializes a list of pluginized processed dependency
+/// providers into exportable foramt.
+class PluginizedDynamicDependencyProviderSerializerTask: AbstractTask<[SerializedProvider]> {
+
+    /// Initializer.
+    ///
+    /// - parameter providers: The pluginized processed dependency provider
+    /// to serialize.
+    init(component: Component, providers: [PluginizedProcessedDependencyProvider]) {
+        self.component = component
+        self.providers = providers
+        super.init(id: TaskIds.pluginizedDependencyProviderSerializerTask.rawValue)
+    }
+
+    /// Execute the task and returns the in-memory serialized dependency
+    /// provider data models.
+    ///
+    /// - returns: The list of `SerializedProvider`.
+    override func execute() -> [SerializedProvider] {
+        guard !providers.isEmpty else {
+            return []
+        }
+        let serilizer = DependencyPropsSerializer(component: component)
+        let result = SerializedProvider(content: serilizer.serialize(), registration: "", attributes: ProviderAttributes())
+        return [result]
+    }
+
+    // MARK: - Private
+
+    private let component: Component
+    private let providers: [PluginizedProcessedDependencyProvider]
+}
diff --git a/Generator/Sources/NeedleFramework/Generating/Serializers/DependencyPropsSerializer.swift b/Generator/Sources/NeedleFramework/Generating/Serializers/DependencyPropsSerializer.swift
new file mode 100644
index 00000000..7d2d3ed3
--- /dev/null
+++ b/Generator/Sources/NeedleFramework/Generating/Serializers/DependencyPropsSerializer.swift
@@ -0,0 +1,67 @@
+//
+//  Copyright (c) 2018. Uber Technologies
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//  http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+
+import Foundation
+
+class DependencyPropsSerializer: Serializer {
+    
+    init(component: Component) {
+        self.component = component
+    }
+    
+    func serialize() -> String {
+        if component.isLeaf {
+            return """
+extension \(component.name): Registration {
+    public func registerItems() {
+\(serialize(component.dependency))
+    }
+}
+
+"""
+        } else {
+            return """
+extension \(component.name): Registration {
+    public func registerItems() {
+\(serialize(component.dependency))
+\(serialize(component.properties))
+    }
+}
+
+"""
+        }
+    }
+
+    // MARK: - Private
+
+    private func serialize(_ dependency: Dependency) -> String {
+        let dependencyName = dependency.name
+        return dependency.properties.map { property in
+            return "        keyPathToName[\\\(dependencyName).\(property.name)] = \"\(property.name)-\(property.type)\""
+        }.joined(separator: "\n")
+    }
+
+    private func serialize(_ properties: [Property]) -> String {
+        return properties.filter { property in
+            !property.isInternal
+        }.map { property in
+            return "        localTable[\"\(property.name)-\(property.type)\"] = { self.\(property.name) as Any }"
+        }.joined(separator: "\n")
+    }
+
+    private let component: Component
+}
+
diff --git a/Generator/Sources/NeedleFramework/Generating/Serializers/OutputSerializer.swift b/Generator/Sources/NeedleFramework/Generating/Serializers/OutputSerializer.swift
index fb051a88..7f8e5393 100644
--- a/Generator/Sources/NeedleFramework/Generating/Serializers/OutputSerializer.swift
+++ b/Generator/Sources/NeedleFramework/Generating/Serializers/OutputSerializer.swift
@@ -26,8 +26,9 @@ class OutputSerializer: Serializer {
     /// - parameter imports: The list of import statements to include.
     /// - parameter headerDocContent: The content of the header doc to
     /// include at the top of the output file.
-    init(providers: [SerializedProvider], imports: [String], headerDocContent: String, needleVersionHash: String? = nil) {
+    init(providers: [SerializedProvider], dynamicProviders: [SerializedProvider], imports: [String], headerDocContent: String, needleVersionHash: String? = nil) {
         self.providers = providers
+        self.dynamicProviders = dynamicProviders
         self.imports = imports
         self.headerDocContent = headerDocContent
         self.needleVersionHash = needleVersionHash
@@ -61,6 +62,10 @@ class OutputSerializer: Serializer {
             }
             .joined()
 
+        let dynamicProvidersSection = dynamicProviders
+            .map { (provider: SerializedProvider) in provider.content }
+            .joined()
+    
         let traversalHelpers = (1...maxLevel).map { num in
             return """
             private func parent\(num)(_ component: NeedleFoundation.Scope) -> NeedleFoundation.Scope {
@@ -119,8 +124,14 @@ class OutputSerializer: Serializer {
 
         // MARK: - Providers
 
+        #if !NEEDLE_DYNAMIC
+        
         \(providersSection)
-
+        #else
+        \(dynamicProvidersSection)
+        
+        #endif
+        
         private func factoryEmptyDependencyProvider(_ component: NeedleFoundation.Scope) -> AnyObject {
             return EmptyDependencyProvider(component: component)
         }
@@ -130,10 +141,15 @@ class OutputSerializer: Serializer {
             __DependencyProviderRegistry.instance.registerDependencyProviderFactory(for: componentPath, factory)
         }
 
+        #if !NEEDLE_DYNAMIC
+        
         \(registrationHelpers)
-
+        #endif
+        
         public func registerProviderFactories() {
+        #if !NEEDLE_DYNAMIC
             \(registrationBody)
+        #endif
         }
 
         """
@@ -142,6 +158,7 @@ class OutputSerializer: Serializer {
     // MARK: - Private
 
     private let providers: [SerializedProvider]
+    private let dynamicProviders: [SerializedProvider]
     private let imports: [String]
     private let headerDocContent: String
     private let needleVersionHash: String?
diff --git a/Generator/Sources/NeedleFramework/Generating/Serializers/Pluginized/PluginExtensionDynamicContentSerializer.swift b/Generator/Sources/NeedleFramework/Generating/Serializers/Pluginized/PluginExtensionDynamicContentSerializer.swift
new file mode 100644
index 00000000..e0ee0714
--- /dev/null
+++ b/Generator/Sources/NeedleFramework/Generating/Serializers/Pluginized/PluginExtensionDynamicContentSerializer.swift
@@ -0,0 +1,57 @@
+//
+//  Copyright (c) 2018. Uber Technologies
+//
+//  Licensed under the Apache License, Version 2.0 (the "License");
+//  you may not use this file except in compliance with the License.
+//  You may obtain a copy of the License at
+//
+//  http://www.apache.org/licenses/LICENSE-2.0
+//
+//  Unless required by applicable law or agreed to in writing, software
+//  distributed under the License is distributed on an "AS IS" BASIS,
+//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+//  See the License for the specific language governing permissions and
+//  limitations under the License.
+//
+
+import Foundation
+
+/// A serializer that produces the class definitation source code for the
+/// plugin extension provider.
+class PluginExtensionDynamicContentSerializer: Serializer {
+
+    /// Initializer.
+    ///
+    /// - parameter component: The pluginized component for which is associated
+    ///   with this plugin extension
+    init(component: PluginizedComponent) {
+        self.component = component
+    }
+
+    /// Serialize the data model and produce the source code.
+    ///
+    /// - returns: The plugin extension class implemention source code.
+    func serialize() -> String {
+        let properties = serialize(properties: component.pluginExtension.properties)
+        
+        return """
+        /// \(component.data.name) plugin extension
+        extension \(component.data.name): ExtensionRegistration {
+            public func registerExtensionItems() {
+        \(properties)
+            }
+        }
+
+        """
+    }
+    
+    func serialize(properties: [Property]) -> String {
+        return properties.map { property in
+            return "        extensionToName[\\\(component.pluginExtension.name).\(property.name)] = \"\(property.name)-\(property.type)\""
+        }.joined(separator: "\n")
+    }
+
+    // MARK: - Private
+
+    private let component: PluginizedComponent
+}