diff --git a/packages/ts/generator-plugin-signals/src/SignalProcessor.ts b/packages/ts/generator-plugin-signals/src/SignalProcessor.ts
index c483d8cbde..e86f84ffd6 100644
--- a/packages/ts/generator-plugin-signals/src/SignalProcessor.ts
+++ b/packages/ts/generator-plugin-signals/src/SignalProcessor.ts
@@ -18,6 +18,15 @@ const signals = ['NumberSignal', 'ValueSignal', 'ListSignal'];
 const genericSignals = ['ValueSignal', 'ListSignal'];
 const collectionSignals = ['ListSignal'];
 
+const primitiveModels = Object.freeze(
+  new Map<ts.SyntaxKind, string>([
+    [ts.SyntaxKind.StringKeyword, 'StringModel'],
+    [ts.SyntaxKind.NumberKeyword, 'NumberModel'],
+    [ts.SyntaxKind.BooleanKeyword, 'BooleanModel'],
+    [ts.SyntaxKind.ArrayType, 'ArrayModel'],
+  ]),
+);
+
 export default class SignalProcessor {
   readonly #dependencyManager: DependencyManager;
   readonly #owner: Plugin;
@@ -48,27 +57,21 @@ export default class SignalProcessor {
       transform((tsNode) => {
         if (ts.isFunctionDeclaration(tsNode) && tsNode.name && this.#methods.has(tsNode.name.text)) {
           const signalId = this.#replaceSignalImport(tsNode);
-          let initialValue: ts.Expression = signalId.text.startsWith('NumberSignal')
-            ? ts.factory.createNumericLiteral('0')
-            : ts.factory.createIdentifier('undefined');
           const filteredParams = tsNode.parameters.filter(
             (p) => !p.type || !ts.isTypeReferenceNode(p.type) || p.type.typeName !== initTypeId,
           );
           // `filteredParams` can be altered after, need to store the param names now
           const paramNames = filteredParams.map((p) => (p.name as ts.Identifier).text).join(', ');
           const isCollectionSignal = collectionSignals.includes(signalId.text);
-          let genericReturnType;
-          if (genericSignals.includes(signalId.text)) {
-            genericReturnType = (tsNode.type as ts.TypeReferenceNode).typeArguments![0];
-            if (!isCollectionSignal) {
-              const defaultValueType = SignalProcessor.#getDefaultValueType(genericReturnType);
-              if (defaultValueType) {
-                const { alias, param } = SignalProcessor.#createDefaultValueParameter(defaultValueType);
-                initialValue = alias;
-                filteredParams.push(param);
-              }
-            }
+
+          const { defaultValueExpression, defaultValueParam, genericReturnType } = this.#createDefaultValue(
+            signalId,
+            tsNode,
+          );
+          if (defaultValueParam) {
+            filteredParams.push(defaultValueParam);
           }
+
           const returnType = genericReturnType ?? signalId;
           if (filteredParams.length > 0) {
             functionParams.set(tsNode.name.text, filteredParams);
@@ -83,7 +86,9 @@ export default class SignalProcessor {
               transform((node) => (ts.isIdentifier(node) && node.text === SIGNAL ? signalId : node)),
               transform((node) => (ts.isIdentifier(node) && node.text === RETURN_TYPE ? returnType : node)),
               transform((node) => (ts.isIdentifier(node) && node.text === CONNECT_CLIENT ? connectClientId : node)),
-              transform((node) => (ts.isIdentifier(node) && node.text === INITIAL_VALUE ? initialValue : node)),
+              transform((node) =>
+                ts.isIdentifier(node) && node.text === INITIAL_VALUE ? defaultValueExpression : node,
+              ),
             ],
           );
         }
@@ -135,6 +140,50 @@ export default class SignalProcessor {
     );
   }
 
+  #createDefaultValue(signalId: ts.Identifier, functionDeclaration: FunctionDeclaration) {
+    const defaultValue: {
+      defaultValueExpression: ts.Expression | ts.Identifier;
+      defaultValueParam: ts.ParameterDeclaration | undefined;
+      genericReturnType: ts.TypeNode | undefined;
+    } = {
+      defaultValueExpression: signalId.text.startsWith('NumberSignal')
+        ? ts.factory.createNumericLiteral('0')
+        : ts.factory.createIdentifier('undefined'),
+      defaultValueParam: undefined,
+      genericReturnType: undefined,
+    };
+
+    if (!genericSignals.includes(signalId.text)) {
+      return defaultValue;
+    }
+
+    defaultValue.genericReturnType = (functionDeclaration.type as ts.TypeReferenceNode).typeArguments![0];
+
+    if (collectionSignals.includes(signalId.text)) {
+      return defaultValue;
+    }
+
+    const defaultValueType = SignalProcessor.#getDefaultValueType(defaultValue.genericReturnType);
+    if (!defaultValueType) {
+      return defaultValue;
+    }
+
+    defaultValue.defaultValueParam = SignalProcessor.#createDefaultValueParameter(defaultValueType);
+    const emptyValueExpression = this.#createEmptyValueExpression(defaultValueType);
+
+    defaultValue.defaultValueExpression = ts.factory.createBinaryExpression(
+      ts.factory.createPropertyAccessChain(
+        ts.factory.createIdentifier('options'),
+        ts.factory.createToken(ts.SyntaxKind.QuestionDotToken),
+        ts.factory.createIdentifier('defaultValue'),
+      ),
+      ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken),
+      emptyValueExpression,
+    );
+
+    return defaultValue;
+  }
+
   static #getDefaultValueType(node: ts.Node) {
     if (
       ts.isUnionTypeNode(node) &&
@@ -145,23 +194,115 @@ export default class SignalProcessor {
     ) {
       return node.types[0].typeArguments[0];
     }
-
     return undefined;
   }
 
-  static #createDefaultValueParameter(returnType: ts.TypeNode) {
-    const alias = createFullyUniqueIdentifier('defaultValue');
-    const bindingPattern = ts.factory.createObjectBindingPattern([
-      ts.factory.createBindingElement(undefined, ts.factory.createIdentifier('defaultValue'), alias, undefined),
-    ]);
+  static #createDefaultValueParameter(defaultValueType: ts.TypeNode) {
     const paramType = ts.factory.createTypeLiteralNode([
-      ts.factory.createPropertySignature(undefined, ts.factory.createIdentifier('defaultValue'), undefined, returnType),
+      ts.factory.createPropertySignature(
+        undefined,
+        ts.factory.createIdentifier('defaultValue'),
+        undefined,
+        defaultValueType,
+      ),
     ]);
-    // Return both the alias and the full parameter
-    return {
-      alias,
-      param: ts.factory.createParameterDeclaration(undefined, undefined, bindingPattern, undefined, paramType),
-    };
+
+    return ts.factory.createParameterDeclaration(
+      undefined,
+      undefined,
+      'options',
+      ts.factory.createToken(ts.SyntaxKind.QuestionToken),
+      paramType,
+    );
+  }
+
+  static #isDefaultValueTypeNullable(defaultValueType: ts.TypeNode) {
+    return (
+      ts.isUnionTypeNode(defaultValueType) &&
+      defaultValueType.types.length &&
+      defaultValueType.types.length > 1 &&
+      defaultValueType.types.map((t) => t.kind).includes(ts.SyntaxKind.UndefinedKeyword)
+    );
+  }
+
+  #createEmptyValueExpression(defaultValueType: ts.UnionTypeNode) {
+    if (SignalProcessor.#isDefaultValueTypeNullable(defaultValueType)) {
+      return ts.factory.createIdentifier('undefined');
+    }
+    const importedModelUniqueId = this.#determineModelImportUniqueIdentifier(defaultValueType);
+    return ts.factory.createCallExpression(
+      ts.factory.createPropertyAccessExpression(importedModelUniqueId, 'createEmptyValue'),
+      undefined,
+      [],
+    );
+  }
+
+  #determineModelImportUniqueIdentifier(returnTypeNode: ts.UnionTypeNode) {
+    let modelName = primitiveModels.get(returnTypeNode.types[0].kind);
+    let entityName;
+    if (modelName === undefined) {
+      const { entityName: e, modelName: m } = SignalProcessor.#extractModelNameFromTypeNode(returnTypeNode);
+      modelName = m;
+      entityName = e;
+    }
+    const modelImportUniqueId =
+      this.#getExistingEntityModelUniqueIdentifier(modelName) ?? createFullyUniqueIdentifier(modelName);
+
+    this.#addModelImport(entityName, modelName, modelImportUniqueId);
+    return modelImportUniqueId;
+  }
+
+  static #extractModelNameFromTypeNode(returnTypeNode: ts.UnionTypeNode) {
+    if (ts.isTypeReferenceNode(returnTypeNode.types[0])) {
+      const typeIdentifier = returnTypeNode.types[0].typeName;
+      if (ts.isIdentifier(typeIdentifier)) {
+        const entityName = typeIdentifier.text;
+        const modelName = `${entityName}Model`;
+        return { entityName, modelName };
+      }
+    }
+    throw new Error('Unsupported type reference node');
+  }
+
+  #getExistingEntityModelUniqueIdentifier(modelName: string) {
+    const { imports } = this.#dependencyManager;
+    return (
+      imports.named.getIdentifier('@vaadin/hilla-lit-form', modelName) ??
+      imports.default.iter().find(([path]) => path.endsWith(`/${modelName}.js`))?.[1]
+    );
+  }
+
+  #addModelImport(
+    entityName: string | undefined,
+    modelName: string | undefined,
+    modelNameUniqueId: ts.Identifier | undefined,
+  ) {
+    if (modelName) {
+      if (primitiveModels.values().find((primitiveModel) => primitiveModel === modelName)) {
+        const { imports } = this.#dependencyManager;
+        const importedModel = imports.named.getIdentifier('@vaadin/hilla-lit-form', modelName);
+        if (importedModel === undefined) {
+          imports.named.add('@vaadin/hilla-lit-form', modelName, false, modelNameUniqueId);
+        }
+      } else {
+        this.#addObjectModelImport(entityName!, modelName, modelNameUniqueId!);
+      }
+    }
+  }
+
+  #addObjectModelImport(entityName: string, modelName: string, modelNameUniqueId: ts.Identifier) {
+    const { imports } = this.#dependencyManager;
+    const entityImport = imports.default
+      .iter()
+      .map(([path]) => path)
+      .find((path) => path.startsWith('./') && path.endsWith(`/${entityName}.js`));
+    if (entityImport) {
+      const entityModelImportPath = entityImport.replace(`/${entityName}.js`, `/${modelName}.js`);
+      const importedModel = imports.default.paths().find((path) => path === entityModelImportPath);
+      if (importedModel === undefined) {
+        imports.default.add(entityModelImportPath, modelName, false, modelNameUniqueId);
+      }
+    }
   }
 
   #replaceSignalImport(method: FunctionDeclaration): Identifier {
diff --git a/packages/ts/generator-plugin-signals/test/SignalsEndpoints.spec.ts b/packages/ts/generator-plugin-signals/test/SignalsEndpoints.spec.ts
index b550d7f76b..266f512792 100644
--- a/packages/ts/generator-plugin-signals/test/SignalsEndpoints.spec.ts
+++ b/packages/ts/generator-plugin-signals/test/SignalsEndpoints.spec.ts
@@ -86,5 +86,19 @@ describe('SignalsPlugin', () => {
         import.meta.url,
       );
     });
+
+    it('correctly generates service with automatic default values for value signals of primitive types', async () => {
+      const generator = new Generator([BackbonePlugin, SignalsPlugin], {
+        logger: new LoggerFactory({ name: 'signals-plugin-test', verbose: true }),
+      });
+      const input = await readFile(new URL('./hilla-openapi-default-value.json', import.meta.url), 'utf8');
+      const files = await generator.process(input);
+
+      const generatedValueSignalService = files.find((f) => f.name === 'PrimitiveTypeValueSignalService.ts')!;
+      await expect(await generatedValueSignalService.text()).toMatchSnapshot(
+        `PrimitiveTypeValueSignalService.snap.ts`,
+        import.meta.url,
+      );
+    });
   });
 });
diff --git a/packages/ts/generator-plugin-signals/test/fixtures/PrimitiveTypeValueSignalService.snap.ts b/packages/ts/generator-plugin-signals/test/fixtures/PrimitiveTypeValueSignalService.snap.ts
new file mode 100644
index 0000000000..be55b6e061
--- /dev/null
+++ b/packages/ts/generator-plugin-signals/test/fixtures/PrimitiveTypeValueSignalService.snap.ts
@@ -0,0 +1,49 @@
+import { ArrayModel as ArrayModel_1, BooleanModel as BooleanModel_1, NumberModel as NumberModel_1, StringModel as StringModel_1 } from "@vaadin/hilla-lit-form";
+import { ValueSignal as ValueSignal_1 } from "@vaadin/hilla-react-signals";
+import client_1 from "./connect-client.default.js";
+function anotherStringValueSignal_1(options?: {
+    defaultValue: string;
+}): ValueSignal_1<string> {
+    return new ValueSignal_1(options?.defaultValue ?? StringModel_1.createEmptyValue(), { client: client_1, endpoint: "PrimitiveTypeValueSignalService", method: "anotherStringValueSignal" });
+}
+function booleanValueSignal_1(options?: {
+    defaultValue: boolean;
+}): ValueSignal_1<boolean> {
+    return new ValueSignal_1(options?.defaultValue ?? BooleanModel_1.createEmptyValue(), { client: client_1, endpoint: "PrimitiveTypeValueSignalService", method: "booleanValueSignal" });
+}
+function booleanValueSignalNullable_1(options?: {
+    defaultValue: boolean | undefined;
+}): ValueSignal_1<boolean | undefined> {
+    return new ValueSignal_1(options?.defaultValue ?? undefined, { client: client_1, endpoint: "PrimitiveTypeValueSignalService", method: "booleanValueSignalNullable" });
+}
+function doubleValueSignal_1(options?: {
+    defaultValue: number;
+}): ValueSignal_1<number> {
+    return new ValueSignal_1(options?.defaultValue ?? NumberModel_1.createEmptyValue(), { client: client_1, endpoint: "PrimitiveTypeValueSignalService", method: "doubleValueSignal" });
+}
+function doubleValueSignalNullable_1(options?: {
+    defaultValue: number | undefined;
+}): ValueSignal_1<number | undefined> {
+    return new ValueSignal_1(options?.defaultValue ?? undefined, { client: client_1, endpoint: "PrimitiveTypeValueSignalService", method: "doubleValueSignalNullable" });
+}
+function stringArrayValueSignal_1(options?: {
+    defaultValue: Array<string>;
+}): ValueSignal_1<Array<string>> {
+    return new ValueSignal_1(options?.defaultValue ?? ArrayModel_1.createEmptyValue(), { client: client_1, endpoint: "PrimitiveTypeValueSignalService", method: "stringArrayValueSignal" });
+}
+function stringArrayValueSignalNullable_1(options?: {
+    defaultValue: Array<string | undefined>;
+}): ValueSignal_1<Array<string | undefined>> {
+    return new ValueSignal_1(options?.defaultValue ?? ArrayModel_1.createEmptyValue(), { client: client_1, endpoint: "PrimitiveTypeValueSignalService", method: "stringArrayValueSignalNullable" });
+}
+function stringValueSignal_1(options?: {
+    defaultValue: string;
+}): ValueSignal_1<string> {
+    return new ValueSignal_1(options?.defaultValue ?? StringModel_1.createEmptyValue(), { client: client_1, endpoint: "PrimitiveTypeValueSignalService", method: "stringValueSignal" });
+}
+function stringValueSignalNullable_1(options?: {
+    defaultValue: string | undefined;
+}): ValueSignal_1<string | undefined> {
+    return new ValueSignal_1(options?.defaultValue ?? undefined, { client: client_1, endpoint: "PrimitiveTypeValueSignalService", method: "stringValueSignalNullable" });
+}
+export { anotherStringValueSignal_1 as anotherStringValueSignal, booleanValueSignal_1 as booleanValueSignal, booleanValueSignalNullable_1 as booleanValueSignalNullable, doubleValueSignal_1 as doubleValueSignal, doubleValueSignalNullable_1 as doubleValueSignalNullable, stringArrayValueSignal_1 as stringArrayValueSignal, stringArrayValueSignalNullable_1 as stringArrayValueSignalNullable, stringValueSignal_1 as stringValueSignal, stringValueSignalNullable_1 as stringValueSignalNullable };
diff --git a/packages/ts/generator-plugin-signals/test/fixtures/SignalServiceMix.snap.ts b/packages/ts/generator-plugin-signals/test/fixtures/SignalServiceMix.snap.ts
index 00586ef275..64650b71af 100644
--- a/packages/ts/generator-plugin-signals/test/fixtures/SignalServiceMix.snap.ts
+++ b/packages/ts/generator-plugin-signals/test/fixtures/SignalServiceMix.snap.ts
@@ -1,29 +1,36 @@
 import { EndpointRequestInit as EndpointRequestInit_1 } from "@vaadin/hilla-frontend";
+import { ArrayModel as ArrayModel_1 } from "@vaadin/hilla-lit-form";
 import { ListSignal as ListSignal_1, ValueSignal as ValueSignal_1 } from "@vaadin/hilla-react-signals";
 import type Person_1 from "./com/github/taefi/data/Person.js";
+import PersonModel_1 from "./com/github/taefi/data/PersonModel.js";
 import client_1 from "./connect-client.default.js";
 async function getPerson_1(init?: EndpointRequestInit_1): Promise<Person_1 | undefined> { return client_1.call("PersonService", "getPerson", {}, init); }
+function personArraySignal_1(options?: {
+    defaultValue: Array<Person_1>;
+}): ValueSignal_1<Array<Person_1>> {
+    return new ValueSignal_1(options?.defaultValue ?? ArrayModel_1.createEmptyValue(), { client: client_1, endpoint: "PersonService", method: "personArraySignal" });
+}
 function personListSignal_1(): ListSignal_1<Person_1> {
     return new ListSignal_1({ client: client_1, endpoint: "PersonService", method: "personListSignal" });
 }
-function personSignal_1({ defaultValue: defaultValue_1 }: {
+function personSignalNotNull_1(options?: {
+    defaultValue: Person_1;
+}): ValueSignal_1<Person_1> {
+    return new ValueSignal_1(options?.defaultValue ?? PersonModel_1.createEmptyValue(), { client: client_1, endpoint: "PersonService", method: "personSignalNotNull" });
+}
+function personSignalNullable_1(isAdult: boolean, options?: {
     defaultValue: Person_1 | undefined;
 }): ValueSignal_1<Person_1 | undefined> {
-    return new ValueSignal_1(defaultValue_1, { client: client_1, endpoint: "PersonService", method: "personSignal" });
+    return new ValueSignal_1(options?.defaultValue ?? undefined, { client: client_1, endpoint: "PersonService", method: "personSignalNullable", params: { isAdult } });
 }
-function personSignalWithParams_1(dummyBoolean: boolean, dummyString: string | undefined, { defaultValue: defaultValue_2 }: {
+function personSignalWithParams_1(dummyBoolean: boolean, dummyString: string | undefined, options?: {
     defaultValue: Person_1 | undefined;
 }): ValueSignal_1<Person_1 | undefined> {
-    return new ValueSignal_1(defaultValue_2, { client: client_1, endpoint: "PersonService", method: "personSignalWithParams", params: { dummyBoolean, dummyString } });
-}
-function personSignalNonNull_1({ defaultValue: defaultValue_3 }: {
-    defaultValue: Person_1;
-}): ValueSignal_1<Person_1> {
-    return new ValueSignal_1(defaultValue_3, { client: client_1, endpoint: "PersonService", method: "personSignalNonNull" });
+    return new ValueSignal_1(options?.defaultValue ?? undefined, { client: client_1, endpoint: "PersonService", method: "personSignalWithParams", params: { dummyBoolean, dummyString } });
 }
-function personSignalNonNullWithParams_1(dummyBoolean: boolean, dummyString: string | undefined, { defaultValue: defaultValue_4 }: {
+function personSignalNonNullWithParams_1(dummyBoolean: boolean, dummyString: string | undefined, options?: {
     defaultValue: Person_1;
 }): ValueSignal_1<Person_1> {
-    return new ValueSignal_1(defaultValue_4, { client: client_1, endpoint: "PersonService", method: "personSignalNonNullWithParams", params: { dummyBoolean, dummyString } });
+    return new ValueSignal_1(options?.defaultValue ?? PersonModel_1.createEmptyValue(), { client: client_1, endpoint: "PersonService", method: "personSignalNonNullWithParams", params: { dummyBoolean, dummyString } });
 }
-export { getPerson_1 as getPerson, personListSignal_1 as personListSignal, personSignal_1 as personSignal, personSignalNonNull_1 as personSignalNonNull, personSignalNonNullWithParams_1 as personSignalNonNullWithParams, personSignalWithParams_1 as personSignalWithParams };
+export { getPerson_1 as getPerson, personArraySignal_1 as personArraySignal, personListSignal_1 as personListSignal, personSignalNonNullWithParams_1 as personSignalNonNullWithParams, personSignalNotNull_1 as personSignalNotNull, personSignalNullable_1 as personSignalNullable, personSignalWithParams_1 as personSignalWithParams };
diff --git a/packages/ts/generator-plugin-signals/test/hilla-openapi-default-value.json b/packages/ts/generator-plugin-signals/test/hilla-openapi-default-value.json
new file mode 100644
index 0000000000..18f8fb0542
--- /dev/null
+++ b/packages/ts/generator-plugin-signals/test/hilla-openapi-default-value.json
@@ -0,0 +1,378 @@
+{
+  "openapi" : "3.0.1",
+  "info" : {
+    "title" : "Hilla Application",
+    "version" : "1.0.0"
+  },
+  "servers" : [
+    {
+      "url" : "http://localhost:8080/connect",
+      "description" : "Hilla Backend"
+    }
+  ],
+  "tags" : [
+    {
+      "name" : "PrimitiveTypeValueSignalService",
+      "x-class-name" : "com.github.taefi.services.PrimitiveTypeValueSignalService"
+    }
+  ],
+  "paths" : {
+    "/PrimitiveTypeValueSignalService/anotherStringValueSignal" : {
+      "post" : {
+        "tags" : [
+          "PrimitiveTypeValueSignalService"
+        ],
+        "operationId" : "PrimitiveTypeValueSignalService_anotherStringValueSignal_POST",
+        "responses" : {
+          "200" : {
+            "description" : "",
+            "content" : {
+              "application/json" : {
+                "schema" : {
+                  "anyOf" : [
+                    {
+                      "$ref" : "#/components/schemas/com.vaadin.hilla.signals.ValueSignal"
+                    }
+                  ],
+                  "x-type-arguments" : {
+                    "allOf" : [
+                      {
+                        "type" : "string",
+                        "x-java-type" : "java.lang.String"
+                      }
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/PrimitiveTypeValueSignalService/booleanValueSignal" : {
+      "post" : {
+        "tags" : [
+          "PrimitiveTypeValueSignalService"
+        ],
+        "operationId" : "PrimitiveTypeValueSignalService_booleanValueSignal_POST",
+        "responses" : {
+          "200" : {
+            "description" : "",
+            "content" : {
+              "application/json" : {
+                "schema" : {
+                  "anyOf" : [
+                    {
+                      "$ref" : "#/components/schemas/com.vaadin.hilla.signals.ValueSignal"
+                    }
+                  ],
+                  "x-type-arguments" : {
+                    "allOf" : [
+                      {
+                        "type" : "boolean",
+                        "x-java-type" : "java.lang.Boolean"
+                      }
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/PrimitiveTypeValueSignalService/booleanValueSignalNullable" : {
+      "post" : {
+        "tags" : [
+          "PrimitiveTypeValueSignalService"
+        ],
+        "operationId" : "PrimitiveTypeValueSignalService_booleanValueSignalNullable_POST",
+        "responses" : {
+          "200" : {
+            "description" : "",
+            "content" : {
+              "application/json" : {
+                "schema" : {
+                  "anyOf" : [
+                    {
+                      "$ref" : "#/components/schemas/com.vaadin.hilla.signals.ValueSignal"
+                    }
+                  ],
+                  "x-type-arguments" : {
+                    "allOf" : [
+                      {
+                        "type" : "boolean",
+                        "nullable" : true,
+                        "x-java-type" : "java.lang.Boolean"
+                      }
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/PrimitiveTypeValueSignalService/doubleValueSignal" : {
+      "post" : {
+        "tags" : [
+          "PrimitiveTypeValueSignalService"
+        ],
+        "operationId" : "PrimitiveTypeValueSignalService_doubleValueSignal_POST",
+        "responses" : {
+          "200" : {
+            "description" : "",
+            "content" : {
+              "application/json" : {
+                "schema" : {
+                  "anyOf" : [
+                    {
+                      "$ref" : "#/components/schemas/com.vaadin.hilla.signals.ValueSignal"
+                    }
+                  ],
+                  "x-type-arguments" : {
+                    "allOf" : [
+                      {
+                        "type" : "number",
+                        "format" : "double",
+                        "x-java-type" : "java.lang.Double"
+                      }
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/PrimitiveTypeValueSignalService/doubleValueSignalNullable" : {
+      "post" : {
+        "tags" : [
+          "PrimitiveTypeValueSignalService"
+        ],
+        "operationId" : "PrimitiveTypeValueSignalService_doubleValueSignalNullable_POST",
+        "responses" : {
+          "200" : {
+            "description" : "",
+            "content" : {
+              "application/json" : {
+                "schema" : {
+                  "anyOf" : [
+                    {
+                      "$ref" : "#/components/schemas/com.vaadin.hilla.signals.ValueSignal"
+                    }
+                  ],
+                  "x-type-arguments" : {
+                    "allOf" : [
+                      {
+                        "type" : "number",
+                        "format" : "double",
+                        "nullable" : true,
+                        "x-java-type" : "java.lang.Double"
+                      }
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/PrimitiveTypeValueSignalService/stringArrayValueSignal" : {
+      "post" : {
+        "tags" : [
+          "PrimitiveTypeValueSignalService"
+        ],
+        "operationId" : "PrimitiveTypeValueSignalService_stringArrayValueSignal_POST",
+        "responses" : {
+          "200" : {
+            "description" : "",
+            "content" : {
+              "application/json" : {
+                "schema" : {
+                  "anyOf" : [
+                    {
+                      "$ref" : "#/components/schemas/com.vaadin.hilla.signals.ValueSignal"
+                    }
+                  ],
+                  "x-type-arguments" : {
+                    "allOf" : [
+                      {
+                        "type" : "array",
+                        "items" : {
+                          "type" : "string",
+                          "x-java-type" : "java.lang.String"
+                        },
+                        "x-java-type" : "java.lang.String[]"
+                      }
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/PrimitiveTypeValueSignalService/stringArrayValueSignalNullable" : {
+      "post" : {
+        "tags" : [
+          "PrimitiveTypeValueSignalService"
+        ],
+        "operationId" : "PrimitiveTypeValueSignalService_stringArrayValueSignalNullable_POST",
+        "responses" : {
+          "200" : {
+            "description" : "",
+            "content" : {
+              "application/json" : {
+                "schema" : {
+                  "anyOf" : [
+                    {
+                      "$ref" : "#/components/schemas/com.vaadin.hilla.signals.ValueSignal"
+                    }
+                  ],
+                  "x-type-arguments" : {
+                    "allOf" : [
+                      {
+                        "type" : "array",
+                        "items" : {
+                          "type" : "string",
+                          "nullable" : true,
+                          "x-java-type" : "java.lang.String"
+                        }
+                      }
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/PrimitiveTypeValueSignalService/stringValueSignal" : {
+      "post" : {
+        "tags" : [
+          "PrimitiveTypeValueSignalService"
+        ],
+        "operationId" : "PrimitiveTypeValueSignalService_stringValueSignal_POST",
+        "responses" : {
+          "200" : {
+            "description" : "",
+            "content" : {
+              "application/json" : {
+                "schema" : {
+                  "anyOf" : [
+                    {
+                      "$ref" : "#/components/schemas/com.vaadin.hilla.signals.ValueSignal"
+                    }
+                  ],
+                  "x-type-arguments" : {
+                    "allOf" : [
+                      {
+                        "type" : "string",
+                        "x-java-type" : "java.lang.String"
+                      }
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/PrimitiveTypeValueSignalService/stringValueSignalNullable" : {
+      "post" : {
+        "tags" : [
+          "PrimitiveTypeValueSignalService"
+        ],
+        "operationId" : "PrimitiveTypeValueSignalService_stringValueSignalNullable_POST",
+        "responses" : {
+          "200" : {
+            "description" : "",
+            "content" : {
+              "application/json" : {
+                "schema" : {
+                  "anyOf" : [
+                    {
+                      "$ref" : "#/components/schemas/com.vaadin.hilla.signals.ValueSignal"
+                    }
+                  ],
+                  "x-type-arguments" : {
+                    "allOf" : [
+                      {
+                        "type" : "string",
+                        "nullable" : true,
+                        "x-java-type" : "java.lang.String"
+                      }
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  },
+  "components" : {
+    "schemas" : {
+      "com.vaadin.hilla.signals.Signal" : {
+        "type" : "object",
+        "properties" : {
+          "id" : {
+            "type" : "string",
+            "x-java-type" : "java.lang.String"
+          },
+          "valueType" : {
+            "type" : "object",
+            "x-type-arguments" : {
+              "allOf" : [
+                {
+                  "type" : "object",
+                  "x-type-variable" : "T"
+                }
+              ]
+            },
+            "x-java-type" : "java.lang.Class"
+          }
+        },
+        "x-type-parameters" : [
+          "T"
+        ]
+      },
+      "com.vaadin.hilla.signals.ValueSignal" : {
+        "anyOf" : [
+          {
+            "$ref" : "#/components/schemas/com.vaadin.hilla.signals.Signal"
+          },
+          {
+            "type" : "object",
+            "properties" : {
+              "value" : {
+                "type" : "object",
+                "nullable" : true,
+                "x-type-variable" : "T"
+              }
+            },
+            "x-type-parameters" : [
+              "T"
+            ]
+          }
+        ],
+        "x-type-arguments" : {
+          "allOf" : [
+            {
+              "type" : "object",
+              "x-type-variable" : "T"
+            }
+          ]
+        }
+      }
+    }
+  }
+}
diff --git a/packages/ts/generator-plugin-signals/test/hilla-openapi-mix.json b/packages/ts/generator-plugin-signals/test/hilla-openapi-mix.json
index 8e4346ba4b..ee00a86eed 100644
--- a/packages/ts/generator-plugin-signals/test/hilla-openapi-mix.json
+++ b/packages/ts/generator-plugin-signals/test/hilla-openapi-mix.json
@@ -275,6 +275,44 @@
         }
       }
     },
+    "/PersonService/personArraySignal" : {
+      "post" : {
+        "tags" : [
+          "PersonService"
+        ],
+        "operationId" : "PersonService_personArraySignal_POST",
+        "responses" : {
+          "200" : {
+            "description" : "",
+            "content" : {
+              "application/json" : {
+                "schema" : {
+                  "anyOf" : [
+                    {
+                      "$ref" : "#/components/schemas/com.vaadin.hilla.signals.ValueSignal"
+                    }
+                  ],
+                  "x-type-arguments" : {
+                    "allOf" : [
+                      {
+                        "type" : "array",
+                        "items" : {
+                          "anyOf" : [
+                            {
+                              "$ref" : "#/components/schemas/com.github.taefi.data.Person"
+                            }
+                          ]
+                        }
+                      }
+                    ]
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    },
     "/PersonService/personListSignal" : {
       "post" : {
         "tags" : [
@@ -310,12 +348,12 @@
         }
       }
     },
-    "/PersonService/personSignal" : {
+    "/PersonService/personSignalNotNull" : {
       "post" : {
         "tags" : [
           "PersonService"
         ],
-        "operationId" : "PersonService_personSignal_POST",
+        "operationId" : "PersonService_personSignalNotNull_POST",
         "responses" : {
           "200" : {
             "description" : "",
@@ -327,13 +365,12 @@
                       "$ref" : "#/components/schemas/com.vaadin.hilla.signals.ValueSignal"
                     }
                   ],
-                  "x-type-arguments": {
-                    "allOf": [
+                  "x-type-arguments" : {
+                    "allOf" : [
                       {
-                        "nullable": true,
-                        "anyOf": [
+                        "anyOf" : [
                           {
-                            "$ref": "#/components/schemas/com.github.taefi.data.Person"
+                            "$ref" : "#/components/schemas/com.github.taefi.data.Person"
                           }
                         ]
                       }
@@ -346,26 +383,21 @@
         }
       }
     },
-    "/PersonService/personSignalWithParams" : {
+    "/PersonService/personSignalNullable" : {
       "post" : {
         "tags" : [
           "PersonService"
         ],
-        "operationId" : "PersonService_personSignalWithParams_POST",
+        "operationId" : "PersonService_personSignalNullable_POST",
         "requestBody" : {
-          "content": {
-            "application/json": {
-              "schema": {
-                "type": "object",
-                "properties": {
-                  "dummyBoolean": {
-                    "type": "boolean",
-                    "x-java-type": "java.lang.Boolean"
-                  },
-                  "dummyString": {
-                    "type": "string",
-                    "x-java-type": "java.lang.String",
-                    "nullable": true
+          "content" : {
+            "application/json" : {
+              "schema" : {
+                "type" : "object",
+                "properties" : {
+                  "isAdult" : {
+                    "type" : "boolean",
+                    "x-java-type" : "boolean"
                   }
                 }
               }
@@ -383,13 +415,13 @@
                       "$ref" : "#/components/schemas/com.vaadin.hilla.signals.ValueSignal"
                     }
                   ],
-                  "x-type-arguments": {
-                    "allOf": [
+                  "x-type-arguments" : {
+                    "allOf" : [
                       {
-                        "nullable": true,
-                        "anyOf": [
+                        "nullable" : true,
+                        "anyOf" : [
                           {
-                            "$ref": "#/components/schemas/com.github.taefi.data.Person"
+                            "$ref" : "#/components/schemas/com.github.taefi.data.Person"
                           }
                         ]
                       }
@@ -402,12 +434,32 @@
         }
       }
     },
-    "/PersonService/personSignalNonNull" : {
+    "/PersonService/personSignalWithParams" : {
       "post" : {
         "tags" : [
           "PersonService"
         ],
-        "operationId" : "PersonService_personSignalNonNull_POST",
+        "operationId" : "PersonService_personSignalWithParams_POST",
+        "requestBody" : {
+          "content": {
+            "application/json": {
+              "schema": {
+                "type": "object",
+                "properties": {
+                  "dummyBoolean": {
+                    "type": "boolean",
+                    "x-java-type": "java.lang.Boolean"
+                  },
+                  "dummyString": {
+                    "type": "string",
+                    "x-java-type": "java.lang.String",
+                    "nullable": true
+                  }
+                }
+              }
+            }
+          }
+        },
         "responses" : {
           "200" : {
             "description" : "",
@@ -422,7 +474,7 @@
                   "x-type-arguments": {
                     "allOf": [
                       {
-                        "nullable": false,
+                        "nullable": true,
                         "anyOf": [
                           {
                             "$ref": "#/components/schemas/com.github.taefi.data.Person"