diff --git a/docs/blog/2025-02-21-using-apollo-graphql-with-react-in-an-nx-workspace.md b/docs/blog/2025-02-21-using-apollo-graphql-with-react-in-an-nx-workspace.md
new file mode 100644
index 0000000000..c584f0937f
--- /dev/null
+++ b/docs/blog/2025-02-21-using-apollo-graphql-with-react-in-an-nx-workspace.md
@@ -0,0 +1,719 @@
+---
+title: 'Using Apollo GraphQL in an Nx Workspace'
+slug: 'using-apollo-graphql-in-an-nx-workspace'
+authors: ['Philip Fulcher']
+cover_image: '/blog/images/2025-02-21/header.avif'
+tags: [nx]
+description: 'Learn how to create an Nx workspace that provides a GraphQL API via Apollo Server, a React frontend, and code generated by GraphQL Codegen to save time on development.'
+---
+
+Because of the Nx's robust support for a diverse ecosystem of JavaScript development, it enables you to build your entire full-stack application in a single repo. This allows you to share code and interfaces between your frontend and backend and acts as a multiplier on your development velocity.
+
+[GraphQL](https://graphql.org/) is a query language for your API. Because of its typed schema definition, it’s a great candidate for defining the contract between your API and its consumers. By using smart tools to generate code based on that schema, you can save yourself a lot of time and enforce better cooperation between your frontend and backend.
+
+In this article, you will build a simple GraphQL API that tracks some information about Lego sets. You’ll create this API using Apollo Server, and it will be consumed by a React application. You’ll have this all inside of an Nx Workspace in a single repository.
+
+In this article, you’ll learn how to:
+
+- Create an Nx workspace for both frontend and backend applications
+- Create a GraphQL API using [Apollo Server](https://www.apollographql.com/docs/apollo-server)
+- Generate frontend code and backend resolver types based on your GraphQL schema using [GraphQL Codegen](https://the-guild.dev/graphql/codegen)
+- Create a [React](https://react.dev/) application to consume your GraphQL API
+
+{% callout type="note" title="Minimal configuration" %}
+When given the option to enable another tool, like linting or testing, we're going to decline. This keeps this article focussed on GraphQL instead of having lint and test configs in the example. As you progress, feel free to enable these additional options if you'd like, especially if you're adding to an existing workspace that has those tools enabled.
+{% /callout %}
+
+An example repo with all the work you’ll be doing here can be found in [our Nx Recipes repo](https://github.com/nrwl/nx-recipes/tree/main/apollo-graphql)
+
+## Create a new workspace
+
+Start by creating an Nx workspace:
+
+```shell
+npx create-nx-workspace@latest --preset=node-monorepo nx-apollo
+```
+
+When prompted, answer the prompts as follows:
+
+```shell
+❯ npx create-nx-workspace@latest --preset node nx-apollo
+
+ NX Let's create a new workspace [https://nx.dev/getting-started/intro]
+
+✔ Application name · api
+✔ What framework should be used? · none
+✔ Would you like to generate a Dockerfile? [https://docs.docker.com/] · No
+✔ Which CI provider would you like to use? · skip
+✔ Would you like remote caching to make your build faster? · skip
+```
+
+## Create GraphQL schema and project
+
+We want to generate model types from our schema that can be used by other projects in our workspace, so we'll start by creating a new project:
+
+```shell
+npx nx g @nx/js:library --directory=libs/models-graphql models-graphql
+```
+
+When prompted, answer the prompts as follows:
+
+```shell
+❯ npx nx g @nx/js:library --directory=libs/models-graphql models-graphql
+
+ NX Generating @nx/js:library
+
+✔ Which bundler would you like to use to build the library? Choose 'none' to skip build setup. · none
+✔ Which linter would you like to use? · none
+✔ Which unit test runner would you like to use? · none
+```
+
+{% callout type="note" title="Why do I need a separate project?" %}
+When you have your GraphQL schema and generated models in a separate project, other projects can depend on it. This ensures that all projects are using the same version of the schema and models. This exemplifies the "modulith" structure for monorepos. [Read more](/blog/virtuous-cycle-of-workspace-structure)
+{% /callout %}
+
+You need a GraphQL schema to create the API, so write a very simple one with a single query and a single mutation. Create a file named `schema.graphql` in the new `models-graphql` project:
+
+```graphql {% fileName="libs/models-graphql/src/lib/schema.graphql" %}
+type Set {
+ id: Int!
+ name: String
+ year: Int
+ numParts: Int
+}
+
+type Query {
+ allSets: [Set]
+}
+
+type Mutation {
+ addSet(name: String, year: String, numParts: Int): Set
+}
+```
+
+To start generating our models from this schema, we'll use [GraphQl Codegen](https://the-guild.dev/graphql/codegen). Install the packages needed:
+
+```shell
+npm install -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-resolvers @graphql-codegen/typescript-react-apollo
+```
+
+GraphQL Codegen is controlled by a configuration file named `codegen.ts` in each project that needs it. Create one for `models-graphql`:
+
+```typescript {% fileName="libs/models-graphql/codegen.ts" %}
+import type { CodegenConfig } from '@graphql-codegen/cli';
+
+const config: CodegenConfig = {
+ schema: 'libs/models-graphql/src/lib/schema.graphql',
+ generates: {
+ 'libs/models-graphql/src/lib/__generated__/models.ts': {
+ plugins: ['typescript'],
+ config: {
+ avoidOptionals: true,
+ },
+ },
+ },
+};
+export default config;
+```
+
+To run GraphqlQL Codegen, we need a target added to our project. Add this to the `project.json` for `models-graphql`:
+
+```json {% fileName="libs/models-graphql/project.json" %}
+"targets": {
+ "codegen": {
+ "command": "npx graphql-codegen --config {projectRoot}/codegen.ts"
+ }
+}
+```
+
+Run the `codegen` task to generate our new models:
+
+```shell
+npx nx codegen models-graphql
+```
+
+You should see the new models created in the `__generated__` directory in `models-graphql`. To use them outside the project, export them from the `index.ts`:
+
+```typescript {% fileName="libs/models-graphql/src/index.ts" %}
+export * from './lib/__generated__/models';
+```
+
+## Create GraphQL API
+
+Use Apollo Server to create your GraphQL api. Start by installing the GraphQL modules needed for Apollo
+
+```shell
+npm install @apollo/server graphql
+```
+
+The workspace was generated with a Node application for us, but we need to make some small changes to support ESM for Apollo Server. First, change these compiler options in `tsconfig.app.json`:
+
+```json {% fileName="apps/api/tsconfig.app.json" %}
+ "compilerOptions": {
+ "lib": ["es2020"],
+ "target": "es2020",
+ "module": "esnext",
+ "moduleResolution": "node",
+ "esModuleInterop": true,
+ ...
+ }
+```
+
+And change the `build` target config in `project.json`:
+
+```json {% fileName="apps/api/project.json" %}
+"targets": {
+ "build": {
+ ...
+ "options": {
+ ...
+ "format": ["esm"]
+ }
+ }
+}
+```
+
+GraphQl Codegen has already created our models for our GraphQL schema, but it can also generate the resolver types we'll want to implement in Apollo Server. Like before, create a `codegen.ts` in the `api` application:
+
+```typescript {% fileName="apps/api/codegen.ts" %}
+import type { CodegenConfig } from '@graphql-codegen/cli';
+
+const config: CodegenConfig = {
+ schema: 'libs/models-graphql/src/lib/schema.graphql',
+ generates: {
+ 'apps/api/src/__generated__/resolvers.ts': {
+ plugins: ['add', 'typescript-resolvers'],
+ config: {
+ useIndexSignature: true,
+ content: 'import * as types from "@nx-apollo/models-graphql"',
+ namespacedImportName: 'types',
+ },
+ },
+ },
+};
+export default config;
+```
+
+And add the task to our targets:
+
+```json {% fileName="apps/api/project.json" %}
+ "targets": {
+ "codegen": {
+ "command": "npx graphql-codegen --config {projectRoot}/codegen.ts"
+ }
+}
+```
+
+And run the task:
+
+```shell
+npx nx codegen api
+```
+
+And now there should be resolver types in the `__generated__` directory. We're ready to put create our Apollo Server application. Replace the contents of `main.ts` with this:
+
+```typescript {% fileName="apps/api/src/main.ts" %}
+import { ApolloServer } from '@apollo/server';
+import { startStandaloneServer } from '@apollo/server/standalone';
+import { Set } from '@nx-apollo/models-graphql';
+import { readFileSync } from 'fs';
+import { join } from 'path';
+import { Resolvers } from './__generated__/resolvers';
+
+// Note: this uses a path relative to the project's
+// root directory, which is the current working directory
+// if the server is executed using `npm run`.
+const typeDefs = readFileSync(
+ join('libs/models-graphql/src/lib', 'schema.graphql'),
+ { encoding: 'utf-8' }
+);
+
+const sets: Set[] = [
+ {
+ id: 1,
+ name: 'Voltron',
+ numParts: 2300,
+ year: '2019',
+ },
+ {
+ id: 2,
+ name: 'Ship in a Bottle',
+ numParts: 900,
+ year: '2019',
+ },
+];
+
+// Resolvers define how to fetch the types defined in your schema.
+// This resolver retrieves books from the "books" array above.
+const resolvers: Resolvers = {
+ Query: {
+ allSets: () => sets,
+ },
+ Mutation: {
+ addSet: (parent, args) => {
+ const newSet = {
+ id: sets.length + 1,
+ name: args.name,
+ year: args.year,
+ numParts: +args.numParts,
+ };
+
+ sets.push(newSet);
+
+ return newSet;
+ },
+ },
+};
+
+// The ApolloServer constructor requires two parameters: your schema
+// definition and your set of resolvers.
+const server = new ApolloServer({
+ typeDefs,
+ resolvers,
+});
+
+// Passing an ApolloServer instance to the `startStandaloneServer` function:
+// 1. creates an Express app
+// 2. installs your ApolloServer instance as middleware
+// 3. prepares your app to handle incoming requests
+const { url } = await startStandaloneServer(server, {
+ listen: { port: 4000 },
+});
+
+console.log(`🚀 Server ready at: ${url}`);
+```
+
+This is already enough to see some progress when you run the `api` application.
+
+```shell
+npx nx serve api
+```
+
+When the application is running, bring up the GraphQL Playground in your browser at [http://localhost:4000/](http://localhost:4000/)
+
+Here you can inspect your GraphQL schema as well as submit queries and mutations.
+
+This is a very simple resolver that holds data in memory. It returns the current contents of the sets array for the `allSets` query and allows users to add a new set using the `addSet` mutation. Add this resolver to the providers array in your app module:
+
+Go back to your GraphQL Playground and see if your queries return any data now. Try a query and a mutation:
+
+```graphql
+query allSets {
+ allSets {
+ id
+ name
+ numParts
+ }
+}
+
+mutation addSet {
+ addSet(name: "My New Set", numParts: 200, year: "2020") {
+ id
+ }
+}
+```
+
+Now that the API is working, you’re ready to build a frontend to access this.
+
+## Add React frontend
+
+Start by adding a React app to your workspace using the `@nx/react` plugin:
+
+```shell
+npx nx add @nx/react
+```
+
+Create the React app using the generator:
+
+```shell
+npx nx g @nx/react:app --directory=apps/frontend frontend
+```
+
+When prompted, answer the prompts as follows:
+
+```shell
+❯ npx nx g @nx/react:app --directory=apps/frontend frontend
+
+ NX Generating @nx/react:application
+
+✔ Which stylesheet format would you like to use? · tailwind
+✔ Would you like to add React Router to this application? (y/N) · false
+✔ Which bundler do you want to use to build the application? · vite
+✔ Which linter would you like to use? · none
+✔ What unit test runner should be used? · none
+✔ Which E2E test runner would you like to use? · none
+```
+
+We use Tailwind styles here for convenience. It will allow us to add some simple styles to our app without adding CSS files and importing them.
+
+The Apollo client makes it easy to consume your GraphQL API. Install the client:
+
+```shell
+npm install @apollo/client
+```
+
+Modify your `app.tsx` to provide the Apollo Client:
+
+```typescript {% fileName="apps/frontend/src/main.tsx" %}
+import { StrictMode } from 'react';
+import * as ReactDOM from 'react-dom/client';
+import App from './app/app';
+import { ApolloClient, InMemoryCache, ApolloProvider } from '@apollo/client';
+
+const root = ReactDOM.createRoot(
+ document.getElementById('root') as HTMLElement
+);
+
+const client = new ApolloClient({
+ uri: 'http://localhost:4000/graphql',
+ cache: new InMemoryCache(),
+});
+
+root.render(
+
Loading ...
+ ) : ( +