diff --git a/plugin-vue/locker/pom.xml b/plugin-vue/locker/pom.xml
new file mode 100644
index 0000000..1637193
--- /dev/null
+++ b/plugin-vue/locker/pom.xml
@@ -0,0 +1,592 @@
+
+
+ 4.0.0
+
+ io.mvnpm
+ esbuild-java-parent
+ 999-SNAPSHOT
+ ..\..\pom.xml
+
+ esbuild-java-plugin-vue-locker
+ pom
+
+
+
+
+
+
+ org.mvnpm.at.babel
+ helper-string-parser
+ 7.27.1
+
+
+ org.mvnpm.at.babel
+ helper-validator-identifier
+ 7.28.5
+
+
+ org.mvnpm.at.babel
+ parser
+ 7.29.2
+
+
+ org.mvnpm.at.babel
+ types
+ 7.29.0
+
+
+ org.mvnpm.at.deno
+ win32-x64
+ 2.5.4
+
+
+ org.mvnpm.at.esbuild
+ win32-x64
+ 0.25.10
+
+
+ org.mvnpm.at.jridgewell
+ sourcemap-codec
+ 1.5.5
+
+
+ org.mvnpm.at.vue
+ compiler-core
+ 3.5.32
+
+
+ org.mvnpm.at.vue
+ compiler-dom
+ 3.5.32
+
+
+ org.mvnpm.at.vue
+ compiler-sfc
+ 3.5.32
+
+
+ org.mvnpm.at.vue
+ compiler-ssr
+ 3.5.32
+
+
+ org.mvnpm.at.vue
+ reactivity
+ 3.5.32
+
+
+ org.mvnpm.at.vue
+ runtime-core
+ 3.5.32
+
+
+ org.mvnpm.at.vue
+ runtime-dom
+ 3.5.32
+
+
+ org.mvnpm.at.vue
+ server-renderer
+ 3.5.32
+
+
+ org.mvnpm.at.vue
+ shared
+ 3.5.32
+
+
+ org.mvnpm
+ acorn
+ 7.4.1
+
+
+ org.mvnpm
+ asap
+ 2.0.6
+
+
+ org.mvnpm
+ assert-never
+ 1.4.0
+
+
+ org.mvnpm
+ async-function
+ 1.0.0
+
+
+ org.mvnpm
+ async-generator-function
+ 1.0.0
+
+
+ org.mvnpm
+ babel-walk
+ 3.0.0-canary-5
+
+
+ org.mvnpm
+ boolbase
+ 1.0.0
+
+
+ org.mvnpm
+ call-bind-apply-helpers
+ 1.0.2
+
+
+ org.mvnpm
+ call-bound
+ 1.0.4
+
+
+ org.mvnpm
+ camel-case
+ 3.0.0
+
+
+ org.mvnpm
+ character-parser
+ 2.2.0
+
+
+ org.mvnpm
+ cheerio-select
+ 2.1.0
+
+
+ org.mvnpm
+ cheerio
+ 1.2.0
+
+
+ org.mvnpm
+ chokidar
+ 4.0.3
+
+
+ org.mvnpm
+ clean-css
+ 4.2.4
+
+
+ org.mvnpm
+ commander
+ 2.20.3
+
+
+ org.mvnpm
+ constantinople
+ 4.0.1
+
+
+ org.mvnpm
+ css-select
+ 5.2.2
+
+
+ org.mvnpm
+ css-what
+ 6.2.2
+
+
+ org.mvnpm
+ csstype
+ 3.2.3
+
+
+ org.mvnpm
+ doctypes
+ 1.1.0
+
+
+ org.mvnpm
+ dom-serializer
+ 2.0.0
+
+
+ org.mvnpm
+ domelementtype
+ 2.3.0
+
+
+ org.mvnpm
+ domhandler
+ 5.0.3
+
+
+ org.mvnpm
+ domutils
+ 3.2.2
+
+
+ org.mvnpm
+ dunder-proto
+ 1.0.1
+
+
+ org.mvnpm
+ encoding-sniffer
+ 0.2.1
+
+
+ org.mvnpm
+ entities
+ 7.0.1
+
+
+ org.mvnpm
+ es-define-property
+ 1.0.1
+
+
+ org.mvnpm
+ es-errors
+ 1.3.0
+
+
+ org.mvnpm
+ es-object-atoms
+ 1.1.1
+
+
+ org.mvnpm
+ esbuild-plugin-vue3
+ 0.5.1
+
+
+ org.mvnpm
+ esbuild
+ 0.25.10
+
+
+ org.mvnpm
+ estree-walker
+ 2.0.2
+
+
+ org.mvnpm
+ function-bind
+ 1.1.2
+
+
+ org.mvnpm
+ generator-function
+ 2.0.1
+
+
+ org.mvnpm
+ get-intrinsic
+ 1.3.1
+
+
+ org.mvnpm
+ get-proto
+ 1.0.1
+
+
+ org.mvnpm
+ gopd
+ 1.2.0
+
+
+ org.mvnpm
+ has-symbols
+ 1.1.0
+
+
+ org.mvnpm
+ has-tostringtag
+ 1.0.2
+
+
+ org.mvnpm
+ hasown
+ 2.0.2
+
+
+ org.mvnpm
+ he
+ 1.2.0
+
+
+ org.mvnpm
+ html-minifier
+ 4.0.0
+
+
+ org.mvnpm
+ htmlparser2
+ 10.1.0
+
+
+ org.mvnpm
+ iconv-lite
+ 0.6.3
+
+
+ org.mvnpm
+ immutable
+ 5.1.5
+
+
+ org.mvnpm
+ is-core-module
+ 2.16.1
+
+
+ org.mvnpm
+ is-expression
+ 4.0.0
+
+
+ org.mvnpm
+ is-promise
+ 2.2.2
+
+
+ org.mvnpm
+ is-regex
+ 1.2.1
+
+
+ org.mvnpm
+ js-stringify
+ 1.0.2
+
+
+ org.mvnpm
+ jstransformer
+ 1.0.0
+
+
+ org.mvnpm
+ lower-case
+ 1.1.4
+
+
+ org.mvnpm
+ magic-string
+ 0.30.21
+
+
+ org.mvnpm
+ math-intrinsics
+ 1.1.0
+
+
+ org.mvnpm
+ nanoid
+ 3.3.11
+
+
+ org.mvnpm
+ no-case
+ 2.3.2
+
+
+ org.mvnpm
+ nth-check
+ 2.1.1
+
+
+ org.mvnpm
+ object-assign
+ 4.1.1
+
+
+ org.mvnpm
+ param-case
+ 2.1.1
+
+
+ org.mvnpm
+ parse5-htmlparser2-tree-adapter
+ 7.1.0
+
+
+ org.mvnpm
+ parse5-parser-stream
+ 7.1.2
+
+
+ org.mvnpm
+ parse5
+ 7.3.0
+
+
+ org.mvnpm
+ path-parse
+ 1.0.7
+
+
+ org.mvnpm
+ picocolors
+ 1.1.1
+
+
+ org.mvnpm
+ postcss
+ 8.5.9
+
+
+ org.mvnpm
+ promise
+ 7.3.1
+
+
+ org.mvnpm
+ pug-attrs
+ 3.0.0
+
+
+ org.mvnpm
+ pug-code-gen
+ 3.0.4
+
+
+ org.mvnpm
+ pug-error
+ 2.1.0
+
+
+ org.mvnpm
+ pug-filters
+ 4.0.0
+
+
+ org.mvnpm
+ pug-lexer
+ 5.0.1
+
+
+ org.mvnpm
+ pug-linker
+ 4.0.0
+
+
+ org.mvnpm
+ pug-load
+ 3.0.0
+
+
+ org.mvnpm
+ pug-parser
+ 6.0.0
+
+
+ org.mvnpm
+ pug-runtime
+ 3.0.1
+
+
+ org.mvnpm
+ pug-strip-comments
+ 2.0.0
+
+
+ org.mvnpm
+ pug-walk
+ 2.0.0
+
+
+ org.mvnpm
+ pug
+ 3.0.4
+
+
+ org.mvnpm
+ readdirp
+ 4.1.2
+
+
+ org.mvnpm
+ relateurl
+ 0.2.7
+
+
+ org.mvnpm
+ resolve
+ 1.22.11
+
+
+ org.mvnpm
+ safer-buffer
+ 2.1.2
+
+
+ org.mvnpm
+ sass
+ 1.99.0
+
+
+ org.mvnpm
+ source-map-js
+ 1.2.1
+
+
+ org.mvnpm
+ source-map
+ 0.6.1
+
+
+ org.mvnpm
+ supports-preserve-symlinks-flag
+ 1.0.0
+
+
+ org.mvnpm
+ token-stream
+ 1.0.0
+
+
+ org.mvnpm
+ typescript
+ 4.9.5
+
+
+ org.mvnpm
+ uglify-js
+ 3.19.3
+
+
+ org.mvnpm
+ undici
+ 7.24.7
+
+
+ org.mvnpm
+ upper-case
+ 1.1.3
+
+
+ org.mvnpm
+ void-elements
+ 3.1.0
+
+
+ org.mvnpm
+ vue
+ 3.5.32
+
+
+ org.mvnpm
+ whatwg-encoding
+ 3.1.1
+
+
+ org.mvnpm
+ whatwg-mimetype
+ 4.0.0
+
+
+ org.mvnpm
+ with
+ 7.0.2
+
+
+
+
diff --git a/plugin-vue/pom.xml b/plugin-vue/pom.xml
new file mode 100644
index 0000000..f76360e
--- /dev/null
+++ b/plugin-vue/pom.xml
@@ -0,0 +1,88 @@
+
+
+ 4.0.0
+
+ io.mvnpm
+ esbuild-java-parent
+ 999-SNAPSHOT
+
+ esbuild-java-plugin-vue
+ Esbuild Java - Plugin Vue
+ Vue plugin for Esbuild Java
+
+ 0.5.1
+
+
+
+ io.mvnpm
+ esbuild-java
+ ${project.version}
+
+
+ org.mvnpm
+ esbuild-plugin-vue3
+ ${esbuild-vue-plugin.version}
+
+
+
+ org.mvnpm
+ entities
+
+
+
+
+ org.mvnpm
+ entities
+ 7.0.1
+
+
+ io.mvnpm
+ esbuild-java-testing
+ ${project.version}
+ test
+
+
+
+
+
+ maven-surefire-plugin
+
+
+ net.revelc.code.formatter
+ formatter-maven-plugin
+
+
+ net.revelc.code
+ impsort-maven-plugin
+
+
+
+
+
+ locker
+
+
+ !unlocked
+
+
+
+
+
+ io.mvnpm
+ esbuild-java-plugin-vue-locker
+ ${project.version}
+ pom
+ import
+
+
+
+
+
+
diff --git a/plugin-vue/src/main/java/io/mvnpm/esbuild/plugin/EsBuildPluginVue.java b/plugin-vue/src/main/java/io/mvnpm/esbuild/plugin/EsBuildPluginVue.java
new file mode 100644
index 0000000..3dc1c57
--- /dev/null
+++ b/plugin-vue/src/main/java/io/mvnpm/esbuild/plugin/EsBuildPluginVue.java
@@ -0,0 +1,32 @@
+package io.mvnpm.esbuild.plugin;
+
+import io.mvnpm.esbuild.model.EsBuildPlugin;
+
+public class EsBuildPluginVue implements EsBuildPlugin {
+
+ @Override
+ public String name() {
+
+ return "vue";
+ }
+
+ @Override
+ public String importScript() {
+
+ return """
+ import vuePlugin from "esbuild-plugin-vue3";
+ """;
+ }
+
+ @Override
+ public String configurePlugin() {
+
+ // language=JavaScript
+ return """
+ (function (config, data) {
+ config.plugins.push(vuePlugin());
+ return config;
+ })
+ """;
+ }
+}
diff --git a/plugin-vue/src/test/java/io/mvnpm/esbuild/plugin/EsBuildPluginVueTest.java b/plugin-vue/src/test/java/io/mvnpm/esbuild/plugin/EsBuildPluginVueTest.java
new file mode 100644
index 0000000..ed90abc
--- /dev/null
+++ b/plugin-vue/src/test/java/io/mvnpm/esbuild/plugin/EsBuildPluginVueTest.java
@@ -0,0 +1,65 @@
+package io.mvnpm.esbuild.plugin;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.jupiter.api.Test;
+
+import io.mvnpm.esbuild.Bundler;
+import io.mvnpm.esbuild.model.BundleOptions;
+import io.mvnpm.esbuild.model.DevResult;
+import io.mvnpm.esbuild.model.EsBuildConfig;
+
+public class EsBuildPluginVueTest {
+
+ @Test
+ void shouldBundleWithVue() throws Exception {
+
+ // given
+ final Path root = prepareTest();
+ final BundleOptions options = BundleOptions.builder().withWorkDir(root)
+ .withEsConfig(EsBuildConfig.builder().entryNames("[name]").build()).addPlugin(new EsBuildPluginVue())
+ .addEntryPoint("app.js").build();
+
+ // when
+ Bundler.bundle(options, true);
+
+ // then
+ assertTrue(options.workDir().resolve("dist").resolve("app.js").toFile().exists());
+ assertTrue(options.workDir().resolve("dist").resolve("app.css").toFile().exists());
+ }
+
+ @Test
+ void shouldBundleInDevWithVue() throws Exception {
+
+ // given
+ final Path root = prepareTest();
+ final BundleOptions options = BundleOptions.builder().withWorkDir(root)
+ .withEsConfig(EsBuildConfig.builder().entryNames("[name]").build()).addPlugin(new EsBuildPluginVue())
+ .addEntryPoint("app.js").build();
+
+ // when
+ try (DevResult dev = Bundler.dev(options, true)) {
+
+ dev.process().build();
+ }
+
+ // then
+ assertTrue(options.workDir().resolve("dist").resolve("app.js").toFile().exists());
+ assertTrue(options.workDir().resolve("dist").resolve("app.css").toFile().exists());
+ }
+
+ static Path prepareTest() throws IOException, URISyntaxException {
+
+ final Path temp = Files.createTempDirectory("test-vue");
+ final Path root = new File(EsBuildPluginVueTest.class.getResource("/vue/").toURI()).toPath();
+ FileUtils.copyDirectory(root.toFile(), temp.toFile());
+ return temp;
+ }
+}
diff --git a/plugin-vue/src/test/resources/vue/SfcCompositionApiTs.vue b/plugin-vue/src/test/resources/vue/SfcCompositionApiTs.vue
new file mode 100644
index 0000000..d00812b
--- /dev/null
+++ b/plugin-vue/src/test/resources/vue/SfcCompositionApiTs.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
diff --git a/plugin-vue/src/test/resources/vue/SfcOptionsApiTs.vue b/plugin-vue/src/test/resources/vue/SfcOptionsApiTs.vue
new file mode 100644
index 0000000..33b3f4d
--- /dev/null
+++ b/plugin-vue/src/test/resources/vue/SfcOptionsApiTs.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/plugin-vue/src/test/resources/vue/app.js b/plugin-vue/src/test/resources/vue/app.js
new file mode 100644
index 0000000..53f0e0e
--- /dev/null
+++ b/plugin-vue/src/test/resources/vue/app.js
@@ -0,0 +1,6 @@
+import { createApp } from "vue";
+import SfcCompositionApi from "./SfcCompositionApiTs.vue";
+import SfcOptionsApi from "./SfcOptionsApiTs.vue";
+
+createApp(SfcCompositionApi).mount("#composition-api");
+createApp(SfcOptionsApi).mount("#options-api");
diff --git a/pom.xml b/pom.xml
index 242c492..a19c5b3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,6 +18,8 @@
plugin-svelte/locker
plugin-svelte
plugin-tailwind
+ plugin-vue/locker
+ plugin-vue
https://github.com/mvnpm/esbuild-java/