# Graffle: the graphql-request successor that generates a typed client from your schema

> Graffle is the renamed, TypeScript-first GraphQL client from the graphql-request lineage. It ships a CLI generator, a document builder with type inference and a preset system, but the README itself says the project is pre-release and points you at the docs for the install command.

**graffle-js/graffle** — Simple GraphQL Client for JavaScript. Minimal. Extensible. Type Safe. Runs everywhere.

- Repository: https://github.com/graffle-js/graffle
- Website: http://graffle.js.org/
- Stars: 6,119 · Forks: 310
- Language: TypeScript
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/graffle-js-graffle

## What Graffle solves, and who it is actually for

Typed GraphQL clients in JavaScript have historically forced a choice. You either write query strings and lose type safety on the response, or you adopt a heavy toolchain that generates code you then have to keep in sync. Graffle sits in the middle. It is a GraphQL client for JavaScript whose stated properties are minimal, extensible and type safe, and the repository description adds that it runs everywhere. The audience is TypeScript engineers building against a GraphQL API who want the response shape inferred at compile time without giving up native GraphQL syntax.

The README lists the capabilities it cares about: a document builder with full type inference, an extension system, multi-transport support covering HTTP and in-memory, native GraphQL syntax, a set of extensions and custom scalar codecs. That list is the product definition. If your problem is calling a GraphQL endpoint and getting a correctly typed object back, Graffle is aimed at you. If your problem is something else, the extension surface is where the project expects you to work.

One naming detail matters before anything else. The README states that graphql-request has been renamed to Graffle, and the old version is available on the graphql-request branch. So this is not a new library that happens to resemble graphql-request. It is the continuation of it under a new name, which means migration questions and lineage questions are the same question.

## How Graffle is put together: exports, presets and the generator

The package.json is the clearest architecture document in the repository. Graffle is a single package with many subpath exports rather than a set of separate packages. The root export is ".", and alongside it you get "./client", "./extension", "./generator", "./schema", "./kit" and "./utilities-for-generated". Extensions are exposed individually: "./extensions/introspection", "./extensions/document-builder", "./extensions/throws", "./extensions/opentelemetry", "./extensions/transport-http", "./extensions/transport-memory" and "./extensions/upload", plus "./extensions/schema-errors" with a separate gentime entry point.

That layout tells you how the runtime is assembled. Transports are extensions, not hardcoded behaviour, which is why HTTP and in-memory sit side by side as peers. The document builder is also an extension, so the typed query DSL is opt-in rather than the only way to talk to a server. The schema-errors extension has both a gentime and a runtime export, which implies error typing is partly decided when code is generated and partly applied when requests run.

The package also ships presets: "./presets/bare", "./presets/basic" and "./presets/minimal". Presets exist because wiring transports, the document builder and error handling by hand is tedious; each preset is a named bundle of extensions. The package declares "type": "module", so it is ESM-first, and it declares a bin at build/cli/index.js, which is the generator you run against a schema. The examples directory mirrors this structure with folders named 10_transport-http, 30_gql, 35_custom-scalar, 50_anyware, 55_document-builder, 60_extension and 65_preset, so the repository treats each of these as a teachable unit.

## Installing Graffle and running it against a schema

The README does not give an install command. It says to visit graffle.js.org/guides/getting-started for installation instructions and examples, and adds a note that Graffle is currently in pre-release and that you should follow the documentation for the correct installation command. That is a real constraint: the package name is graffle, but the exact install line is deliberately kept in the docs, so check there rather than copying a command from a blog post.

The package is managed with pnpm, and the repository pins pnpm@10.19.0 in package.json. If you work inside a checkout of the repository rather than consuming the published package, that pin is what the lockfile expects.

```bash
pnpm install
```

The second thing to know is that the package publishes a CLI. The bin field points at build/cli/index.js, and the generator is exposed as a subpath export at "./generator". The examples directory contains a graffle.config.ts at its root, which is the configuration file the generator reads in that workspace. A first real use therefore has two steps: generate typed code from your schema, then import the generated client and call it. The repository does not show the exact generate command in what is available here, so read the getting-started guide for the subcommand and flags before running it. The bin entry itself is the only invocation the repository names directly.

```bash
node build/cli/index.js
```

Once generated code exists, the runtime side is assembled from a preset. The package exposes "./presets/basic", "./presets/minimal" and "./presets/bare", and the examples folder 65_preset exists precisely to show the difference. Pick one preset rather than hand-assembling transports, because the transport-http extension is what actually performs the network call. The README's own example list shows 10_transport-http as a separate unit, which confirms transport is a decision you make, not a default you inherit.

## The pre-release label is the limitation that matters most

The README says plainly that Graffle is currently in pre-release. That single sentence should shape how you read everything else. A pre-release TypeScript library with a large subpath export map is a library whose import paths can move. The exports object in package.json is long and granular, which is good for tree-shaking and bad for stability: each of those keys is a public path that a future version could rename or remove. If you import from "./extensions/document-builder" today, treat that string as a version-coupled detail.

The version field in the repository package.json reads 0.0.0-dripip, which is a placeholder rather than a released version. The npm releases listed for the project include 7.4.0 and v7.3.5, so the published line and the repository working tree are clearly not the same thing. Do not assume the repository state you read on main matches the release you install.

There is a second, quieter limitation. The README routes almost everything to the website: installation, quick start, examples, full documentation. The README itself contains no API reference, no configuration schema and no error-handling guide. For a project whose selling point is type inference and an extension system, the types are the documentation, and that is a demanding way to learn a library. It also means the README cannot answer questions about rollback, versioning policy or breaking-change cadence, because it does not discuss them.

## Graffle versus plain graphql-request, and versus a schema-first codegen stack

The most direct alternative is graphql-request itself. The README states that graphql-request was renamed to Graffle and that the old version lives on the graphql-request branch. The difference in approach is the code generation step. graphql-request in its original form is a small client that sends a query string you wrote and returns a response you type yourself. Graffle adds a generator, a document builder and an extension system on top of that lineage. If you never wanted codegen, the old branch is the smaller thing, and it is frozen in the sense that it is a branch rather than the main line of work.

The second alternative is a schema-first codegen stack, where a separate tool reads your schema and your query documents and emits typed hooks or functions, and a thin client executes them. Graffle folds both halves into one package: the "./generator" export and the "./utilities-for-generated" export are in the same package.json as the runtime client and the transport extensions. The practical difference is dependency count and version coupling. One package means one version to track; it also means a generator change and a runtime change can arrive in the same release, which is convenient until it is not.

A third comparison is worth naming because the search data is full of it. People searching for Graffle also search for OmniGraffle and for GRAFFLE files. Those are unrelated: OmniGraffle is a diagramming application, and a GRAFFLE file is not a GraphQL artifact. If you arrived here looking for a way to open a .graffle document, this repository is the wrong project entirely.

## Maintenance, licensing and what a version bump costs you

The repository is not archived, and the last push was on 2026-05-11. The most recent npm release listed is 7.4.0 from 2025-12-12, preceded by v7.3.5 on 2025-11-25. The gap between the last push and the latest release is worth noting if you depend on fixes landing in a published version rather than on main.

The licence is MIT, declared in the LICENSE file and repeated in the README. MIT is permissive: you can use Graffle in closed-source products, and the licence imposes no copyleft obligation on your own code. The one practical implication is that MIT gives you no warranty, so the pre-release label and the licence point the same direction: you are responsible for pinning the version you depend on. That is a statement about the licence text, not legal advice; read the LICENSE file and your own counsel if the distinction matters to your organisation.

Upgrade cost is dominated by the export map. Because extensions, presets and the generator are separate subpath exports, a major version can change import specifiers without changing your query code. Budget for the import lines, not the queries. The repository also carries a typescript-dual-export-pattern.md file at its root, which suggests the maintainers are thinking about how the package is consumed across module systems; if your build setup is unusual, that document is the one to read before filing an issue.

## Conclusion

Adopt Graffle if you are already on TypeScript, you want generated types and a document builder rather than writing raw query strings by hand, and you are willing to track a project whose README labels it pre-release. Do not adopt it if you need a stable, frozen API surface today, or if you want a client that only does plain string queries with no code generation step; graphql-request on the old branch is the conservative choice for that. Before committing, verify three things in the repository: which subpath exports you actually import, whether the preset you pick enables the extensions you rely on, and what the generator emits for your custom scalars.

## FAQ

### Is Graffle the same project as graphql-request?

Yes. The README states that graphql-request has been renamed to Graffle, and that the old version is available on the graphql-request branch. The published npm releases for Graffle include 7.4.0 and v7.3.5.

### How do I open a GRAFFLE file?

Not with this project. Graffle here is a GraphQL client for JavaScript, and the repository does not describe opening a GRAFFLE document.

### What is Graffle?

Graffle is a GraphQL client for JavaScript, described in its repository as minimal, extensible and type safe, and as running everywhere. It ships a document builder with type inference, an extension system, HTTP and in-memory transports, and custom scalar codecs.

### What is a GRAFFLE file?

The repository does not define a GRAFFLE file. Graffle in this project is a GraphQL client for JavaScript, distributed as the graffle package, and its sources are TypeScript and JavaScript rather than a GRAFFLE document format.

## Sources

- [graffle-js/graffle on GitHub](https://github.com/graffle-js/graffle)
- [License: MIT](https://github.com/graffle-js/graffle/blob/main/LICENSE)
- [Project website](http://graffle.js.org/)
- [README](https://github.com/graffle-js/graffle/blob/main/README.md)
- [Releases](https://github.com/graffle-js/graffle/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/graffle-js-graffle
