diff --git a/ultimate/resources/META-INF/kotlin-nodejs.xml b/ultimate/resources/META-INF/kotlin-nodejs.xml
index e8a8cd73eb2..6846e15c71d 100644
--- a/ultimate/resources/META-INF/kotlin-nodejs.xml
+++ b/ultimate/resources/META-INF/kotlin-nodejs.xml
@@ -5,5 +5,6 @@
+
diff --git a/ultimate/src/org/jetbrains/kotlin/idea/nodejs/cli/KotlinNodeJsRunConfigurationProducer.kt b/ultimate/src/org/jetbrains/kotlin/idea/nodejs/cli/KotlinNodeJsRunConfigurationProducer.kt
new file mode 100644
index 00000000000..25b2246a4d6
--- /dev/null
+++ b/ultimate/src/org/jetbrains/kotlin/idea/nodejs/cli/KotlinNodeJsRunConfigurationProducer.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
+ * that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.idea.nodejs.cli
+
+import com.intellij.execution.actions.ConfigurationContext
+import com.intellij.execution.actions.RunConfigurationProducer
+import com.intellij.openapi.util.Ref
+import com.intellij.openapi.util.io.FileUtil
+import com.intellij.psi.PsiElement
+import com.jetbrains.nodejs.run.NodeJsRunConfiguration
+import com.jetbrains.nodejs.run.NodeJsRunConfigurationType
+import org.jetbrains.kotlin.descriptors.FunctionDescriptor
+import org.jetbrains.kotlin.idea.MainFunctionDetector
+import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
+import org.jetbrains.kotlin.idea.js.jsOrJsImpl
+import org.jetbrains.kotlin.idea.js.jsProductionOutputFilePath
+import org.jetbrains.kotlin.idea.nodejs.TestElementPath
+import org.jetbrains.kotlin.idea.nodejs.getNodeJsEnvironmentVars
+import org.jetbrains.kotlin.idea.run.addBuildTask
+import org.jetbrains.kotlin.idea.util.module
+import org.jetbrains.kotlin.psi.KtNamedFunction
+
+private class KotlinNodeJsRunConfigurationProducer :
+ RunConfigurationProducer(NodeJsRunConfigurationType.getInstance()) {
+ private val ConfigurationContext?.isAcceptable: Boolean
+ get() {
+ val original = this?.getOriginalConfiguration(null)
+ return original == null || original is NodeJsRunConfiguration
+ }
+
+ override fun setupConfigurationFromContext(
+ configuration: NodeJsRunConfiguration,
+ context: ConfigurationContext,
+ sourceElement: Ref
+ ): Boolean {
+ if (!context.isAcceptable) return false
+
+ val psiElement = sourceElement.get() ?: return false
+ val psiFile = psiElement.containingFile
+ val jsModule = psiFile.module?.jsOrJsImpl() ?: return false
+ val project = psiFile.project
+
+ if (psiElement is KtNamedFunction) {
+ val detector = MainFunctionDetector { it.resolveToDescriptorIfAny() as? FunctionDescriptor }
+ if (!detector.isMain(psiElement, false)) return false
+ }
+ else if (!TestElementPath.isModuleAssociatedDir(psiElement, jsModule)) return false
+
+ val jsFilePath = jsModule.jsProductionOutputFilePath ?: return false
+
+ if (configuration.workingDirectory.isNullOrBlank()) {
+ configuration.workingDirectory = FileUtil.toSystemDependentName(project.baseDir.path)
+ }
+ configuration.inputPath = jsFilePath
+ configuration.envs = jsModule.getNodeJsEnvironmentVars().envs
+ configuration.setGeneratedName()
+ configuration.addBuildTask()
+
+ return true
+ }
+
+ override fun isConfigurationFromContext(configuration: NodeJsRunConfiguration, context: ConfigurationContext): Boolean {
+ if (!context.isAcceptable) return false
+
+ val contextPsi = context.psiLocation ?: return false
+ val jsModule = contextPsi.module?.jsOrJsImpl() ?: return false
+ val jsFilePath = jsModule.jsProductionOutputFilePath ?: return false
+ return configuration.inputPath == jsFilePath
+ }
+}
\ No newline at end of file