---
title: Directives on Directive Definitions
sidebarTitle: Directives on Directives
---
import { Callout } from 'nextra/components';
# Directives on Directive Definitions
<Callout type="info">
GraphQL.js supports directives applied to directive definitions, directive
extensions, and directive deprecation metadata through experimental APIs.
</Callout>
When the experiment is enabled, GraphQL directives can be applied to directive
definitions. This is the SDL shape introduced by the directives-on-directives
proposal:
```graphql
directive @tag(name: String!) on DIRECTIVE_DEFINITION
directive @cacheControl(maxAge: Int) @tag(name: "runtime") on FIELD_DEFINITION
```
The directive location is `DIRECTIVE_DEFINITION`.
```js
import { DirectiveLocation } from 'graphql';
DirectiveLocation.DIRECTIVE_DEFINITION;
```
## Parser surface
Directive definition directives are represented on the AST:
- `DirectiveDefinitionNode.directives`
- `DirectiveExtensionNode.directives`
- `Kind.DIRECTIVE_EXTENSION`
Parsing this syntax is controlled by
`experimentalDirectivesOnDirectiveDefinitions`.
```js
import { parse } from 'graphql';
const document = parse(source, {
experimentalDirectivesOnDirectiveDefinitions: true,
});
```
Directive extensions use the same option:
```graphql
extend directive @cacheControl @tag(name: "performance")
```
## Runtime schema surface
GraphQL.js does not add a generic `GraphQLDirective.directives` property. The
applied directives remain available through the AST nodes:
- `GraphQLDirective.astNode?.directives`
- `GraphQLDirective.extensionASTNodes`
GraphQL.js does derive directive deprecation metadata from those AST nodes.
`GraphQLDirective` includes:
- `deprecationReason`
- `extensionASTNodes`
```js
const directive = schema.getDirective('cacheControl');
directive.deprecationReason;
directive.astNode?.directives;
directive.extensionASTNodes;
```
## Deprecating custom directives
`@deprecated` can be used on directive definitions. The built-in
`GraphQLDeprecatedDirective` includes `DIRECTIVE_DEFINITION` in its locations.
```graphql
directive @oldAuth @deprecated(reason: "Use @auth instead") on FIELD_DEFINITION
```
The introspection type `__Directive` includes:
- `isDeprecated`
- `deprecationReason`
`__Schema.directives` accepts `includeDeprecated: Boolean! = false` when
directive deprecation support is present.
```graphql
query DeprecatedDirectives {
__schema {
directives(includeDeprecated: true) {
name
isDeprecated
deprecationReason
}
}
}
```
## Directive extensions
Directive extensions can attach deprecation metadata to a directive defined in
another document:
```graphql
directive @oldAuth on FIELD_DEFINITION
extend directive @oldAuth @deprecated(reason: "Use @auth instead")
```
When a schema is extended, GraphQL.js preserves directive extension AST nodes on
`GraphQLDirective.extensionASTNodes` and uses them when computing
`deprecationReason`.
## Validation
`KnownDirectivesRule` understands `DIRECTIVE_DEFINITION`, so a directive applied
to a directive definition must itself be declared for that location.
`UniqueDirectivesPerLocationRule` also treats a directive definition and its
extensions as one directive location for non-repeatable directive uniqueness.