Migrate to Monorepo Structure
Overview
Transform Graffle from a single package into a monorepo with 17 focused packages. This will:
- ✅ Enable independent versioning and releases
- ✅ Separate generic GraphQL utilities (
@graffle/grafaid) from Graffle-specific code
- ✅ Allow extensions to be used independently
- ✅ Improve tree-shaking and bundle sizes
- ✅ Enable better code organization and maintainability
- ✅ Claim the
@graffle npm scope
Package Structure (17 packages)
Core Packages (5)
1. @graffle/core
Graffle-specific shared infrastructure
Contains:
- Context system (
src/context/)
- Extension base class (
Extension)
- GlobalRegistry
- TypeFunction
- ContextFragments
- RequestResult types
- Docpar (document parser)
- SchemaDrivenDataMap
- Shared Graffle data structures
Used by: client, generator, all extensions
2. @graffle/grafaid
Generic GraphQL utilities (not Graffle-specific)
Contains:
- Schema types & definitions (from
src/types/Schema/)
- GraphQL document utilities
- Schema introspection & analysis
- HTTP helpers
- Execution helpers
- Tree-shakeable, reusable GraphQL tools
Design Goal: Grafaid should be usable standalone for any GraphQL tooling, not just Graffle.
Used by: client, generator
3. @graffle/client
GraphQL Client
Contains:
- Client implementation (
src/client/)
- Request pipeline (
src/requestPipeline/)
- Static helpers (
src/static/gql)
- Client methods
- Export path:
graffle/utilities-for-generated (re-exports from core + client for generated code)
Depends on: @graffle/core, @graffle/grafaid
4. @graffle/generator
Code Generator & CLI
Contains:
- Generator (
src/generator/)
- CLI (
src/cli/)
- Code generation logic
Depends on: @graffle/grafaid, @graffle/core
5. graffle
Main Convenience Package
The "batteries included" package.
- Re-exports
@graffle/client and common extensions
- Default entry point for users:
npm i graffle
Extension Packages (8)
Each extension is independently publishable and versioned:
@graffle/extension-document-builder
@graffle/extension-introspection
@graffle/extension-throws
@graffle/extension-opentelemetry
@graffle/extension-schema-errors
@graffle/extension-transport-http
@graffle/extension-transport-memory
@graffle/extension-upload
All depend on: @graffle/core
Preset Packages (3)
Pre-configured extension bundles:
@graffle/preset-bare
@graffle/preset-basic
@graffle/preset-minimal
Dependency Graph
@wollybeard/kit (external)
↓
@graffle/core
↓
┌─────┴─────────────┐
↓ ↓
@graffle/grafaid Extensions (8)
↓ ↓
@graffle/client Presets (3)
@graffle/generator ↓
↓ ↓
graffle (meta package)
Key Design Decisions
1. Grafaid = Generic, Core = Graffle-specific
@graffle/grafaid: Generic GraphQL utilities, tree-shakeable, usable standalone
@graffle/core: Graffle-specific infrastructure (extensions, context, etc.)
2. Replace Internal Kit with @wollybeard/kit
- Remove
src/lib/anyware, src/lib/tex, src/lib/config-manager
- Use
@wollybeard/kit for these utilities
3. Keep utilities-for-generated as Export Path
- Not a separate package
- Export path in
@graffle/client: graffle/utilities-for-generated
- Generated code imports:
import * as $$Utilities from "graffle/utilities-for-generated"
4. Independent Versioning
- Each package can be released independently
- Use Changesets for version management
5. Schema Types in Grafaid
- Move
src/types/Schema/ into @graffle/grafaid
- Rely on tree-shaking to keep client bundle small
Tooling Stack
Build & Task Running
- pnpm workspaces - Package management
- Turborepo - Build orchestration & caching (temporary)
- TypeScript project references - Fast, incremental builds
- Vite/Rolldown - Bundling
Future Migration
- Migrate to Vite+ when available (early 2026)
- Vite+ includes built-in monorepo task runner with intelligent caching
Versioning & Publishing
- Changesets - Independent versioning & changelog generation
- Each package publishes to
@graffle/* scope (except main graffle package)
Directory Structure
graffle/ # Monorepo root
├── packages/
│ ├── core/ # @graffle/core
│ ├── grafaid/ # @graffle/grafaid
│ ├── client/ # @graffle/client
│ ├── generator/ # @graffle/generator
│ ├── graffle/ # graffle (meta package)
│ │
│ ├── extensions/
│ │ ├── document-builder/ # @graffle/extension-document-builder
│ │ ├── introspection/ # @graffle/extension-introspection
│ │ ├── throws/ # @graffle/extension-throws
│ │ ├── opentelemetry/ # @graffle/extension-opentelemetry
│ │ ├── schema-errors/ # @graffle/extension-schema-errors
│ │ ├── transport-http/ # @graffle/extension-transport-http
│ │ ├── transport-memory/ # @graffle/extension-transport-memory
│ │ └── upload/ # @graffle/extension-upload
│ │
│ └── presets/
│ ├── bare/ # @graffle/preset-bare
│ ├── basic/ # @graffle/preset-basic
│ └── minimal/ # @graffle/preset-minimal
│
├── examples/ # Example projects (workspace, not published)
├── website/ # Documentation site (workspace, not published)
├── tests/ # Integration/e2e tests
├── scripts/ # Build/dev scripts
├── turbo.json # Turborepo config
├── pnpm-workspace.yaml # pnpm workspace config
└── package.json # Root package.json
Migration Strategy
Phase 1: Setup Infrastructure
- Create monorepo structure
- Configure pnpm workspaces
- Set up Turborepo
- Configure TypeScript project references
- Set up Changesets
Phase 2: Split Core Packages
- Extract
@graffle/core
- Extract
@graffle/grafaid (includes Schema types)
- Split
@graffle/client
- Split
@graffle/generator
- Update internal imports
Phase 3: Extract Extensions
- Move each extension to
packages/extensions/*
- Update extension imports and dependencies
- Test extensions independently
Phase 4: Extract Presets
- Move presets to
packages/presets/*
- Update preset dependencies
Phase 5: Create Meta Package
- Create
packages/graffle/ as main entry point
- Re-export client + common extensions
- Update documentation
Phase 6: Replace Kit Dependencies
- Replace
src/lib/anyware → @wollybeard/kit
- Replace
src/lib/tex → @wollybeard/kit
- Replace
src/lib/config-manager → @wollybeard/kit
- Remove internal lib utilities
Phase 7: Testing & Publishing
- Run full test suite across all packages
- Update CI/CD for monorepo
- Publish initial versions
- Update documentation and migration guides
References
Open Questions
Migrate to Monorepo Structure
Overview
Transform Graffle from a single package into a monorepo with 17 focused packages. This will:
@graffle/grafaid) from Graffle-specific code@grafflenpm scopePackage Structure (17 packages)
Core Packages (5)
1.
@graffle/coreGraffle-specific shared infrastructure
Contains:
src/context/)Extension)Used by: client, generator, all extensions
2.
@graffle/grafaidGeneric GraphQL utilities (not Graffle-specific)
Contains:
src/types/Schema/)Design Goal: Grafaid should be usable standalone for any GraphQL tooling, not just Graffle.
Used by: client, generator
3.
@graffle/clientGraphQL Client
Contains:
src/client/)src/requestPipeline/)src/static/gql)graffle/utilities-for-generated(re-exports from core + client for generated code)Depends on:
@graffle/core,@graffle/grafaid4.
@graffle/generatorCode Generator & CLI
Contains:
src/generator/)src/cli/)Depends on:
@graffle/grafaid,@graffle/core5.
graffleMain Convenience Package
The "batteries included" package.
@graffle/clientand common extensionsnpm i graffleExtension Packages (8)
Each extension is independently publishable and versioned:
@graffle/extension-document-builder@graffle/extension-introspection@graffle/extension-throws@graffle/extension-opentelemetry@graffle/extension-schema-errors@graffle/extension-transport-http@graffle/extension-transport-memory@graffle/extension-uploadAll depend on:
@graffle/corePreset Packages (3)
Pre-configured extension bundles:
@graffle/preset-bare@graffle/preset-basic@graffle/preset-minimalDependency Graph
Key Design Decisions
1. Grafaid = Generic, Core = Graffle-specific
@graffle/grafaid: Generic GraphQL utilities, tree-shakeable, usable standalone@graffle/core: Graffle-specific infrastructure (extensions, context, etc.)2. Replace Internal Kit with @wollybeard/kit
src/lib/anyware,src/lib/tex,src/lib/config-manager@wollybeard/kitfor these utilities3. Keep
utilities-for-generatedas Export Path@graffle/client:graffle/utilities-for-generatedimport * as $$Utilities from "graffle/utilities-for-generated"4. Independent Versioning
5. Schema Types in Grafaid
src/types/Schema/into@graffle/grafaidTooling Stack
Build & Task Running
Future Migration
Versioning & Publishing
@graffle/*scope (except maingrafflepackage)Directory Structure
Migration Strategy
Phase 1: Setup Infrastructure
Phase 2: Split Core Packages
@graffle/core@graffle/grafaid(includes Schema types)@graffle/client@graffle/generatorPhase 3: Extract Extensions
packages/extensions/*Phase 4: Extract Presets
packages/presets/*Phase 5: Create Meta Package
packages/graffle/as main entry pointPhase 6: Replace Kit Dependencies
src/lib/anyware→@wollybeard/kitsrc/lib/tex→@wollybeard/kitsrc/lib/config-manager→@wollybeard/kitPhase 7: Testing & Publishing
References
@grafflehas been claimedOpen Questions