diff --git a/Cargo.lock b/Cargo.lock
index bac742953a..e93a1caddf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1170,30 +1170,15 @@ dependencies = [
  "which 4.4.2",
 ]
 
-[[package]]
-name = "bit-set"
-version = "0.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
-dependencies = [
- "bit-vec 0.6.3",
-]
-
 [[package]]
 name = "bit-set"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
 dependencies = [
- "bit-vec 0.8.0",
+ "bit-vec",
 ]
 
-[[package]]
-name = "bit-vec"
-version = "0.6.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
-
 [[package]]
 name = "bit-vec"
 version = "0.8.0"
@@ -1465,7 +1450,7 @@ dependencies = [
  "bytes 1.9.0",
  "cargo-component-core",
  "cargo-config2",
- "cargo_metadata 0.19.1",
+ "cargo_metadata",
  "clap",
  "futures",
  "heck 0.5.0",
@@ -1545,20 +1530,6 @@ dependencies = [
  "serde",
 ]
 
-[[package]]
-name = "cargo_metadata"
-version = "0.18.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037"
-dependencies = [
- "camino",
- "cargo-platform",
- "semver",
- "serde",
- "serde_json",
- "thiserror 1.0.69",
-]
-
 [[package]]
 name = "cargo_metadata"
 version = "0.19.1"
@@ -1865,7 +1836,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "68578f196d2a33ff61b27fae256c3164f65e36382648e30666dde05b8cc9dfdf"
 dependencies = [
  "async-trait",
- "convert_case 0.6.0",
+ "convert_case",
  "json5",
  "nom",
  "pathdiff",
@@ -1961,12 +1932,6 @@ version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6"
 
-[[package]]
-name = "convert_case"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
-
 [[package]]
 name = "convert_case"
 version = "0.6.0"
@@ -2620,19 +2585,6 @@ dependencies = [
  "syn 2.0.96",
 ]
 
-[[package]]
-name = "derive_more"
-version = "0.99.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce"
-dependencies = [
- "convert_case 0.4.0",
- "proc-macro2",
- "quote",
- "rustc_version",
- "syn 2.0.96",
-]
-
 [[package]]
 name = "derive_more"
 version = "1.0.0"
@@ -3172,11 +3124,11 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
 
 [[package]]
 name = "fancy-regex"
-version = "0.13.0"
+version = "0.14.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "531e46835a22af56d1e3b66f04844bed63158bc094a628bec1d321d9b4c44bf2"
+checksum = "6e24cb5a94bcae1e5408b0effca5cd7172ea3c5755049c5f3af4cd283a165298"
 dependencies = [
- "bit-set 0.5.3",
+ "bit-set",
  "regex-automata 0.4.9",
  "regex-syntax 0.8.5",
 ]
@@ -3799,7 +3751,7 @@ dependencies = [
  "async-trait",
  "bincode",
  "bytes 1.9.0",
- "cargo_metadata 0.19.1",
+ "cargo_metadata",
  "futures-core",
  "golem-wasm-ast",
  "golem-wasm-rpc",
@@ -3830,7 +3782,7 @@ dependencies = [
  "clap_complete",
  "cli-table",
  "colored",
- "derive_more 1.0.0",
+ "derive_more",
  "dirs 5.0.1",
  "env_logger 0.11.6",
  "futures-util",
@@ -3925,7 +3877,7 @@ dependencies = [
  "combine",
  "console-subscriber",
  "dashmap",
- "derive_more 1.0.0",
+ "derive_more",
  "figment",
  "fred",
  "git-version",
@@ -4082,20 +4034,22 @@ dependencies = [
 
 [[package]]
 name = "golem-examples"
-version = "1.1.0"
+version = "1.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c0bcbbedbbecc9c66f2349150cbeb1b9e9704958611af624fbf11ea7202c4d9"
+checksum = "f0ae4fa06a19377a53f113c47c70724416fd9cf6b9f655749250ded3f81de616"
 dependencies = [
  "Inflector",
- "cargo_metadata 0.18.1",
+ "cargo_metadata",
  "clap",
  "colored",
  "copy_dir",
- "derive_more 0.99.18",
+ "derive_more",
  "dir-diff",
  "fancy-regex",
  "golem-wit",
  "include_dir",
+ "itertools 0.14.0",
+ "nanoid",
  "once_cell",
  "regex",
  "serde",
@@ -4111,7 +4065,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b33e98f6cc141902ffcc13d027d0bb9a4d3310e51ff182f67236384e8dfeb3ac"
 dependencies = [
  "clap",
- "convert_case 0.6.0",
+ "convert_case",
  "fmt",
  "indexmap 2.7.0",
  "indoc",
@@ -4311,7 +4265,7 @@ dependencies = [
  "async-trait",
  "bigdecimal",
  "bincode",
- "cargo_metadata 0.19.1",
+ "cargo_metadata",
  "git-version",
  "golem-wasm-ast",
  "poem-openapi",
@@ -4433,7 +4387,7 @@ dependencies = [
  "cap-fs-ext",
  "cap-std",
  "cap-time-ext",
- "cargo_metadata 0.19.1",
+ "cargo_metadata",
  "chrono",
  "console-subscriber",
  "dashmap",
@@ -4513,7 +4467,7 @@ dependencies = [
  "bincode",
  "bytes 1.9.0",
  "console-subscriber",
- "derive_more 1.0.0",
+ "derive_more",
  "figment",
  "futures",
  "futures-util",
@@ -4568,7 +4522,7 @@ dependencies = [
  "chrono",
  "conditional-trait-gen",
  "criterion",
- "derive_more 1.0.0",
+ "derive_more",
  "fastrand",
  "figment",
  "fred",
@@ -5573,6 +5527,15 @@ dependencies = [
  "either",
 ]
 
+[[package]]
+name = "itertools"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
+dependencies = [
+ "either",
+]
+
 [[package]]
 name = "itoa"
 version = "1.0.14"
@@ -6216,6 +6179,15 @@ version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03"
 
+[[package]]
+name = "nanoid"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8"
+dependencies = [
+ "rand",
+]
+
 [[package]]
 name = "nanorand"
 version = "0.7.0"
@@ -7349,7 +7321,7 @@ dependencies = [
  "base64 0.22.1",
  "bytes 1.9.0",
  "chrono",
- "derive_more 1.0.0",
+ "derive_more",
  "futures-util",
  "humantime",
  "indexmap 2.7.0",
@@ -7681,8 +7653,8 @@ version = "1.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "14cae93065090804185d3b75f0bf93b8eeda30c7a9b4a33d3bdb3988d6229e50"
 dependencies = [
- "bit-set 0.8.0",
- "bit-vec 0.8.0",
+ "bit-set",
+ "bit-vec",
  "bitflags 2.7.0",
  "lazy_static 1.5.0",
  "num-traits",
diff --git a/golem-cli/Cargo.toml b/golem-cli/Cargo.toml
index 81b143e9ea..cc2c7fbd84 100644
--- a/golem-cli/Cargo.toml
+++ b/golem-cli/Cargo.toml
@@ -45,7 +45,7 @@ derive_more = { workspace = true }
 dirs = "5.0.1"
 futures-util = { workspace = true }
 glob = "0.3.1"
-golem-examples = "1.1.0"
+golem-examples = "1.1.1"
 h2 = "0.4.7"
 http = { workspace = true }
 humansize = { workspace = true }
diff --git a/golem-cli/src/command.rs b/golem-cli/src/command.rs
index 746c1acefd..9023371f78 100644
--- a/golem-cli/src/command.rs
+++ b/golem-cli/src/command.rs
@@ -32,6 +32,8 @@ use api_deployment::ApiDeploymentSubcommand;
 use clap::{self, Command, Subcommand};
 use component::ComponentSubCommand;
 use golem_common::uri::oss::uri::ComponentUri;
+use golem_examples::cli::NameOrLanguage;
+use golem_examples::model::{ComponentName, GuestLanguage, GuestLanguageTier, PackageName};
 use golem_wasm_rpc_stubgen::App;
 use plugin::PluginSubcommand;
 use profile::{ProfileSubCommand, UniversalProfileAdd};
@@ -104,9 +106,43 @@ pub enum StaticSharedCommand {
         #[command(flatten)]
         command: diagnose::cli::Command,
     },
-    /// Create a new Golem component from built-in examples
-    #[command(flatten)]
-    Examples(golem_examples::cli::Command),
+
+    /// Create a new Golem standalone component example project from built-in examples
+    #[command()]
+    New {
+        #[command(flatten)]
+        name_or_language: NameOrLanguage,
+
+        /// The package name of the generated component (in namespace:name format)
+        #[arg(short, long)]
+        package_name: Option<PackageName>,
+
+        /// The new component's name
+        component_name: ComponentName,
+    },
+
+    /// Add a new Golem component to a project using Golem Application Manifest
+    #[command()]
+    NewAppComponent {
+        /// The component name (and package name) of the generated component (in namespace:name format)
+        component_name: PackageName,
+
+        /// Component language
+        #[arg(short, long, alias = "lang")]
+        language: GuestLanguage,
+    },
+
+    /// Lists the built-in examples available for creating new components
+    #[command()]
+    ListExamples {
+        /// The minimum language tier to include in the list
+        #[arg(short, long)]
+        min_tier: Option<GuestLanguageTier>,
+
+        /// Filter examples by a given guest language
+        #[arg(short, long, alias = "lang")]
+        language: Option<GuestLanguage>,
+    },
 }
 
 impl<Ctx> CliCommand<Ctx> for StaticSharedCommand {
@@ -116,19 +152,22 @@ impl<Ctx> CliCommand<Ctx> for StaticSharedCommand {
                 diagnose(command);
                 Ok(GolemResult::Empty)
             }
-            StaticSharedCommand::Examples(golem_examples::cli::Command::ListExamples {
-                min_tier,
-                language,
-            }) => examples::process_list_examples(min_tier, language),
-            StaticSharedCommand::Examples(golem_examples::cli::Command::New {
+            StaticSharedCommand::ListExamples { min_tier, language } => {
+                examples::list_standalone_examples(min_tier, language)
+            }
+            StaticSharedCommand::New {
                 name_or_language,
                 package_name,
                 component_name,
-            }) => examples::process_new(
+            } => examples::new(
                 name_or_language.example_name(),
                 component_name,
                 package_name,
             ),
+            StaticSharedCommand::NewAppComponent {
+                component_name,
+                language,
+            } => examples::new_app_component(component_name, language),
         }
     }
 }
diff --git a/golem-cli/src/diagnose.rs b/golem-cli/src/diagnose.rs
index a4a194d742..5d61f9f63f 100644
--- a/golem-cli/src/diagnose.rs
+++ b/golem-cli/src/diagnose.rs
@@ -716,7 +716,7 @@ impl DetectedTool {
 
 pub fn diagnose(command: cli::Command) {
     let selected_language = match &command.language {
-        Some(language) => SelectedLanguage::from_flag(language.clone()),
+        Some(language) => SelectedLanguage::from_flag(*language),
         None => SelectedLanguage::from_env(),
     };
 
diff --git a/golem-cli/src/examples.rs b/golem-cli/src/examples.rs
index 39aa9ecb7a..94a27af434 100644
--- a/golem-cli/src/examples.rs
+++ b/golem-cli/src/examples.rs
@@ -14,24 +14,25 @@
 
 use std::env;
 
+use crate::model::{ExampleDescription, GolemError, GolemResult};
 use golem_examples::model::{
-    ComponentName, ExampleName, ExampleParameters, GuestLanguage, GuestLanguageTier, PackageName,
+    ComponentName, ComposableAppGroupName, ExampleName, ExampleParameters, GuestLanguage,
+    GuestLanguageTier, PackageName, TargetExistsResolveMode,
 };
 use golem_examples::*;
+use itertools::Itertools;
 
-use crate::model::{ExampleDescription, GolemError, GolemResult};
-
-pub fn process_new(
+pub fn new(
     example_name: ExampleName,
     component_name: ComponentName,
     package_name: Option<PackageName>,
 ) -> Result<GolemResult, GolemError> {
-    let examples = GolemExamples::list_all_examples();
+    let examples = all_standalone_examples();
     let example = examples.iter().find(|example| example.name == example_name);
     match example {
         Some(example) => {
             let cwd = env::current_dir().expect("Failed to get current working directory");
-            match GolemExamples::instantiate(
+            match instantiate_example(
                 example,
                 &ExampleParameters {
                     component_name,
@@ -39,6 +40,7 @@ pub fn process_new(
                         .unwrap_or(PackageName::from_string("golem:component").unwrap()),
                     target_path: cwd,
                 },
+                TargetExistsResolveMode::Fail,
             ) {
                 Ok(instructions) => Ok(GolemResult::Str(instructions.to_string())),
                 Err(err) => GolemResult::err(format!("Failed to instantiate component: {err}")),
@@ -50,11 +52,11 @@ pub fn process_new(
     }
 }
 
-pub fn process_list_examples(
+pub fn list_standalone_examples(
     min_tier: Option<GuestLanguageTier>,
     language: Option<GuestLanguage>,
 ) -> Result<GolemResult, GolemError> {
-    let examples = GolemExamples::list_all_examples()
+    let examples = all_standalone_examples()
         .iter()
         .filter(|example| match &language {
             Some(language) => example.language == *language,
@@ -69,3 +71,43 @@ pub fn process_list_examples(
 
     Ok(GolemResult::Ok(Box::new(examples)))
 }
+
+pub fn new_app_component(
+    component_name: PackageName,
+    language: GuestLanguage,
+) -> Result<GolemResult, GolemError> {
+    let all_examples = all_composable_app_examples();
+
+    let Some(language_examples) = all_examples.get(&language) else {
+        return Err(GolemError(format!(
+            "No template found for {}, currently supported languages: {}",
+            language,
+            all_examples.keys().join(", ")
+        )));
+    };
+
+    let default_examples = language_examples
+        .get(&ComposableAppGroupName::default())
+        .expect("No default template found for the selected language");
+
+    assert_eq!(
+        default_examples.components.len(),
+        1,
+        "Expected exactly one default component template"
+    );
+
+    let default_component_example = &default_examples.components[0];
+
+    match add_component_by_example(
+        default_examples.common.as_ref(),
+        default_component_example,
+        &env::current_dir().expect("Failed to get current working directory"),
+        &component_name,
+    ) {
+        Ok(_) => Ok(GolemResult::Str(format!(
+            "Added new app component {}",
+            component_name.to_string_with_colon()
+        ))),
+        Err(err) => Err(GolemError(format!("Failed to add component: {err}"))),
+    }
+}
diff --git a/golem-cli/src/model.rs b/golem-cli/src/model.rs
index 460cf24733..445ad053d4 100644
--- a/golem-cli/src/model.rs
+++ b/golem-cli/src/model.rs
@@ -596,7 +596,7 @@ impl ExampleDescription {
     pub fn from_example(example: &Example) -> Self {
         Self {
             name: example.name.clone(),
-            language: example.language.clone(),
+            language: example.language,
             description: example.description.clone(),
             tier: example.language.tier(),
         }
diff --git a/golem-cli/src/model/text.rs b/golem-cli/src/model/text.rs
index 38fba00540..2ac5c17ba3 100644
--- a/golem-cli/src/model/text.rs
+++ b/golem-cli/src/model/text.rs
@@ -695,7 +695,7 @@ pub mod example {
         fn from(value: &ExampleDescription) -> Self {
             Self {
                 name: value.name.clone(),
-                language: value.language.clone(),
+                language: value.language,
                 tier: value.tier.clone(),
                 description: textwrap::wrap(&value.description, 30).join("\n"),
             }
diff --git a/test-components/auction-example/auction-registry/golem.yaml b/test-components/auction-example/auction-registry/golem.yaml
index c7a3ca0b61..b7cda62f1b 100644
--- a/test-components/auction-example/auction-registry/golem.yaml
+++ b/test-components/auction-example/auction-registry/golem.yaml
@@ -1,7 +1,7 @@
 # Schema for IDEA:
-# $schema: https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# $schema: https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 # Schema for vscode-yaml
-# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 
 components:
   auction-registry:
diff --git a/test-components/auction-example/auction/golem.yaml b/test-components/auction-example/auction/golem.yaml
index 6852fdd359..dd5ba8c541 100644
--- a/test-components/auction-example/auction/golem.yaml
+++ b/test-components/auction-example/auction/golem.yaml
@@ -1,7 +1,7 @@
 # Schema for IDEA:
-# $schema: https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# $schema: https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 # Schema for vscode-yaml
-# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 
 components:
   auction:
diff --git a/test-components/auction-example/golem.yaml b/test-components/auction-example/golem.yaml
index fc14644feb..5f051e3e6a 100644
--- a/test-components/auction-example/golem.yaml
+++ b/test-components/auction-example/golem.yaml
@@ -1,7 +1,7 @@
 # Schema for IDEA:
-# $schema: https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# $schema: https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 # Schema for vscode-yaml
-# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 
 tempDir: target/golem-temp
 templates:
diff --git a/test-components/rpc/caller/golem.yaml b/test-components/rpc/caller/golem.yaml
index 256d497f08..70bf7a944f 100644
--- a/test-components/rpc/caller/golem.yaml
+++ b/test-components/rpc/caller/golem.yaml
@@ -1,7 +1,7 @@
 # Schema for IDEA:
-# $schema: https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# $schema: https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 # Schema for vscode-yaml
-# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 
 components:
   caller:
diff --git a/test-components/rpc/counters/golem.yaml b/test-components/rpc/counters/golem.yaml
index 0ca0ef07eb..b3e6819c09 100644
--- a/test-components/rpc/counters/golem.yaml
+++ b/test-components/rpc/counters/golem.yaml
@@ -1,7 +1,7 @@
 # Schema for IDEA:
-# $schema: https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# $schema: https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 # Schema for vscode-yaml
-# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 
 components:
   counters:
diff --git a/test-components/rpc/ephemeral/golem.yaml b/test-components/rpc/ephemeral/golem.yaml
index 5484ccedf1..499373bd50 100644
--- a/test-components/rpc/ephemeral/golem.yaml
+++ b/test-components/rpc/ephemeral/golem.yaml
@@ -1,7 +1,7 @@
 # Schema for IDEA:
-# $schema: https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# $schema: https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 # Schema for vscode-yaml
-# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 
 components:
   ephemeral:
diff --git a/test-components/rpc/golem.yaml b/test-components/rpc/golem.yaml
index fc14644feb..5f051e3e6a 100644
--- a/test-components/rpc/golem.yaml
+++ b/test-components/rpc/golem.yaml
@@ -1,7 +1,7 @@
 # Schema for IDEA:
-# $schema: https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# $schema: https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 # Schema for vscode-yaml
-# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 
 tempDir: target/golem-temp
 templates:
diff --git a/test-components/rust-service/rpc/child-component/golem.yaml b/test-components/rust-service/rpc/child-component/golem.yaml
index dad604c8c0..04b3b06b2a 100644
--- a/test-components/rust-service/rpc/child-component/golem.yaml
+++ b/test-components/rust-service/rpc/child-component/golem.yaml
@@ -1,7 +1,7 @@
 # Schema for IDEA:
-# $schema: https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# $schema: https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 # Schema for vscode-yaml
-# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 
 components:
   child-component:
diff --git a/test-components/rust-service/rpc/golem.yaml b/test-components/rust-service/rpc/golem.yaml
index c579ae6dda..1019c8be30 100644
--- a/test-components/rust-service/rpc/golem.yaml
+++ b/test-components/rust-service/rpc/golem.yaml
@@ -1,7 +1,7 @@
 # Schema for IDEA:
-# $schema: https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# $schema: https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 # Schema for vscode-yaml
-# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 
 tempDir: target/golem-temp
 templates:
diff --git a/test-components/rust-service/rpc/parent-component/golem.yaml b/test-components/rust-service/rpc/parent-component/golem.yaml
index 86e960b83e..7d507d0c9e 100644
--- a/test-components/rust-service/rpc/parent-component/golem.yaml
+++ b/test-components/rust-service/rpc/parent-component/golem.yaml
@@ -1,7 +1,7 @@
 # Schema for IDEA:
-# $schema: https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# $schema: https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 # Schema for vscode-yaml
-# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 
 components:
   parent-component:
diff --git a/test-components/ts-rpc/caller/golem.yaml b/test-components/ts-rpc/caller/golem.yaml
index 375321e37d..e7ebfaacfc 100644
--- a/test-components/ts-rpc/caller/golem.yaml
+++ b/test-components/ts-rpc/caller/golem.yaml
@@ -1,7 +1,7 @@
 # Schema for IDEA:
-# $schema: https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# $schema: https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 # Schema for vscode-yaml
-# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 
 components:
   caller:
diff --git a/test-components/ts-rpc/counter/golem.yaml b/test-components/ts-rpc/counter/golem.yaml
index 5603d26bcb..bdd48e8e7b 100644
--- a/test-components/ts-rpc/counter/golem.yaml
+++ b/test-components/ts-rpc/counter/golem.yaml
@@ -1,7 +1,7 @@
 # Schema for IDEA:
-# $schema: https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# $schema: https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 # Schema for vscode-yaml
-# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 
 components:
   counter:
diff --git a/test-components/ts-rpc/golem.yaml b/test-components/ts-rpc/golem.yaml
index 0155947ee9..7d1960795e 100644
--- a/test-components/ts-rpc/golem.yaml
+++ b/test-components/ts-rpc/golem.yaml
@@ -1,7 +1,7 @@
 # Schema for IDEA:
-# $schema: https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# $schema: https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 # Schema for vscode-yaml
-# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.0/golem.schema.json
+# yaml-language-server: $schema=https://schema.golem.cloud/app/golem/1.1.1/golem.schema.json
 
 tempDir: dist/golem-temp
 witDeps:
diff --git a/wasm-rpc-stubgen/src/commands/app.rs b/wasm-rpc-stubgen/src/commands/app.rs
index 6122735f7a..e2ea8185b2 100644
--- a/wasm-rpc-stubgen/src/commands/app.rs
+++ b/wasm-rpc-stubgen/src/commands/app.rs
@@ -20,6 +20,7 @@ use crate::wit_generate::{
 use crate::wit_resolve::{ResolvedWitApplication, WitDepsResolver};
 use crate::{commands, naming, WasmRpcOverride};
 use anyhow::{anyhow, bail, Context, Error};
+use colored::control::SHOULD_COLORIZE;
 use colored::Colorize;
 use glob::{glob_with, MatchOptions};
 use golem_wasm_rpc::WASM_RPC_VERSION;
@@ -559,36 +560,128 @@ pub fn clean<CPE: ComponentPropertiesExtensions>(config: Config<CPE>) -> anyhow:
     Ok(())
 }
 
-// TODO: collect_custom_commands is not selected_component_names aware yet
-pub fn collect_custom_commands<CPE: ComponentPropertiesExtensions>(
+pub fn print_dynamic_help<CPE: ComponentPropertiesExtensions>(
     config: Config<CPE>,
-) -> anyhow::Result<BTreeMap<String, BTreeSet<ProfileName>>> {
-    set_log_output(config.log_output);
+) -> anyhow::Result<()> {
+    static LABEL_SOURCE: &str = "Source";
+    static LABEL_SELECTED: &str = "Selected";
+    static LABEL_TEMPLATE: &str = "Template";
+    static LABEL_PROFILES: &str = "Profiles";
+    static LABEL_DEPENDENCIES: &str = "Dependencies";
+
+    let label_padding = {
+        [
+            &LABEL_SOURCE,
+            &LABEL_SELECTED,
+            &LABEL_TEMPLATE,
+            &LABEL_PROFILES,
+            &LABEL_DEPENDENCIES,
+        ]
+        .map(|label| label.len())
+        .into_iter()
+        .max()
+        .unwrap_or(0)
+            + 1
+    };
 
-    let (app, _selected_component_names) = to_anyhow(
-        config.log_output,
-        "Failed to load application manifest(s), see problems above",
-        load_app(&config),
-    )?;
+    let print_field = |label: &'static str, value: String| {
+        println!("    {:<label_padding$} {}", format!("{}:", label), value)
+    };
+
+    let ctx = ApplicationContext::new(config)?;
+    let should_colorize = SHOULD_COLORIZE.should_colorize();
+
+    if ctx.application.has_any_component() {
+        println!("{}", "Components:".log_color_help_group());
+        for component_name in ctx.application.component_names() {
+            let selected = ctx.selected_component_names.contains(component_name);
+            let effective_property_source = ctx
+                .application
+                .component_effective_property_source(component_name, ctx.profile());
+            println!("  {}", component_name.as_str().bold());
+            print_field(
+                LABEL_SELECTED,
+                if selected {
+                    "yes".green().bold().to_string()
+                } else {
+                    "no".red().bold().to_string()
+                },
+            );
+            print_field(
+                LABEL_SOURCE,
+                ctx.application
+                    .component_source(component_name)
+                    .to_string_lossy()
+                    .underline()
+                    .to_string(),
+            );
+            if let Some(template_name) = effective_property_source.template_name {
+                print_field(LABEL_TEMPLATE, template_name.as_str().bold().to_string());
+            }
+            if let Some(selected_profile) = effective_property_source.profile {
+                print_field(
+                    LABEL_PROFILES,
+                    ctx.application
+                        .component_profiles(component_name)
+                        .iter()
+                        .map(|profile| {
+                            if selected_profile == profile {
+                                if should_colorize {
+                                    profile.as_str().bold().underline().to_string()
+                                } else {
+                                    format!("*{}", profile.as_str())
+                                }
+                            } else {
+                                profile.to_string()
+                            }
+                        })
+                        .join(", "),
+                );
+            }
+            let dependencies = ctx
+                .application
+                .component_wasm_rpc_dependencies(component_name);
+            if !dependencies.is_empty() {
+                println!("    {}:", LABEL_DEPENDENCIES);
+                for dependency in dependencies {
+                    println!(
+                        "      - {} ({})",
+                        dependency.name.as_str().bold(),
+                        dependency.dep_type.as_str()
+                    )
+                }
+            }
+        }
+        println!()
+    } else {
+        println!("No components found\n");
+    }
 
-    let all_profiles = app.all_option_profiles();
+    for (profile, commands) in ctx.application.all_custom_commands_for_all_profiles() {
+        if commands.is_empty() {
+            continue;
+        }
 
-    let mut commands = BTreeMap::<String, BTreeSet<ProfileName>>::new();
-    for profile in &all_profiles {
-        for command in app.all_custom_commands(profile.as_ref()) {
-            if !commands.contains_key(command.as_str()) {
-                commands.insert(command.clone(), BTreeSet::new());
+        match profile {
+            None => {
+                println!("{}", "Custom commands:".log_color_help_group())
+            }
+            Some(profile) => {
+                println!(
+                    "{}{}{}",
+                    "Custom commands for ".log_color_help_group(),
+                    profile.as_str().log_color_help_group(),
+                    " profile:".log_color_help_group()
+                )
             }
-            profile.iter().for_each(|profile| {
-                commands
-                    .get_mut(command.as_str())
-                    .unwrap()
-                    .insert(profile.clone());
-            });
         }
+        for command in commands {
+            println!("  {}", command.bold())
+        }
+        println!()
     }
 
-    Ok(commands)
+    Ok(())
 }
 
 pub fn custom_command<CPE: ComponentPropertiesExtensions>(
diff --git a/wasm-rpc-stubgen/src/lib.rs b/wasm-rpc-stubgen/src/lib.rs
index 075d75a16f..2fe51bdf5c 100644
--- a/wasm-rpc-stubgen/src/lib.rs
+++ b/wasm-rpc-stubgen/src/lib.rs
@@ -33,8 +33,6 @@ use crate::stub::{StubConfig, StubDefinition};
 use crate::wit_generate::UpdateCargoToml;
 use anyhow::Context;
 use clap::Subcommand;
-use colored::Colorize;
-use itertools::Itertools;
 use std::collections::HashSet;
 use std::marker::PhantomData;
 use std::path::PathBuf;
@@ -194,7 +192,7 @@ pub struct App {
 
 #[derive(Subcommand, Debug)]
 pub enum AppSubCommand {
-    /// Runs component build steps
+    /// Run component build steps
     Build(AppBuildArgs),
     /// Clean outputs
     Clean,
@@ -290,7 +288,7 @@ pub async fn run_app_command<CPE: ComponentPropertiesExtensions>(
         None => {
             clap_command.print_help()?;
             println!();
-            print_app_custom_commands_help(config);
+            print_dynamic_help(config);
             exit(2);
         }
     }
@@ -336,34 +334,10 @@ fn app_manifest_sources_to_resolve_mode(
     }
 }
 
-fn print_app_custom_commands_help<CPE: ComponentPropertiesExtensions>(
-    mut config: commands::app::Config<CPE>,
-) {
+fn print_dynamic_help<CPE: ComponentPropertiesExtensions>(mut config: commands::app::Config<CPE>) {
     config.log_output = Output::None;
-    match commands::app::collect_custom_commands(config) {
-        Ok(commands) => {
-            if !commands.is_empty() {
-                println!("{}", "Custom commands:".bold().underline());
-                for (command, profiles) in commands {
-                    if profiles.is_empty() {
-                        println!("  {}", command);
-                    } else {
-                        println!(
-                            "  {} ({})",
-                            command,
-                            profiles.iter().map(|s| s.to_string()).join(", ")
-                        );
-                    }
-                }
-                println!();
-            }
-        }
-        Err(err) => {
-            println!(
-                "{}\n{:?}",
-                "Cannot show custom commands:".log_color_warn(),
-                err
-            );
-        }
+
+    if let Some(err) = commands::app::print_dynamic_help(config).err() {
+        println!("{}\n{}", "Cannot show dynamic help:".log_color_warn(), err);
     }
 }
diff --git a/wasm-rpc-stubgen/src/log.rs b/wasm-rpc-stubgen/src/log.rs
index b9f361758c..37b244b617 100644
--- a/wasm-rpc-stubgen/src/log.rs
+++ b/wasm-rpc-stubgen/src/log.rs
@@ -253,6 +253,10 @@ pub trait LogColorize {
         self.as_str().bold()
     }
 
+    fn log_color_help_group(&self) -> ColoredString {
+        self.as_str().bold().underline()
+    }
+
     fn log_color_error_highlight(&self) -> ColoredString {
         self.as_str().bold().red().underline()
     }
diff --git a/wasm-rpc-stubgen/src/model/app.rs b/wasm-rpc-stubgen/src/model/app.rs
index a380eda3ec..bb9ea0e8e1 100644
--- a/wasm-rpc-stubgen/src/model/app.rs
+++ b/wasm-rpc-stubgen/src/model/app.rs
@@ -6,7 +6,7 @@ use crate::validation::{ValidatedResult, ValidationBuilder};
 use crate::{fs, naming};
 use serde::{Deserialize, Serialize};
 use std::cmp::Ordering;
-use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
+use std::collections::{BTreeMap, BTreeSet, HashMap};
 use std::fmt::Formatter;
 use std::fmt::{Debug, Display};
 use std::hash::Hash;
@@ -232,6 +232,10 @@ impl<CPE: ComponentPropertiesExtensions> Application<CPE> {
         self.components.keys()
     }
 
+    pub fn has_any_component(&self) -> bool {
+        !self.components.is_empty()
+    }
+
     pub fn contains_component(&self, component_name: &ComponentName) -> bool {
         self.components.contains_key(component_name)
     }
@@ -282,6 +286,36 @@ impl<CPE: ComponentPropertiesExtensions> Application<CPE> {
         custom_commands
     }
 
+    pub fn all_custom_commands_for_all_profiles(
+        &self,
+    ) -> BTreeMap<Option<ProfileName>, BTreeSet<String>> {
+        let mut custom_commands = BTreeMap::<Option<ProfileName>, BTreeSet<String>>::new();
+
+        custom_commands
+            .entry(None)
+            .or_default()
+            .extend(self.custom_commands.keys().cloned());
+
+        for profile in self.all_option_profiles() {
+            let profile_commands: &mut BTreeSet<String> = {
+                if custom_commands.contains_key(&profile) {
+                    custom_commands.get_mut(&profile).unwrap()
+                } else {
+                    custom_commands.entry(profile.clone()).or_default()
+                }
+            };
+
+            profile_commands.extend(self.component_names().flat_map(|component_name| {
+                self.component_properties(component_name, profile.as_ref())
+                    .custom_commands
+                    .keys()
+                    .cloned()
+            }));
+        }
+
+        custom_commands
+    }
+
     pub fn temp_dir(&self) -> PathBuf {
         match self.temp_dir.as_ref() {
             Some(temp_dir) => temp_dir.source.as_path().join(&temp_dir.value),
@@ -316,9 +350,9 @@ impl<CPE: ComponentPropertiesExtensions> Application<CPE> {
             .unwrap_or(&self.no_dependencies)
     }
 
-    fn component_profiles(&self, component_name: &ComponentName) -> HashSet<ProfileName> {
+    pub fn component_profiles(&self, component_name: &ComponentName) -> BTreeSet<ProfileName> {
         match &self.component(component_name).properties {
-            ResolvedComponentProperties::Properties { .. } => HashSet::new(),
+            ResolvedComponentProperties::Properties { .. } => BTreeSet::new(),
             ResolvedComponentProperties::Profiles { profiles, .. } => {
                 profiles.keys().cloned().collect()
             }