diff --git a/integration-tests/codestarts/pom.xml b/integration-tests/codestarts/pom.xml
new file mode 100644
index 0000000..ff145c3
--- /dev/null
+++ b/integration-tests/codestarts/pom.xml
@@ -0,0 +1,61 @@
+
+
+ 4.0.0
+
+
+ com.vaadin
+ vaadin-quarkus-integration-tests
+ 2.0-SNAPSHOT
+
+
+ vaadin-quarkus-codestarts-tests
+ Vaadin Quarkus - Codestarts tests
+ jar
+
+
+ true
+
+
+
+
+
+
+ com.vaadin
+ vaadin-quarkus
+ test
+
+
+
+ io.quarkus
+ quarkus-junit5
+ test
+
+
+ io.quarkus
+ quarkus-devtools-testing
+ test
+
+
+
+
+
+
+ io.quarkus
+ quarkus-maven-plugin
+
+
+
+ build
+
+
+
+
+
+ maven-failsafe-plugin
+
+
+
+
+
+
diff --git a/integration-tests/codestarts/src/test/java/com/vaadin/flow/quarkus/it/CodestartTestUtils.java b/integration-tests/codestarts/src/test/java/com/vaadin/flow/quarkus/it/CodestartTestUtils.java
new file mode 100644
index 0000000..9f10502
--- /dev/null
+++ b/integration-tests/codestarts/src/test/java/com/vaadin/flow/quarkus/it/CodestartTestUtils.java
@@ -0,0 +1,58 @@
+package com.vaadin.flow.quarkus.it;
+
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.PluginExecution;
+import org.apache.maven.model.RepositoryBase;
+import org.assertj.core.api.SoftAssertions;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+final class CodestartTestUtils {
+
+ static void assertThatHasVaadinBom(Model pom, SoftAssertions soft) {
+ soft.assertThat(pom.getDependencyManagement().getDependencies())
+ .filteredOn(dep -> "com.vaadin".equals(dep.getGroupId())
+ && "vaadin-bom".equals(dep.getArtifactId()))
+ .singleElement()
+ .extracting(Dependency::getType, Dependency::getScope)
+ .contains("pom", "import");
+ }
+
+ static void assertThatHasVaadinQuarkusExtension(Model pom,
+ SoftAssertions soft) {
+ soft.assertThat(pom.getDependencies())
+ .filteredOn(dep -> "com.vaadin".equals(dep.getGroupId())
+ && "vaadin-quarkus-extension"
+ .equals(dep.getArtifactId()))
+ .hasSize(1);
+ }
+
+ static void assertThatHasProductionProfile(Model pom, SoftAssertions soft) {
+ soft.assertThat(pom.getProfiles())
+ .filteredOn(dep -> "production".equals(dep.getId()))
+ .flatExtracting(profile -> profile.getBuild().getPlugins())
+ .filteredOn(plugin -> "com.vaadin".equals(plugin.getGroupId())
+ && "vaadin-maven-plugin".equals(plugin.getArtifactId()))
+ .singleElement()
+ .satisfies(plugin -> assertThat(plugin.getExecutions())
+ .flatMap(PluginExecution::getGoals)
+ .contains("prepare-frontend", "build-frontend"))
+ .extracting(Plugin::getVersion).isEqualTo("${vaadin.version}");
+ }
+
+ static void assertThatHasPreReleaseRepositories(Model pom,
+ SoftAssertions soft) {
+ soft.assertThat(pom.getRepositories())
+ .filteredOn(repo -> "vaadin-prereleases".equals(repo.getId()))
+ .singleElement().extracting(RepositoryBase::getUrl)
+ .isEqualTo("https://maven.vaadin.com/vaadin-prereleases/");
+ soft.assertThat(pom.getPluginRepositories())
+ .filteredOn(repo -> "vaadin-prereleases".equals(repo.getId()))
+ .singleElement().extracting(RepositoryBase::getUrl)
+ .isEqualTo("https://maven.vaadin.com/vaadin-prereleases/");
+
+ }
+
+}
diff --git a/integration-tests/codestarts/src/test/java/com/vaadin/flow/quarkus/it/VaadinExtensionBuildCodestartTest.java b/integration-tests/codestarts/src/test/java/com/vaadin/flow/quarkus/it/VaadinExtensionBuildCodestartTest.java
new file mode 100644
index 0000000..26ce439
--- /dev/null
+++ b/integration-tests/codestarts/src/test/java/com/vaadin/flow/quarkus/it/VaadinExtensionBuildCodestartTest.java
@@ -0,0 +1,32 @@
+package com.vaadin.flow.quarkus.it;
+
+import io.quarkus.devtools.codestarts.quarkus.QuarkusCodestartCatalog.Language;
+import io.quarkus.devtools.testing.codestarts.QuarkusCodestartTest;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+@EnabledIfSystemProperty(named = "vaadin.platform.version", matches = ".*", disabledReason = "Project should not have dependencies on platform. "
+ + "Vaadin platform version should be provided as system property to test code start build.")
+public class VaadinExtensionBuildCodestartTest {
+
+ @RegisterExtension
+ public static QuarkusCodestartTest codestartTest = QuarkusCodestartTest
+ .builder().languages(Language.JAVA)
+ .setupStandaloneExtensionTest("com.vaadin:vaadin-quarkus")
+ .putData("vaadin-flow-codestart.vaadinVersion",
+ System.getProperty("vaadin.platform.version"))
+ .build();
+
+ /**
+ * This test runs the build (with tests) on generated projects for all
+ * selected languages. To compile the source classes dependencies to vaadin
+ * platform artifacts are required. Use {@literal vaadin.platform.version}
+ * system property to provide a valid Vaadin platform version to enable the
+ * test, for example {@literal -Dvaadin.platform.version=24.1-SNAPSHOT}
+ */
+ @Test
+ void buildAllProjects() throws Throwable {
+ codestartTest.buildAllProjects();
+ }
+}
diff --git a/integration-tests/codestarts/src/test/java/com/vaadin/flow/quarkus/it/VaadinExtensionCodestartTest.java b/integration-tests/codestarts/src/test/java/com/vaadin/flow/quarkus/it/VaadinExtensionCodestartTest.java
new file mode 100644
index 0000000..a4bc7f0
--- /dev/null
+++ b/integration-tests/codestarts/src/test/java/com/vaadin/flow/quarkus/it/VaadinExtensionCodestartTest.java
@@ -0,0 +1,56 @@
+package com.vaadin.flow.quarkus.it;
+
+import java.util.Map;
+
+import io.quarkus.devtools.codestarts.quarkus.QuarkusCodestartCatalog.Language;
+import io.quarkus.devtools.testing.codestarts.QuarkusCodestartTest;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.DefaultModelReader;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import static com.vaadin.flow.quarkus.it.CodestartTestUtils.assertThatHasProductionProfile;
+import static com.vaadin.flow.quarkus.it.CodestartTestUtils.assertThatHasVaadinBom;
+import static com.vaadin.flow.quarkus.it.CodestartTestUtils.assertThatHasVaadinQuarkusExtension;
+import static io.quarkus.devtools.testing.SnapshotTesting.checkContains;
+import static org.assertj.core.api.SoftAssertions.assertSoftly;
+
+public class VaadinExtensionCodestartTest {
+
+ @RegisterExtension
+ public static QuarkusCodestartTest codestartTest = QuarkusCodestartTest
+ .builder().languages(Language.JAVA)
+ .setupStandaloneExtensionTest("com.vaadin:vaadin-quarkus")
+ .putData("vaadin-flow-codestart.vaadinVersion",
+ System.getProperty("vaadin.platform.version", "24.0.5"))
+ .build();
+
+ @Test
+ void testApplicationContents() throws Throwable {
+ // source code
+ codestartTest.checkGeneratedSource("org.acme.example.MainView");
+ codestartTest.checkGeneratedSource("org.acme.example.AppConfig");
+ codestartTest.checkGeneratedSource("org.acme.example.GreetService");
+
+ codestartTest.assertThatGeneratedTreeMatchSnapshots(Language.JAVA,
+ "frontend");
+
+ codestartTest.assertThatGeneratedFile(Language.JAVA, ".gitignore")
+ .satisfies(checkContains("node_modules/"),
+ checkContains("frontend/generated/"),
+ checkContains("vite.generated.ts"));
+
+ // Check POM file: vaadin-bom, deps, production profile
+ codestartTest.assertThatGeneratedFile(Language.JAVA, "pom.xml")
+ .satisfies(pomFile -> {
+ Model pom = new DefaultModelReader().read(pomFile.toFile(),
+ Map.of());
+ assertSoftly(soft -> {
+ assertThatHasVaadinBom(pom, soft);
+ assertThatHasVaadinQuarkusExtension(pom, soft);
+ assertThatHasProductionProfile(pom, soft);
+ });
+ });
+ }
+
+}
diff --git a/integration-tests/codestarts/src/test/java/com/vaadin/flow/quarkus/it/VaadinExtensionPreReleaseCodestartTest.java b/integration-tests/codestarts/src/test/java/com/vaadin/flow/quarkus/it/VaadinExtensionPreReleaseCodestartTest.java
new file mode 100644
index 0000000..9291588
--- /dev/null
+++ b/integration-tests/codestarts/src/test/java/com/vaadin/flow/quarkus/it/VaadinExtensionPreReleaseCodestartTest.java
@@ -0,0 +1,56 @@
+package com.vaadin.flow.quarkus.it;
+
+import java.util.Map;
+
+import io.quarkus.devtools.codestarts.quarkus.QuarkusCodestartCatalog.Language;
+import io.quarkus.devtools.testing.codestarts.QuarkusCodestartTest;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.DefaultModelReader;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import static com.vaadin.flow.quarkus.it.CodestartTestUtils.assertThatHasPreReleaseRepositories;
+import static com.vaadin.flow.quarkus.it.CodestartTestUtils.assertThatHasProductionProfile;
+import static com.vaadin.flow.quarkus.it.CodestartTestUtils.assertThatHasVaadinBom;
+import static com.vaadin.flow.quarkus.it.CodestartTestUtils.assertThatHasVaadinQuarkusExtension;
+import static io.quarkus.devtools.testing.SnapshotTesting.checkContains;
+import static org.assertj.core.api.SoftAssertions.assertSoftly;
+
+public class VaadinExtensionPreReleaseCodestartTest {
+
+ @RegisterExtension
+ public static QuarkusCodestartTest codestartTest = QuarkusCodestartTest
+ .builder().languages(Language.JAVA)
+ .setupStandaloneExtensionTest("com.vaadin:vaadin-quarkus")
+ .putData("vaadin-flow-codestart.vaadinVersion", "24.1-SNAPSHOT")
+ .build();
+
+ @Test
+ void testApplicationContents() throws Throwable {
+ codestartTest.checkGeneratedSource("org.acme.example.MainView");
+ codestartTest.checkGeneratedSource("org.acme.example.AppConfig");
+ codestartTest.checkGeneratedSource("org.acme.example.GreetService");
+
+ codestartTest.assertThatGeneratedTreeMatchSnapshots(Language.JAVA,
+ "frontend");
+
+ codestartTest.assertThatGeneratedFile(Language.JAVA, ".gitignore")
+ .satisfies(checkContains("node_modules/"),
+ checkContains("frontend/generated/"),
+ checkContains("vite.generated.ts"));
+
+ // Check POM file: vaadin-bom, deps, production profile
+ codestartTest.assertThatGeneratedFile(Language.JAVA, "pom.xml")
+ .satisfies(pomFile -> {
+ Model pom = new DefaultModelReader().read(pomFile.toFile(),
+ Map.of());
+ assertSoftly(soft -> {
+ assertThatHasVaadinBom(pom, soft);
+ assertThatHasVaadinQuarkusExtension(pom, soft);
+ assertThatHasProductionProfile(pom, soft);
+ assertThatHasPreReleaseRepositories(pom, soft);
+ });
+ });
+ }
+
+}
diff --git a/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionCodestartTest/testApplicationContents/dir-tree.snapshot b/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionCodestartTest/testApplicationContents/dir-tree.snapshot
new file mode 100644
index 0000000..9fbb5b8
--- /dev/null
+++ b/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionCodestartTest/testApplicationContents/dir-tree.snapshot
@@ -0,0 +1,7 @@
+/
+themes/
+themes/starter-theme/
+themes/starter-theme/components/
+themes/starter-theme/components/vaadin-text-field.css
+themes/starter-theme/styles.css
+themes/starter-theme/theme.json
\ No newline at end of file
diff --git a/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_AppConfig.java b/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_AppConfig.java
new file mode 100644
index 0000000..8709622
--- /dev/null
+++ b/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_AppConfig.java
@@ -0,0 +1,8 @@
+package ilove.quark.us.example;
+
+import com.vaadin.flow.component.page.AppShellConfigurator;
+import com.vaadin.flow.theme.Theme;
+
+@Theme("starter-theme")
+public class AppConfig implements AppShellConfigurator {
+}
diff --git a/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_GreetService.java b/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_GreetService.java
new file mode 100644
index 0000000..bc09cd8
--- /dev/null
+++ b/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_GreetService.java
@@ -0,0 +1,15 @@
+package ilove.quark.us.example;
+
+import jakarta.enterprise.context.Dependent;
+
+@Dependent
+public class GreetService {
+
+ public String greet(String name) {
+ if (name == null || name.isEmpty()) {
+ return "Hello anonymous user";
+ } else {
+ return "Hello " + name;
+ }
+ }
+}
diff --git a/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_MainView.java b/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_MainView.java
new file mode 100644
index 0000000..1cae664
--- /dev/null
+++ b/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_MainView.java
@@ -0,0 +1,46 @@
+package ilove.quark.us.example;
+
+import jakarta.inject.Inject;
+
+import com.vaadin.flow.component.Key;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.button.ButtonVariant;
+import com.vaadin.flow.component.html.Paragraph;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.router.Route;
+
+/**
+ * The main view contains a button and a click listener.
+ */
+@Route("")
+public class MainView extends VerticalLayout {
+
+ @Inject
+ GreetService greetService;
+
+ public MainView() {
+ // Use TextField for standard text input
+ TextField textField = new TextField("Your name");
+ textField.addThemeName("bordered");
+
+ // Button click listeners can be defined as lambda expressions
+ Button button = new Button("Say hello", e -> {
+ add(new Paragraph(greetService.greet(textField.getValue())));
+ });
+
+ // Theme variants give you predefined extra styles for components.
+ // Example: Primary button is more prominent look.
+ button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
+
+ // You can specify keyboard shortcuts for buttons.
+ // Example: Pressing enter in this view clicks the Button.
+ button.addClickShortcut(Key.ENTER);
+
+ // Use custom CSS classes to apply styling. This is defined in
+ // shared-styles.css.
+ addClassName("centered-content");
+
+ add(textField, button);
+ }
+}
diff --git a/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionPreReleaseCodestartTest/testApplicationContents/dir-tree.snapshot b/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionPreReleaseCodestartTest/testApplicationContents/dir-tree.snapshot
new file mode 100644
index 0000000..9fbb5b8
--- /dev/null
+++ b/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionPreReleaseCodestartTest/testApplicationContents/dir-tree.snapshot
@@ -0,0 +1,7 @@
+/
+themes/
+themes/starter-theme/
+themes/starter-theme/components/
+themes/starter-theme/components/vaadin-text-field.css
+themes/starter-theme/styles.css
+themes/starter-theme/theme.json
\ No newline at end of file
diff --git a/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionPreReleaseCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_AppConfig.java b/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionPreReleaseCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_AppConfig.java
new file mode 100644
index 0000000..8709622
--- /dev/null
+++ b/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionPreReleaseCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_AppConfig.java
@@ -0,0 +1,8 @@
+package ilove.quark.us.example;
+
+import com.vaadin.flow.component.page.AppShellConfigurator;
+import com.vaadin.flow.theme.Theme;
+
+@Theme("starter-theme")
+public class AppConfig implements AppShellConfigurator {
+}
diff --git a/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionPreReleaseCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_GreetService.java b/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionPreReleaseCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_GreetService.java
new file mode 100644
index 0000000..bc09cd8
--- /dev/null
+++ b/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionPreReleaseCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_GreetService.java
@@ -0,0 +1,15 @@
+package ilove.quark.us.example;
+
+import jakarta.enterprise.context.Dependent;
+
+@Dependent
+public class GreetService {
+
+ public String greet(String name) {
+ if (name == null || name.isEmpty()) {
+ return "Hello anonymous user";
+ } else {
+ return "Hello " + name;
+ }
+ }
+}
diff --git a/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionPreReleaseCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_MainView.java b/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionPreReleaseCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_MainView.java
new file mode 100644
index 0000000..1cae664
--- /dev/null
+++ b/integration-tests/codestarts/src/test/resources/__snapshots__/VaadinExtensionPreReleaseCodestartTest/testApplicationContents/src_main_java_ilove_quark_us_example_MainView.java
@@ -0,0 +1,46 @@
+package ilove.quark.us.example;
+
+import jakarta.inject.Inject;
+
+import com.vaadin.flow.component.Key;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.button.ButtonVariant;
+import com.vaadin.flow.component.html.Paragraph;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.router.Route;
+
+/**
+ * The main view contains a button and a click listener.
+ */
+@Route("")
+public class MainView extends VerticalLayout {
+
+ @Inject
+ GreetService greetService;
+
+ public MainView() {
+ // Use TextField for standard text input
+ TextField textField = new TextField("Your name");
+ textField.addThemeName("bordered");
+
+ // Button click listeners can be defined as lambda expressions
+ Button button = new Button("Say hello", e -> {
+ add(new Paragraph(greetService.greet(textField.getValue())));
+ });
+
+ // Theme variants give you predefined extra styles for components.
+ // Example: Primary button is more prominent look.
+ button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
+
+ // You can specify keyboard shortcuts for buttons.
+ // Example: Pressing enter in this view clicks the Button.
+ button.addClickShortcut(Key.ENTER);
+
+ // Use custom CSS classes to apply styling. This is defined in
+ // shared-styles.css.
+ addClassName("centered-content");
+
+ add(textField, button);
+ }
+}
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 4490239..87d87c8 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -26,6 +26,9 @@
production
development
+
+
+ codestarts
diff --git a/runtime/pom.xml b/runtime/pom.xml
index 09a3bec..fac2ec2 100644
--- a/runtime/pom.xml
+++ b/runtime/pom.xml
@@ -92,6 +92,26 @@
+
+ maven-jar-plugin
+
+
+ generate-codestart-jar
+ generate-resources
+
+ jar
+
+
+ ${project.basedir}/src/main
+
+ codestarts/**
+
+ codestarts
+ true
+
+
+
+
diff --git a/runtime/src/main/codestarts/quarkus/flow-codestart/base/.gitignore b/runtime/src/main/codestarts/quarkus/flow-codestart/base/.gitignore
new file mode 100644
index 0000000..929e504
--- /dev/null
+++ b/runtime/src/main/codestarts/quarkus/flow-codestart/base/.gitignore
@@ -0,0 +1,15 @@
+/target/
+.idea/
+.settings
+.project
+.classpath
+
+*.iml
+.DS_Store
+
+# The following files are generated/updated by vaadin-maven-plugin
+node_modules/
+frontend/generated/
+pnpmfile.js
+vite.generated.ts
+webpack.generated.js
diff --git a/runtime/src/main/codestarts/quarkus/flow-codestart/base/README.tpl.qute.md b/runtime/src/main/codestarts/quarkus/flow-codestart/base/README.tpl.qute.md
new file mode 100644
index 0000000..7cdaa26
--- /dev/null
+++ b/runtime/src/main/codestarts/quarkus/flow-codestart/base/README.tpl.qute.md
@@ -0,0 +1,2 @@
+{#include readme-header /}
+
diff --git a/runtime/src/main/codestarts/quarkus/flow-codestart/base/frontend/themes/starter-theme/components/vaadin-text-field.css b/runtime/src/main/codestarts/quarkus/flow-codestart/base/frontend/themes/starter-theme/components/vaadin-text-field.css
new file mode 100644
index 0000000..bb70786
--- /dev/null
+++ b/runtime/src/main/codestarts/quarkus/flow-codestart/base/frontend/themes/starter-theme/components/vaadin-text-field.css
@@ -0,0 +1,11 @@
+/*
+ CSS styling examples for the Vaadin app.
+ Visit https://vaadin.com/docs/flow/theme/theming-overview.html and
+ https://vaadin.com/themes/lumo for more information.
+*/
+
+/* Example: the style is applied only to the textfields which has the `bordered` theme attribute. */
+:host([theme~="bordered"]) [part="input-field"] {
+ box-shadow: inset 0 0 0 1px var(--lumo-contrast-30pct);
+ background-color: var(--lumo-base-color);
+}
diff --git a/runtime/src/main/codestarts/quarkus/flow-codestart/base/frontend/themes/starter-theme/styles.css b/runtime/src/main/codestarts/quarkus/flow-codestart/base/frontend/themes/starter-theme/styles.css
new file mode 100644
index 0000000..6bf128d
--- /dev/null
+++ b/runtime/src/main/codestarts/quarkus/flow-codestart/base/frontend/themes/starter-theme/styles.css
@@ -0,0 +1,12 @@
+/*
+ CSS styling examples for the Vaadin app.
+ Visit https://vaadin.com/docs/flow/theme/theming-overview.html and
+ https://vaadin.com/themes/lumo for more information.
+*/
+
+/* Example: CSS class name to center align the content . */
+.centered-content {
+ margin: 0 auto;
+ max-width: 250px;
+}
+
diff --git a/runtime/src/main/codestarts/quarkus/flow-codestart/base/frontend/themes/starter-theme/theme.json b/runtime/src/main/codestarts/quarkus/flow-codestart/base/frontend/themes/starter-theme/theme.json
new file mode 100644
index 0000000..b007ffd
--- /dev/null
+++ b/runtime/src/main/codestarts/quarkus/flow-codestart/base/frontend/themes/starter-theme/theme.json
@@ -0,0 +1,3 @@
+{
+ "lumoImports" : [ "typography", "color", "spacing", "badge", "utility" ]
+}
diff --git a/runtime/src/main/codestarts/quarkus/flow-codestart/base/pom.xml.tpl.qute b/runtime/src/main/codestarts/quarkus/flow-codestart/base/pom.xml.tpl.qute
new file mode 100644
index 0000000..bae8e7f
--- /dev/null
+++ b/runtime/src/main/codestarts/quarkus/flow-codestart/base/pom.xml.tpl.qute
@@ -0,0 +1,114 @@
+
+{#if vaadinVersion }
+
+ {vaadinVersion}
+
+
+
+
+
+ com.vaadin
+ vaadin-bom
+ pom
+ import
+ $\{vaadin.version\}
+
+
+
+
+
+
+ {#if !input['selected-extensions-ga'].contains("com.vaadin:vaadin-quarkus-extension") }
+
+ com.vaadin
+ vaadin-quarkus-extension
+ $\{vaadin.version\}
+
+ {/if}
+
+
+
+
+
+
+
+
+ production
+
+
+
+ com.vaadin
+ vaadin-maven-plugin
+ $\{vaadin.version\}
+
+
+
+ prepare-frontend
+ build-frontend
+
+ compile
+
+
+
+
+
+
+
+
+ {#if !vaadinVersion.matches("^\\d+\\.\\d+\.\\d+$") }
+ {! Vaadin SNAPSHOT or pre-release, this section is added only when testing !}
+
+
+
+
+
+ central
+ https://repo.maven.apache.org/maven2
+
+ false
+
+
+
+ vaadin-prereleases
+
+ https://maven.vaadin.com/vaadin-prereleases/
+
+
+
+
+ Vaadin Directory
+ https://maven.vaadin.com/vaadin-addons
+
+ false
+
+
+
+
+
+
+
+ central
+ https://repo.maven.apache.org/maven2
+
+ false
+
+
+
+ vaadin-prereleases
+
+ https://maven.vaadin.com/vaadin-prereleases/
+
+
+
+ {/if}
+{/if}
+
diff --git a/runtime/src/main/codestarts/quarkus/flow-codestart/codestart.yml b/runtime/src/main/codestarts/quarkus/flow-codestart/codestart.yml
new file mode 100644
index 0000000..dcd4c66
--- /dev/null
+++ b/runtime/src/main/codestarts/quarkus/flow-codestart/codestart.yml
@@ -0,0 +1,12 @@
+name: vaadin-flow-codestart
+ref: vaadin-flow
+type: code
+tags: extension-codestart
+metadata:
+ title: Vaadin Flow example
+ description: This is an example application to get started with Vaadin Flow. It generates a simple view interacting with an injected service
+ related-guide-section: https://vaadin.com/docs/latest/integrations/quarkus
+language:
+ base:
+ data:
+ vaadinVersion: ${vaadin.version}
diff --git a/runtime/src/main/codestarts/quarkus/flow-codestart/java/src/main/java/org/acme/example/AppConfig.java b/runtime/src/main/codestarts/quarkus/flow-codestart/java/src/main/java/org/acme/example/AppConfig.java
new file mode 100644
index 0000000..bf9202b
--- /dev/null
+++ b/runtime/src/main/codestarts/quarkus/flow-codestart/java/src/main/java/org/acme/example/AppConfig.java
@@ -0,0 +1,8 @@
+package org.acme.example;
+
+import com.vaadin.flow.component.page.AppShellConfigurator;
+import com.vaadin.flow.theme.Theme;
+
+@Theme("starter-theme")
+public class AppConfig implements AppShellConfigurator {
+}
diff --git a/runtime/src/main/codestarts/quarkus/flow-codestart/java/src/main/java/org/acme/example/GreetService.java b/runtime/src/main/codestarts/quarkus/flow-codestart/java/src/main/java/org/acme/example/GreetService.java
new file mode 100644
index 0000000..03eb8f6
--- /dev/null
+++ b/runtime/src/main/codestarts/quarkus/flow-codestart/java/src/main/java/org/acme/example/GreetService.java
@@ -0,0 +1,15 @@
+package org.acme.example;
+
+import jakarta.enterprise.context.Dependent;
+
+@Dependent
+public class GreetService {
+
+ public String greet(String name) {
+ if (name == null || name.isEmpty()) {
+ return "Hello anonymous user";
+ } else {
+ return "Hello " + name;
+ }
+ }
+}
diff --git a/runtime/src/main/codestarts/quarkus/flow-codestart/java/src/main/java/org/acme/example/MainView.java b/runtime/src/main/codestarts/quarkus/flow-codestart/java/src/main/java/org/acme/example/MainView.java
new file mode 100644
index 0000000..a64dc3c
--- /dev/null
+++ b/runtime/src/main/codestarts/quarkus/flow-codestart/java/src/main/java/org/acme/example/MainView.java
@@ -0,0 +1,46 @@
+package org.acme.example;
+
+import jakarta.inject.Inject;
+
+import com.vaadin.flow.component.Key;
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.button.ButtonVariant;
+import com.vaadin.flow.component.html.Paragraph;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.component.textfield.TextField;
+import com.vaadin.flow.router.Route;
+
+/**
+ * The main view contains a button and a click listener.
+ */
+@Route("")
+public class MainView extends VerticalLayout {
+
+ @Inject
+ GreetService greetService;
+
+ public MainView() {
+ // Use TextField for standard text input
+ TextField textField = new TextField("Your name");
+ textField.addThemeName("bordered");
+
+ // Button click listeners can be defined as lambda expressions
+ Button button = new Button("Say hello", e -> {
+ add(new Paragraph(greetService.greet(textField.getValue())));
+ });
+
+ // Theme variants give you predefined extra styles for components.
+ // Example: Primary button is more prominent look.
+ button.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
+
+ // You can specify keyboard shortcuts for buttons.
+ // Example: Pressing enter in this view clicks the Button.
+ button.addClickShortcut(Key.ENTER);
+
+ // Use custom CSS classes to apply styling. This is defined in
+ // shared-styles.css.
+ addClassName("centered-content");
+
+ add(textField, button);
+ }
+}
diff --git a/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/runtime/src/main/resources/META-INF/quarkus-extension.yaml
index 9acebb7..8b0499e 100644
--- a/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++ b/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -9,3 +9,8 @@ metadata:
categories:
- "web"
status: "stable"
+ codestart:
+ name: "vaadin-flow"
+ languages:
+ - "java"
+ artifact: "com.vaadin:vaadin-quarkus:codestarts:jar:${project.version}"