I believe I have answered most of your questions in the Sections
below.
Here is a summary.
Do projects generated by create-react-app come with some kind of
ESLint configuration?
– Yes, ESLint gets installed and configured.
(Section 1 below.)
How do I enable and extend it correctly?
– It is already enabled. You expand it exactly as you already suggested
in the question, except that you don't need to change anything under
the extends attribute.
(Sections 1 & 2 below.)
ESLint is obviously integrated into Create React App in a different
way than it would be if it had been manually added to the project
using
[npm install eslint --save-dev and npm init @eslint/config ?]
– No, it's not.
Installing ESLint once again
(npm install eslint --save-dev) does add
  "devDependencies": {
    "eslint": "^7.32.0"
  }
to package.json.
But that's all it does.
The practical implications are none, because "eslint": "^7.32.0" is
already installed as a dependency via react-scripts.
I advise against running npm init @eslint/config, which is
a command that creates a .eslintrc.* configuration file.
If you do run this command, consider moving all the contents of
.eslintrc.* to package.json under eslintConfig.
Then delete the problematic .eslintrc.* file.
It might save you a lot of pain.
1
(Sections 1 & 5 below.)
one cannot run the eslint command in the project root [?]
– Yes, you can!
It's npx eslint . --ext .js
(Section 4 below.)
ESLint does not seem to be a dependency within package.json [?]
– Yes, it is!
The dependency is indirect as react-scripts depends
on ESLint and on a lot of other packages.
(Section 1 below.)
VS Code doesn't pick up that there is ESLint present [?]
– Yes, it does! Run npx eslint . --ext .js.
If you get at least one warning or error, then you know you should see
it in VS Code as well.
(Section 3 below – check out the gotchas.)
there is no .eslintrc.* file in the project root.
– Be glad there isn't! And don't put one there either!
(Section 5 below.)
0. Prerequisites
In order to be able to answer your questions, I created an App :
2
npx create-react-app how-is-eslint-integrated-into-create-react-app
I then deleted all files in the src subdirectory, and inserted my own
versions of App.js, App.css, index.js, index.css, along with
a components subdirectory that contains a Button component.
In package.json I deleted a few irrelevant lines, such as
"version": "0.1.0",
and "private": true, and the production attribute
under browserslist.
The resulting package.json :
{
  "name": "how-is-eslint-integrated-into-create-react-app",
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.2",
    "@testing-library/react": "^12.1.3",
    "@testing-library/user-event": "^13.5.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-scripts": "5.0.0",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "development": [
      "last 1 chrome version"
    ]
  }
}
When you wrote your question a little more than two years ago,
the eslintConfig attribute was
,
  "eslintConfig": {
    "extends": "react-app"
  }
whereas nowadays, it's
,
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  }
I will assume that this change makes no difference for the issues and
questions you bring up
(unless someone proves me wrong).
Another difference over the past two years – apart from the obvious
changes in version numbering – is the added web-vitals attribute :
,
    "web-vitals": "^2.1.4"
which is a package for measuring performance metrics in JavaScript.
3
Thus, web-vitals is irrelevant for your questions.
You can download the resulting
zip file containing all necessary project files.
Once downloaded – from the root of the project (directory Q59633005)
– run npm install.
Expect it to take anytime between 4 and 11 minutes to complete.
Next run npm start.
Expect your default web browser to open and
– after hitting F12 – display :
4

Now close the server from the terminal by hitting
Ctrl+C.
Take a look inside App.js. The contents are :
// App.js
import React, { useCallback, useState } from 'react';
import "./App.css";
import Button from "./components/UI/Button/Button"
function App(unUsedArgument) {
  const [unUsedVariable, setShowParagraph] = useState(true);
  const showParagraphFcn = useCallback(() => {
    setShowParagraph((prevToggle) => !prevToggle);
  },[]);
  console.log("App RUNNING");
  return (
    <div className="app">
      <h1>Hi there!</h1>
      <Button onClick={showParagraphFcn}>A Button</Button>
    </div>
  );
}
export default App;
I now have project to help answer your questions.
1. ESLint in Visual Studio Code
VS Code does not seem to recognize that there is any kind of linter
present/configured.
This is not super surprising, as ESLint is not a dependency of the
React project I just generated -- at least not according to
package.json.
The npx create-react-app ... does indeed install ESLint.
ESLint is deeply buried in the dependency tree of the react-scripts
package.
The top node for ESLint in react-scripts is eslint-config-react-app.
5
Some basic configuration is also part of the deal.
So ESLint does work out of the box.
VS Code shows a warning for unUsedVariable on line 7 of App.js
(but for some reason not for unUsedArgument on line 6).
In VS Code, expect to see :

2. How to expand ESLint
How do I expand [ESLint in a Create React App]?
To expand ESLint, you need to add rules under eslintConfig in
package.json, exactly as you have already suggested in your
question.
To try your example, replace
,
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  }
with
,
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ],
    "rules": {
      "semi": [
        "error",
        "always"
      ],
      "quotes": [
        "error",
        "double"
      ]
    }
  }
After restarting VS Code, it still shows the warning for
unUsedVariable on line 7, but now also an error on line 2 for having
single quotes instead of double quotes, and an error on line 4 for the
missing semicolon at the end of the line.

This shows that you have already correctly answered how to expand
Create React App.
For another example, consider looking at the
package.json | eslintConfig of this answer.
3. Some gotchas with VS Code
Still don't see the errors and warnings as in the screenshot
above?
It might not work, I know.
Three gotchas to check :
4. A much faster way to check if ESLint works
For starters: How do I run it?
Answer:
6
npx eslint . --ext .js

The first four lines of the response:
C:\stackexchange\stackoverflow\linting\eslint\Q59633005\src\App.js
 2:46 error    Strings must use doublequote                         quotes
 4:51 error    Missing semicolon                                    semi
 7:10 warning  'unUsedVariable' is assigned a value but never used  no-unused-vars
– In less than 10 seconds, you get the same information about errors
and warnings as in VS Code.
5. A word of warning
If you don't like hard-to-debug errors such as
Parsing error: The keyword 'import' is reserved
then don't use any .eslintrc.* files at all.
1
In my experience, you can put all ESLint configurations under
eslintConfig in package.json as described in Section 2 above.
– You won't need any .eslintrc.* files.
References
1
If you want to know why, compare this long answer with
this short answer.
2 I'm on Windows 10, but I expect all the commands
provided here to work just as fine on both Linux and macOS – except
where otherwise stated.
3 You can find that out by running npm ll.
4 I use Google Chrome Version 98.0.4758.102, 64-bit.
Running on Windows 10.
5 I got this information from
NPMGraph - Visualize NPM Module Dependencies.
6 Alternatively, use the first line below if you are on
Microsoft Windows (backslashes).
Use the second line if you are on Linux or macOS (forward slashes).
node*modules\.bin\eslint . --ext .js
node*modules/.bin/eslint . --ext .js