Graphql Docs
Easily generate beautiful documentation from your GraphQL schema.
Install / Use
npx skills add brettchalupa/graphql-docsInstalls into whichever agent you are using.
README
GraphQLDocs
Ruby library and CLI for easily generating beautiful documentation from your GraphQL schema.

Key links:
- Demo: https://graphql-docs.bcodes.me.
- Ruby documentation: https://rubydoc.info/github/brettchalupa/graphql-docs.git/main.
Installation
Add the gem to your project with this command:
bundle add graphql-docs
Or install it yourself as:
gem install graphql-docs
Usage
GraphQLDocs provides two ways to serve your documentation:
- Static Site Generator (SSG) - Pre-generate all HTML files (default)
- Rack Application - Serve documentation dynamically on-demand
Static Site Generation (SSG)
GraphQLDocs can be used as a Ruby library to build the documentation website. Using it as a Ruby library allows for more control and using every supported option. Here's an example:
# pass in a filename
GraphQLDocs.build(filename: filename)
# or pass in a string
GraphQLDocs.build(schema: contents)
# or a schema class
schema = GraphQL::Schema.define do
query query_type
end
GraphQLDocs.build(schema: schema)
GraphQLDocs also has a simplified CLI (graphql-docs) that gets installed with the gem:
graphql-docs schema.graphql
That will generate the output in the output dir.
See all of the supported CLI options with:
graphql-docs -h
Rake Task
GraphQLDocs includes a Rake task for integration with Rails applications and other Ruby projects that use Rake. This allows you to generate documentation as part of your build process or hook it into other Rake tasks.
Basic Usage
Using task arguments (recommended):
rake graphql-docs:generate[schema.graphql]
rake graphql-docs:generate[schema.graphql,./docs]
rake graphql-docs:generate[schema.graphql,./docs,/api-docs,true]
Or using environment variables:
GRAPHQL_SCHEMA_FILE=schema.graphql rake graphql-docs:generate
Available Arguments
Arguments are passed in order: [schema_file, output_dir, base_url, delete_output]
schema_file- Path to GraphQL schema file (required)output_dir- Output directory (default:./output/)base_url- Base URL for assets and links (default:'')delete_output- Delete output directory before generating (true/false, default:false)
Available Environment Variables
GRAPHQL_SCHEMA_FILE- Path to GraphQL schema file (required)GRAPHQL_OUTPUT_DIR- Output directory (default:./output/)GRAPHQL_BASE_URL- Base URL for assets and links (default:'')GRAPHQL_DELETE_OUTPUT- Delete output directory before generating (true/false)
Note: Task arguments take precedence over environment variables.
Example: Generate Docs Before Asset Compilation
In Rails, you can automatically generate documentation before compiling assets:
# Rakefile or lib/tasks/docs.rake
Rake::Task["assets:precompile"].enhance(["graphql-docs:generate"])
Then configure using environment variables:
# config/application.rb or .env
ENV["GRAPHQL_SCHEMA_FILE"] = Rails.root.join("app/graphql/schema.graphql").to_s
Or invoke with arguments in your custom task:
# lib/tasks/custom_docs.rake
namespace :docs do
desc "Generate API documentation"
task :generate do
Rake::Task["graphql-docs:generate"].invoke(
"app/graphql/schema.graphql", # schema_file
"public/api-docs", # output_dir
"/api-docs", # base_url
"true" # delete_output
)
end
end
# Hook into asset compilation
Rake::Task["assets:precompile"].enhance(["docs:generate"])
Rack Application (Dynamic)
For more flexibility and control, you can serve documentation dynamically using the Rack application. This is useful for:
- Internal tools with frequently changing schemas
- Integration with existing Rails/Sinatra applications
- Adding authentication/authorization middleware
- Dynamic schema loading from databases or APIs
Requirements: The Rack application feature requires the rack gem (version 2.x or 3.x). Add it to your Gemfile:
gem 'rack', '~> 3.0' # or '~> 2.0' for Rack 2.x
The gem is compatible with both Rack 2.x and 3.x, so you can use whichever version your application requires.
Standalone Rack App
Create a config.ru file:
require 'graphql-docs'
schema = File.read('schema.graphql')
app = GraphQLDocs::App.new(
schema: schema,
options: {
base_url: '',
use_default_styles: true,
cache: true # Enable page caching
}
)
run app
Then run with:
rackup config.ru
Visit http://localhost:9292 to view your docs.
Mounting in Rails
# config/routes.rb
require 'graphql-docs'
Rails.application.routes.draw do
mount GraphQLDocs::App.new(schema: MyGraphQLSchema) => '/docs'
end
Mounting in Sinatra
require 'sinatra'
require 'graphql-docs'
schema = File.read('schema.graphql')
docs_app = GraphQLDocs::App.new(schema: schema)
map '/docs' do
run docs_app
end
map '/' do
run Sinatra::Application
end
Rack App Features
- On-demand generation - Pages are generated when requested
- Built-in caching - Generated pages are cached in memory (disable with
cache: false) - Schema reloading - Update schema without restarting server:
app = GraphQLDocs::App.new(schema: schema)
# Later, reload with new schema
new_schema = File.read('updated_schema.graphql')
app.reload_schema!(new_schema)
- Asset serving - CSS, fonts, and images served automatically
- Error handling - Friendly error pages for missing types
SSG vs Rack Comparison
| Feature | SSG | Rack App | |---------|-----|----------| | Setup complexity | Low | Medium | | First page load | Instant | Fast (with caching) | | Schema updates | Manual rebuild | Automatic/reload | | Hosting | Any static host | Requires Ruby server | | Memory usage | Minimal | Higher (cached pages) | | Authentication | Separate layer | Built-in middleware | | Best for | Public docs, open source | Internal tools, dynamic schemas |
Breakdown
There are several phases going on the single GraphQLDocs.build call:
- The GraphQL IDL file is read (if you passed
filename) throughGraphQL::Client(or simply read if you passed a string throughschema). GraphQL::Parsermanipulates the IDL into a slightly saner format.GraphQL::Generatortakes that saner format and begins the process of applying items to the HTML templates.GraphQL::Renderertechnically runs as part of the generation phase. It passes the contents of each page and converts it into HTML.
If you wanted to, you could break these calls up individually. For example:
options = {}
options[:filename] = "#{File.dirname(__FILE__)}/../data/graphql/schema.idl"
options[:renderer] = MySuperCoolRenderer
options = GraphQLDocs::Configuration::GRAPHQLDOCS_DEFAULTS.merge(options)
response = File.read(options[:filename])
parser = GraphQLDocs::Parser.new(response, options)
parsed_schema = parser.parse
generator = GraphQLDocs::Generator.new(parsed_schema, options)
generator.generate
Generating output
By default, the HTML generation process uses ERB to layout the content. There are a bunch of default options provided for you, but feel free to override any of these. The Configuration section below has more information on what you can change.
It uses Commonmarker (v2.x) to perform the Markdown rendering by default, with GitHub Flavored Markdown extensions enabled including automatic header anchors. Emoji shortcodes (like :smile:) are automatically converted to emoji characters using gemoji. You can override this by providing a custom rendering class. You must implement two methods:
initialize- Takes two arguments, the parsedschemaand the configurationoptions.renderTakes the contents of a template page. It also takes two optional kwargs, the GraphQLtypeand itsname. For example:
class CustomRenderer
def initialize(parsed_schema, options)
@parsed_schema = parsed_schema
@options = options
end
def render(contents, type: nil, name: nil)
contents.sub(/Repository/i, '<strong>Meow Woof!</strong>')
opts[:content] = contents
@graphql_default_layout.result(OpenStruct.new(opts).instance_eval { binding })
end
end
options[:filename] = 'location/to/sw-api.graphql'
options[:renderer] = CustomRenderer
GraphQLDocs.build(options)
If your render method returns nil, the Generator will not attempt to write any HTML file.
Templates
The layouts for the individual GraphQL pages are ERB templates, but you can also use ERB templates for your static landing pages.
If you want to add additional variables for your landing pages, you can add define a variables hash within the landing_pages option.
Helper methods
In your ERB layouts, there are several helper methods you can use. The helper methods are:
slugify(str)- This slugifies the given string.include(filename, opts)- This embeds a template from yourincludesfolder, passing along the local options provided.markdownify(string)- This converts a string into HTML via CommonMarker.graphql_operation_types,graphql_mutation_types,graphql_object_types,graphql_interface_types,graphql_enum_types,graphql_union_types,graphql_input_object_types,graphql_scalar_types,graphql_directive_types- Collections of the various GraphQL types.
To call these methods within templates, you must use the dot notation, such as <%= slugify.(text) %>.
Dark Mode Support
GraphQLDocs i
Related Skills
node-connect
385.6kDiagnose OpenClaw Android, iOS, or macOS node pairing, QR/setup code, route, auth, and connection failures.
prose
385.6kOpenProse VM skill pack. Activate on any `prose` command, .prose files, or OpenProse mentions; orchestrates multi-agent workflows.
Writing Hookify Rules
140.7kThis skill should be used when the user asks to "create a hookify rule", "write a hook rule", "configure hookify", "add a hookify rule", or needs guidance on hookify rule syntax and patterns.
Command Development
140.7kThis skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs gu…
