diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 39c1f2b3a6c85..4ae5675ad0f09 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -369,11 +369,11 @@ repos:
         files: ^pandas/
         exclude: ^pandas/tests/
         types: [python]
-    -   id: no-bool-in-core-generic
-        name: Use bool_t instead of bool in pandas/core/generic.py
-        entry: python scripts/no_bool_in_generic.py
+    -   id: no-bool-in-core-ndframe
+        name: Use bool_t instead of bool in pandas/core/ndframe.py
+        entry: python scripts/no_bool_in_ndframe.py
         language: python
-        files: ^pandas/core/generic\.py$
+        files: ^pandas/core/ndframe\.py$
     -   id: no-return-exception
         name: Use raise instead of return for exceptions
         language: pygrep
diff --git a/pandas/_typing.py b/pandas/_typing.py
index 8d3044a978291..bb518e6232c3b 100644
--- a/pandas/_typing.py
+++ b/pandas/_typing.py
@@ -50,7 +50,6 @@
     )
     from pandas.core.arrays.base import ExtensionArray
     from pandas.core.frame import DataFrame
-    from pandas.core.generic import NDFrame
     from pandas.core.groupby.generic import (
         DataFrameGroupBy,
         GroupBy,
@@ -63,6 +62,7 @@
         SingleArrayManager,
         SingleBlockManager,
     )
+    from pandas.core.ndframe import NDFrame
     from pandas.core.resample import Resampler
     from pandas.core.series import Series
     from pandas.core.window.rolling import BaseWindow
diff --git a/pandas/core/arraylike.py b/pandas/core/arraylike.py
index 1d10d797866f4..0e483da8d0b1e 100644
--- a/pandas/core/arraylike.py
+++ b/pandas/core/arraylike.py
@@ -262,8 +262,8 @@ def array_ufunc(self, ufunc: np.ufunc, method: str, *inputs: Any, **kwargs: Any)
         DataFrame,
         Series,
     )
-    from pandas.core.generic import NDFrame
     from pandas.core.internals import BlockManager
+    from pandas.core.ndframe import NDFrame
 
     cls = type(self)
 
diff --git a/pandas/core/computation/align.py b/pandas/core/computation/align.py
index 2e7a0f842ee6d..c164c60cf453f 100644
--- a/pandas/core/computation/align.py
+++ b/pandas/core/computation/align.py
@@ -31,8 +31,8 @@
 if TYPE_CHECKING:
     from pandas._typing import F
 
-    from pandas.core.generic import NDFrame
     from pandas.core.indexes.api import Index
+    from pandas.core.ndframe import NDFrame
 
 
 def _align_core_single_unary_op(
diff --git a/pandas/core/computation/eval.py b/pandas/core/computation/eval.py
index f0127ae05182a..f58ef92c312f4 100644
--- a/pandas/core/computation/eval.py
+++ b/pandas/core/computation/eval.py
@@ -16,7 +16,7 @@
 )
 from pandas.core.computation.parsing import tokenize_string
 from pandas.core.computation.scope import ensure_scope
-from pandas.core.generic import NDFrame
+from pandas.core.ndframe import NDFrame
 
 from pandas.io.formats.printing import pprint_thing
 
diff --git a/pandas/core/dtypes/generic.py b/pandas/core/dtypes/generic.py
index 5904ba4895aef..6e5e42a5d1d4b 100644
--- a/pandas/core/dtypes/generic.py
+++ b/pandas/core/dtypes/generic.py
@@ -28,7 +28,7 @@
         PeriodArray,
         TimedeltaArray,
     )
-    from pandas.core.generic import NDFrame
+    from pandas.core.ndframe import NDFrame
 
 
 # define abstract base classes to enable isinstance type checking on our
diff --git a/pandas/core/frame.py b/pandas/core/frame.py
index 4f13ead4005e7..b102f65bf0492 100644
--- a/pandas/core/frame.py
+++ b/pandas/core/frame.py
@@ -179,7 +179,6 @@
     sanitize_array,
     sanitize_masked_array,
 )
-from pandas.core.generic import NDFrame
 from pandas.core.indexers import check_key_length
 from pandas.core.indexes.api import (
     DatetimeIndex,
@@ -213,6 +212,7 @@
     to_arrays,
     treat_as_nested,
 )
+from pandas.core.ndframe import NDFrame
 from pandas.core.reshape.melt import melt
 from pandas.core.series import Series
 from pandas.core.shared_docs import _shared_docs
diff --git a/pandas/core/groupby/generic.py b/pandas/core/groupby/generic.py
index d6482b61a536d..46fd2e3ee49d4 100644
--- a/pandas/core/groupby/generic.py
+++ b/pandas/core/groupby/generic.py
@@ -97,7 +97,7 @@
 from pandas.plotting import boxplot_frame_groupby
 
 if TYPE_CHECKING:
-    from pandas.core.generic import NDFrame
+    from pandas.core.ndframe import NDFrame
 
 # TODO(typing) the return value on this callable should be any *scalar*.
 AggScalar = Union[str, Callable[..., Any]]
diff --git a/pandas/core/groupby/groupby.py b/pandas/core/groupby/groupby.py
index fd9a06a06cfa7..a87beaab16f35 100644
--- a/pandas/core/groupby/groupby.py
+++ b/pandas/core/groupby/groupby.py
@@ -106,7 +106,6 @@ class providing the base-class of operations.
 )
 import pandas.core.common as com
 from pandas.core.frame import DataFrame
-from pandas.core.generic import NDFrame
 from pandas.core.groupby import (
     base,
     numba_,
@@ -125,6 +124,7 @@ class providing the base-class of operations.
     default_index,
 )
 from pandas.core.internals.blocks import ensure_block_shape
+from pandas.core.ndframe import NDFrame
 from pandas.core.series import Series
 from pandas.core.sorting import get_group_index_sorter
 from pandas.core.util.numba_ import (
diff --git a/pandas/core/groupby/grouper.py b/pandas/core/groupby/grouper.py
index d77ad59a4bb82..8ef3c1ce1ff7e 100644
--- a/pandas/core/groupby/grouper.py
+++ b/pandas/core/groupby/grouper.py
@@ -50,7 +50,7 @@
 from pandas.io.formats.printing import pprint_thing
 
 if TYPE_CHECKING:
-    from pandas.core.generic import NDFrame
+    from pandas.core.ndframe import NDFrame
 
 
 class Grouper:
diff --git a/pandas/core/groupby/ops.py b/pandas/core/groupby/ops.py
index bff61ec135d74..f72d09277f3c9 100644
--- a/pandas/core/groupby/ops.py
+++ b/pandas/core/groupby/ops.py
@@ -96,7 +96,7 @@
 )
 
 if TYPE_CHECKING:
-    from pandas.core.generic import NDFrame
+    from pandas.core.ndframe import NDFrame
 
 
 class WrappedCythonOp:
diff --git a/pandas/core/generic.py b/pandas/core/ndframe.py
similarity index 100%
rename from pandas/core/generic.py
rename to pandas/core/ndframe.py
diff --git a/pandas/core/resample.py b/pandas/core/resample.py
index ebb803ee8f3b4..d75148b12cfa5 100644
--- a/pandas/core/resample.py
+++ b/pandas/core/resample.py
@@ -57,10 +57,6 @@
 from pandas.core.apply import ResamplerWindowApply
 from pandas.core.base import PandasObject
 import pandas.core.common as com
-from pandas.core.generic import (
-    NDFrame,
-    _shared_docs,
-)
 from pandas.core.groupby.generic import SeriesGroupBy
 from pandas.core.groupby.groupby import (
     BaseGroupBy,
@@ -82,6 +78,10 @@
     TimedeltaIndex,
     timedelta_range,
 )
+from pandas.core.ndframe import (
+    NDFrame,
+    _shared_docs,
+)
 
 from pandas.tseries.frequencies import (
     is_subperiod,
diff --git a/pandas/core/reshape/concat.py b/pandas/core/reshape/concat.py
index f8220649bf890..566e08be1b1b7 100644
--- a/pandas/core/reshape/concat.py
+++ b/pandas/core/reshape/concat.py
@@ -60,7 +60,7 @@
         DataFrame,
         Series,
     )
-    from pandas.core.generic import NDFrame
+    from pandas.core.ndframe import NDFrame
 
 # ---------------------------------------------------------------------
 # Concatenate DataFrame objects
diff --git a/pandas/core/sample.py b/pandas/core/sample.py
index a9b236b58a9ba..12c7fd1337e50 100644
--- a/pandas/core/sample.py
+++ b/pandas/core/sample.py
@@ -16,7 +16,7 @@
 )
 
 if TYPE_CHECKING:
-    from pandas.core.generic import NDFrame
+    from pandas.core.ndframe import NDFrame
 
 
 def preprocess_weights(obj: NDFrame, weights, axis: AxisInt) -> np.ndarray:
diff --git a/pandas/core/series.py b/pandas/core/series.py
index abe31d0dbd52a..35409cfb7ed1b 100644
--- a/pandas/core/series.py
+++ b/pandas/core/series.py
@@ -132,7 +132,6 @@
     extract_array,
     sanitize_array,
 )
-from pandas.core.generic import NDFrame
 from pandas.core.indexers import (
     disallow_ndim_indexing,
     unpack_1tuple,
@@ -156,6 +155,7 @@
     SingleArrayManager,
     SingleBlockManager,
 )
+from pandas.core.ndframe import NDFrame
 from pandas.core.shared_docs import _shared_docs
 from pandas.core.sorting import (
     ensure_key_mapped,
diff --git a/pandas/core/window/ewm.py b/pandas/core/window/ewm.py
index c0a7b2b7cc361..ae012c04a6e68 100644
--- a/pandas/core/window/ewm.py
+++ b/pandas/core/window/ewm.py
@@ -16,7 +16,7 @@
 
 if TYPE_CHECKING:
     from pandas import DataFrame, Series
-    from pandas.core.generic import NDFrame
+    from pandas.core.ndframe import NDFrame
 
 from pandas.util._decorators import doc
 
diff --git a/pandas/core/window/expanding.py b/pandas/core/window/expanding.py
index 6147f0f43c558..b2c12c47522c3 100644
--- a/pandas/core/window/expanding.py
+++ b/pandas/core/window/expanding.py
@@ -15,7 +15,7 @@
 
 if TYPE_CHECKING:
     from pandas import DataFrame, Series
-    from pandas.core.generic import NDFrame
+    from pandas.core.ndframe import NDFrame
 
 from pandas.util._decorators import doc
 
diff --git a/pandas/core/window/rolling.py b/pandas/core/window/rolling.py
index ef0524e48f9e2..84328fe9c1c80 100644
--- a/pandas/core/window/rolling.py
+++ b/pandas/core/window/rolling.py
@@ -103,8 +103,8 @@
         DataFrame,
         Series,
     )
-    from pandas.core.generic import NDFrame
     from pandas.core.groupby.ops import BaseGrouper
+    from pandas.core.ndframe import NDFrame
 
 
 class BaseWindow(SelectionMixin):
diff --git a/pandas/io/formats/style.py b/pandas/io/formats/style.py
index 442f2ab72a1e2..13e736509f4db 100644
--- a/pandas/io/formats/style.py
+++ b/pandas/io/formats/style.py
@@ -48,7 +48,7 @@
     DataFrame,
     Series,
 )
-from pandas.core.generic import NDFrame
+from pandas.core.ndframe import NDFrame
 from pandas.core.shared_docs import _shared_docs
 
 from pandas.io.formats.format import save_to_buffer
diff --git a/pandas/io/json/_json.py b/pandas/io/json/_json.py
index 66991eab54671..c79e4b52a5f60 100644
--- a/pandas/io/json/_json.py
+++ b/pandas/io/json/_json.py
@@ -78,7 +78,7 @@
 from pandas.io.parsers.readers import validate_integer
 
 if TYPE_CHECKING:
-    from pandas.core.generic import NDFrame
+    from pandas.core.ndframe import NDFrame
 
 FrameSeriesStrT = TypeVar("FrameSeriesStrT", bound=Literal["frame", "series"])
 
diff --git a/pandas/tests/generic/__init__.py b/pandas/tests/ndframe/__init__.py
similarity index 100%
rename from pandas/tests/generic/__init__.py
rename to pandas/tests/ndframe/__init__.py
diff --git a/pandas/tests/generic/test_duplicate_labels.py b/pandas/tests/ndframe/test_duplicate_labels.py
similarity index 100%
rename from pandas/tests/generic/test_duplicate_labels.py
rename to pandas/tests/ndframe/test_duplicate_labels.py
diff --git a/pandas/tests/generic/test_finalize.py b/pandas/tests/ndframe/test_finalize.py
similarity index 100%
rename from pandas/tests/generic/test_finalize.py
rename to pandas/tests/ndframe/test_finalize.py
diff --git a/pandas/tests/generic/test_frame.py b/pandas/tests/ndframe/test_frame.py
similarity index 100%
rename from pandas/tests/generic/test_frame.py
rename to pandas/tests/ndframe/test_frame.py
diff --git a/pandas/tests/generic/test_generic.py b/pandas/tests/ndframe/test_frame_and_series.py
similarity index 100%
rename from pandas/tests/generic/test_generic.py
rename to pandas/tests/ndframe/test_frame_and_series.py
diff --git a/pandas/tests/generic/test_label_or_level_utils.py b/pandas/tests/ndframe/test_label_or_level_utils.py
similarity index 100%
rename from pandas/tests/generic/test_label_or_level_utils.py
rename to pandas/tests/ndframe/test_label_or_level_utils.py
diff --git a/pandas/tests/generic/test_series.py b/pandas/tests/ndframe/test_series.py
similarity index 100%
rename from pandas/tests/generic/test_series.py
rename to pandas/tests/ndframe/test_series.py
diff --git a/pandas/tests/generic/test_to_xarray.py b/pandas/tests/ndframe/test_to_xarray.py
similarity index 100%
rename from pandas/tests/generic/test_to_xarray.py
rename to pandas/tests/ndframe/test_to_xarray.py
diff --git a/scripts/no_bool_in_generic.py b/scripts/no_bool_in_ndframe.py
similarity index 91%
rename from scripts/no_bool_in_generic.py
rename to scripts/no_bool_in_ndframe.py
index 92e2c0983b25b..1e5243c83848d 100644
--- a/scripts/no_bool_in_generic.py
+++ b/scripts/no_bool_in_ndframe.py
@@ -1,11 +1,11 @@
 """
-Check that pandas/core/generic.py doesn't use bool as a type annotation.
+Check that pandas/core/ndframe.py doesn't use bool as a type annotation.
 
 There is already the method `bool`, so the alias `bool_t` should be used instead.
 
 This is meant to be run as a pre-commit hook - to run it manually, you can do:
 
-    pre-commit run no-bool-in-core-generic --all-files
+    pre-commit run no-bool-in-core-ndframe --all-files
 
 The function `visit` is adapted from a function by the same name in pyupgrade:
 https://github.com/asottile/pyupgrade/blob/5495a248f2165941c5d3b82ac3226ba7ad1fa59d/pyupgrade/_data.py#L70-L113
@@ -57,7 +57,7 @@ def replace_bool_with_bool_t(to_replace, content: str) -> str:
     return "\n".join(new_lines)
 
 
-def check_for_bool_in_generic(content: str) -> tuple[bool, str]:
+def check_for_bool_in_ndframe(content: str) -> tuple[bool, str]:
     tree = ast.parse(content)
     to_replace = visit(tree)
 
@@ -77,7 +77,7 @@ def main(argv: Sequence[str] | None = None) -> None:
     for path in args.paths:
         with open(path, encoding="utf-8") as fd:
             content = fd.read()
-        mutated, new_content = check_for_bool_in_generic(content)
+        mutated, new_content = check_for_bool_in_ndframe(content)
         if mutated:
             with open(path, "w", encoding="utf-8") as fd:
                 fd.write(new_content)
diff --git a/scripts/tests/test_no_bool_in_generic.py b/scripts/tests/test_no_bool_in_ndframe.py
similarity index 68%
rename from scripts/tests/test_no_bool_in_generic.py
rename to scripts/tests/test_no_bool_in_ndframe.py
index 0bc91c5d1cf1e..ebbb75e066b97 100644
--- a/scripts/tests/test_no_bool_in_generic.py
+++ b/scripts/tests/test_no_bool_in_ndframe.py
@@ -1,4 +1,4 @@
-from scripts.no_bool_in_generic import check_for_bool_in_generic
+from scripts.no_bool_in_ndframe import check_for_bool_in_ndframe
 
 BAD_FILE = "def foo(a: bool) -> bool:\n    return bool(0)"
 GOOD_FILE = "def foo(a: bool_t) -> bool_t:\n    return bool(0)"
@@ -6,7 +6,7 @@
 
 def test_bad_file_with_replace():
     content = BAD_FILE
-    mutated, result = check_for_bool_in_generic(content)
+    mutated, result = check_for_bool_in_ndframe(content)
     expected = GOOD_FILE
     assert result == expected
     assert mutated
@@ -14,7 +14,7 @@ def test_bad_file_with_replace():
 
 def test_good_file_with_replace():
     content = GOOD_FILE
-    mutated, result = check_for_bool_in_generic(content)
+    mutated, result = check_for_bool_in_ndframe(content)
     expected = content
     assert result == expected
     assert not mutated