-
Notifications
You must be signed in to change notification settings - Fork 309
Open
Labels
Description
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
@grafflenpm 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/clientand 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/kitfor 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 maingrafflepackage)
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
- Related: Extract extensions to own packages #1124 (Extract extensions to own packages)
- npm scope
@grafflehas been claimed
Open Questions
- Should examples/ and website/ be in monorepo or separate repos? Decision: Keep in monorepo
- Versioning strategy for extensions - lock-step or independent? Decision: Independent
- Breaking change migration path for users
P4sca1