In packages/web/package.json :
// packages/api/lib/appsync-stack.ts import * as appsync from 'aws-cdk-lib/aws-appsync'; import * as dynamodb from 'aws-cdk-lib/aws-dynamodb'; const api = new appsync.GraphqlApi(this, 'MyUnifiedApi', { name: 'UnifiedBlogApi', schema: appsync.Schema.fromAsset('graphql/schema.graphql'), // single source of truth });
{ "scripts": { "codegen": "graphql-codegen --config codegen.yml", "build": "npm run codegen && vite build" } } The codegen.yml points to the local schema file: appsync unified repo
If you have ever worked on a project with multiple frontends (React, iOS, Android) talking to a single GraphQL API, you know the pain: Schema drift, duplicated resolver logic, and the "it works on my machine" syndrome for GraphQL transformations.
How to share schemas, resolvers, and logic across multiple frontends without losing your mind. In packages/web/package
// DynamoDB datasource const postTable = new dynamodb.Table(...); const postDS = api.addDynamoDbDataSource('PostDS', postTable);
schema: ../api/graphql/schema.graphql documents: src/**/*.graphql generates: src/generated/graphql.ts: plugins: - typescript - typescript-operations - typescript-react-apollo Now, when a developer runs npm run build in the web package, they always use the latest schema from the api package. No more out-of-sync copies. Your CI pipeline (GitHub Actions, GitLab CI) should enforce integration. Here is a typical workflow: No more out-of-sync copies
Start with a simple two-package structure ( api + one client), then expand. The tooling (CDK, GraphQL Codegen, npm workspaces) is mature enough for production today.
Enter the (monorepo). By managing your AWS AppSync configuration—schema, resolvers (VTL or JavaScript), datasources, and even client code—in a single repository, you can enforce consistency, improve developer experience, and streamline CI/CD.