diff --git a/homeassistant/helpers/area_registry.py b/homeassistant/helpers/area_registry.py
index 1d785fd0ceeff8f9525af6c871d124908fa33992..95f889281fcfbb602de303e15d9bbec9f29fe159 100644
--- a/homeassistant/helpers/area_registry.py
+++ b/homeassistant/helpers/area_registry.py
@@ -2,11 +2,10 @@
 from __future__ import annotations
 
 from collections import OrderedDict
-from collections.abc import Container, Iterable, MutableMapping
+from collections.abc import Iterable, MutableMapping
+import dataclasses
 from typing import Any, Literal, TypedDict, cast
 
-import attr
-
 from homeassistant.core import HomeAssistant, callback
 from homeassistant.util import slugify
 
@@ -29,26 +28,15 @@ class EventAreaRegistryUpdatedData(TypedDict):
     area_id: str
 
 
-@attr.s(slots=True, frozen=True)
+@dataclasses.dataclass(frozen=True, kw_only=True, slots=True)
 class AreaEntry:
     """Area Registry Entry."""
 
-    name: str = attr.ib()
-    normalized_name: str = attr.ib()
-    aliases: set[str] = attr.ib(
-        converter=attr.converters.default_if_none(factory=set)  # type: ignore[misc]
-    )
-    id: str | None = attr.ib(default=None)
-    picture: str | None = attr.ib(default=None)
-
-    def generate_id(self, existing_ids: Container[str]) -> None:
-        """Initialize ID."""
-        suggestion = suggestion_base = slugify(self.name)
-        tries = 1
-        while suggestion in existing_ids:
-            tries += 1
-            suggestion = f"{suggestion_base}_{tries}"
-        object.__setattr__(self, "id", suggestion)
+    aliases: set[str]
+    id: str
+    name: str
+    normalized_name: str
+    picture: str | None
 
 
 class AreaRegistryStore(Store[dict[str, list[dict[str, Any]]]]):
@@ -133,10 +121,14 @@ class AreaRegistry:
         if self.async_get_area_by_name(name):
             raise ValueError(f"The name {name} ({normalized_name}) is already in use")
 
+        area_id = self._generate_area_id(name)
         area = AreaEntry(
-            aliases=aliases, name=name, normalized_name=normalized_name, picture=picture
+            aliases=aliases or set(),
+            id=area_id,
+            name=name,
+            normalized_name=normalized_name,
+            picture=picture,
         )
-        area.generate_id(self.areas)
         assert area.id is not None
         self.areas[area.id] = area
         self._normalized_name_area_idx[normalized_name] = area.id
@@ -221,7 +213,7 @@ class AreaRegistry:
         if not new_values:
             return old
 
-        new = self.areas[area_id] = attr.evolve(old, **new_values)  # type: ignore[arg-type]
+        new = self.areas[area_id] = dataclasses.replace(old, **new_values)  # type: ignore[arg-type]
         if normalized_name is not None:
             self._normalized_name_area_idx[
                 normalized_name
@@ -273,6 +265,15 @@ class AreaRegistry:
 
         return data
 
+    def _generate_area_id(self, name: str) -> str:
+        """Generate area ID."""
+        suggestion = suggestion_base = slugify(name)
+        tries = 1
+        while suggestion in self.areas:
+            tries += 1
+            suggestion = f"{suggestion_base}_{tries}"
+        return suggestion
+
 
 @callback
 def async_get(hass: HomeAssistant) -> AreaRegistry: