{"id":13259,"library":"grats","title":"Grats GraphQL Server","description":"Grats provides an implementation-first, code-first approach to building GraphQL servers in TypeScript, enabling developers to define their GraphQL schema directly from their existing TypeScript types and functions using JSDoc-style annotations. This library leverages static analysis of your TypeScript code to automatically generate an executable GraphQL schema, eliminating the need for schema duplication or synchronization between SDL and resolver implementations. The current stable version, 0.0.36, reflects its active development phase, with frequent iterative updates and potentially breaking changes in minor `0.0.x` increments. Key differentiators include zero runtime overhead as the schema is extracted at build time, and a developer experience focused on reducing mental overhead by making the TypeScript implementation the single source of truth for the GraphQL schema, similar to approaches seen in Python (Strawberry) or C# (Hot Chocolate) but adapted for TypeScript's static nature.","status":"active","version":"0.0.36","language":"javascript","source_language":"en","source_url":"https://github.com/captbaritone/grats","tags":["javascript","graphql","typescript","resolvers","schema","code-first","implementation-first"],"install":[{"cmd":"npm install grats","lang":"bash","label":"npm"},{"cmd":"yarn add grats","lang":"bash","label":"yarn"},{"cmd":"pnpm add grats","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required as a peer dependency for static analysis and schema generation. Grats typically requires TypeScript >=5.5.","package":"typescript","optional":false},{"reason":"The generated schema is a standard graphql-js GraphQLSchema object, making this an implicit runtime dependency for any GraphQL server.","package":"graphql","optional":false}],"imports":[{"note":"Required for typing the `info` argument in resolvers, introduced in v0.0.27. As of v0.0.36, Grats is an ES Module, so `require()` will not work.","wrong":"const GqlInfo = require('grats');","symbol":"GqlInfo","correct":"import { GqlInfo } from 'grats';"},{"note":"Grats generates a `schema.ts` (or `schema.js`) file that exports the executable GraphQL schema. This is the primary symbol consumers import after running the `npx grats` CLI command. The `.js` extension is important for ESM environments.","symbol":"schema","correct":"import { schema } from './schema.js';"},{"note":"Grats uses JSDoc-style docblock tags (e.g., `/** @gqlType */`) for schema declarations, not actual TypeScript decorators or imported symbols. These are processed by the Grats CLI at build time, not runtime.","wrong":"import { gqlType } from 'grats'; // This is incorrect.\n@gqlType\nclass User {}","symbol":"@gqlType, @gqlField, @gqlQueryField, @gqlContext","correct":"/** @gqlType */\nclass User {}"}],"quickstart":{"code":"/* package.json */\n{\n  \"name\": \"grats-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Grats GraphQL Quickstart\",\n  \"main\": \"dist/server.js\",\n  \"type\": \"module\",\n  \"scripts\": {\n    \"grats\": \"npx grats\",\n    \"build\": \"npm run grats && tsc\",\n    \"start\": \"npm run build && node dist/server.js\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"devDependencies\": {\n    \"@types/node\": \"^20.0.0\",\n    \"grats\": \"^0.0.36\",\n    \"typescript\": \"^5.5.0\"\n  },\n  \"dependencies\": {\n    \"graphql\": \"^16.0.0\",\n    \"graphql-yoga\": \"^5.0.0\"\n  }\n}\n\n/* tsconfig.json */\n{\n  \"compilerOptions\": {\n    \"target\": \"es2022\",\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"bundler\",\n    \"esModuleInterop\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"strict\": true,\n    \"skipLibCheck\": true,\n    \"outDir\": \"./dist\",\n    \"resolveJsonModule\": true,\n    // Required for Grats to process JSDoc tags\n    \"jsx\": \"react-jsx\", // or other if needed\n    \"strictPropertyInitialization\": false // Often helpful with classes and Grats\n  },\n  \"include\": [\"src/**/*.ts\"],\n  \"exclude\": [\"node_modules\"]\n}\n\n/* src/user.ts */\n/**\n * Represents a user in the system.\n * @gqlType\n */\nexport class User {\n  /** @gqlField */\n  id: string;\n  /** @gqlField */\n  name: string;\n\n  constructor(id: string, name: string) {\n    this.id = id;\n    this.name = name;\n  }\n\n  /**\n   * Returns a greeting for the user.\n   * @gqlField\n   */\n  greeting(salutation: string): string {\n    return `${salutation}, ${this.name}!`;\n  }\n}\n\n/* src/schema.ts */\n// This file is generated by `npx grats`\n// It will contain the executable schema.\n\n/* src/server.ts */\nimport { createYoga } from 'graphql-yoga';\nimport { createServer } from 'node:http';\nimport { schema } from './schema.js'; // This file will be generated by Grats\n\ninterface MyContext {\n  viewerId: string | null;\n}\n\n/** @gqlContext */\nclass Context implements MyContext {\n  constructor(request: Request) {\n    // Simulate authentication\n    this.viewerId = request.headers.get('x-viewer-id') || null;\n  }\n}\n\nconst yoga = createYoga<MyContext>({\n  schema,\n  context: (request) => new Context(request.request)\n});\n\nconst server = createServer(yoga);\n\nserver.listen(4000, () => {\n  console.info('Server is running on http://localhost:4000/graphql');\n  console.info('Try a query like: { me { id name greeting(salutation: \"Hello\") } }');\n});\n","lang":"typescript","description":"This quickstart demonstrates setting up a basic Grats project with `graphql-yoga`. It defines a `User` type and `Context` using docblock annotations, generates the schema, and runs a GraphQL server."},"warnings":[{"fix":"Set `\"type\": \"module\"` in your `package.json` and update all Grats-related imports from `require()` to `import`. Adjust `tsconfig.json`'s `module` and `moduleResolution` to `esnext` or `nodenext` respectively.","message":"Grats v0.0.36 and later are published as ES Modules only. If you were using `require()` for Grats imports, you must migrate to ES `import` statements and ensure your project is configured for ESM.","severity":"breaking","affected_versions":">=0.0.36"},{"fix":"Add `/** @gqlContext */` to your context type definition. If using the `info` argument in a resolver, add `import { GqlInfo } from 'grats';` and type the argument as `info: GqlInfo`.","message":"Since Grats v0.0.27, any type or class intended to be used as a GraphQL context object MUST be explicitly annotated with `/** @gqlContext */`. Resolvers accessing the GraphQL `info` object must explicitly type it using `GqlInfo` imported from `grats`.","severity":"breaking","affected_versions":">=0.0.27"},{"fix":"Ensure that the call to the generated `getSchema` function in your server setup (often found in `schema.ts`) includes a configuration object, especially if you define custom scalars. Consult the Grats documentation for detailed custom scalar configuration.","message":"Starting with v0.0.34, the `getSchema` function (implicitly generated by Grats) now requires a configuration object. This is especially relevant if you are using custom scalars and need to provide serialization/parsing functions for them.","severity":"breaking","affected_versions":">=0.0.34"},{"fix":"Always use `/** @tagName */` in JSDoc comments preceding the relevant TypeScript class, type, or function. Do not attempt to import these as runtime constructs.","message":"Grats infers schema definitions from JSDoc-style docblock tags (e.g., `/** @gqlType */`). These are compile-time annotations, not runtime decorators or imported symbols. Attempting to `import { gqlType } from 'grats'` or use `@gqlType` as a TypeScript decorator will result in errors.","severity":"gotcha","affected_versions":"All"},{"fix":"Refer to the 'Limitations of Grats' documentation. Avoid wrapping methods in functions that obscure their type signatures. For enums, consider using TypeScript `enum`s or direct GraphQL SDL if these features are critical.","message":"Grats has known limitations regarding complex TypeScript patterns. It may not correctly infer types or arguments for method wrappers, or support descriptions/deprecated tags on GraphQL enum values defined as TypeScript union types.","severity":"gotcha","affected_versions":"All"},{"fix":"Ensure your project's `typescript` dependency in `package.json` meets the `>=5.5` requirement. Upgrade TypeScript if necessary.","message":"Grats requires TypeScript `>=5.5` as a peer dependency. Using an older version of TypeScript in your project may lead to build failures or unexpected behavior when running `npx grats`.","severity":"gotcha","affected_versions":">=0.0.36"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Update `package.json` to include `\"type\": \"module\"`. Change all `require()` statements to `import` statements. Ensure `tsconfig.json` has `\"module\": \"esnext\"` and `\"moduleResolution\": \"bundler\"` or `\"nodenext\"`.","cause":"Attempting to `require()` Grats or its generated output when Grats v0.0.36+ is an ES Module, or your project's `package.json` is not configured for ESM.","error":"Error [ERR_REQUIRE_ESM]: require() of ES Module ... Not compatible with CommonJS 'require'."},{"fix":"Add the `/** @gqlContext */` JSDoc comment immediately preceding your TypeScript class or type definition that serves as the GraphQL context.","cause":"After Grats v0.0.27, the GraphQL context type/class is missing the `/** @gqlContext */` docblock tag.","error":"Grats encountered an error: The declaration of the type/class you use as your GraphQL context must now be annotated with @gqlContext"},{"fix":"Ensure that any class, type, or function annotated with `/** @gqlType */`, `/** @gqlField */`, `/** @gqlQueryField */`, etc., is explicitly exported using `export` (e.g., `export class MyType { ... }`).","cause":"A GraphQL type, field, or query field defined with Grats annotations is not exported from its TypeScript module, making it inaccessible for schema generation.","error":"Grats encountered an error: Type 'X' is not visible in the generated schema. Ensure it is exported from a module Grats knows about."},{"fix":"Update the Grats configuration object in your generated `schema.ts` (or equivalent) to include `scalarSerializers` for each custom scalar you've defined, providing `serialize`, `parseValue`, and `parseLiteral` functions.","cause":"After Grats v0.0.34, custom scalars require explicit serialization/parsing functions provided in the configuration object passed to `getSchema`.","error":"Grats encountered an error: Custom scalar 'X' has no serializer defined in the Grats configuration."}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"grats","cli_version":null}