Contributing
json-to-office is an MIT-licensed pnpm monorepo maintained at Wiseair-srl/json-to-office. This page covers the local development setup, how the monorepo is wired together, and how changes get tested and released.
Development setup
You need Node >= 20 and pnpm (the repo pins pnpm@9.15.9 via the packageManager field, so corepack will pick the right version automatically):
git clone https://github.com/Wiseair-srl/json-to-office.git
cd json-to-office
pnpm install
pnpm build # build all packages + regenerate root JSON schemas
pnpm test # run the vitest suites
pnpm check # lint + typecheck + test in one goOther useful scripts:
| Command | What it does |
|---|---|
pnpm dev | turbo dev --ui tui — hot-reload dev servers |
pnpm test:watch / pnpm test:coverage | Vitest in watch / coverage mode |
pnpm lint / pnpm lint:fix | ESLint across the workspace |
pnpm typecheck | TypeScript project-wide type check |
pnpm format / pnpm format:fix | Prettier check / write |
pnpm generate:schemas | Regenerate schemas/document.schema.json, theme.schema.json, presentation.schema.json |
pnpm cli | Run the CLI from source (tsx packages/jto/src/cli.ts) |
pnpm cli:dev:docx / pnpm cli:dev:pptx | Start a playground from source |
pnpm clean / clean:dist / clean:all / clean:cache | Various levels of cleanup |
Monorepo layout
The pnpm workspace contains packages/* plus the VitePress docs site (the services/ directory is deployment infrastructure, not a workspace member). Runtime package dependencies flow strictly upward:
shared # format-agnostic types, schemas, validation, fonts
├─ shared-docx # DOCX schemas + component registry
└─ shared-pptx # PPTX schemas + component registry
├─ core-docx # DOCX rendering engine (docx.js)
└─ core-pptx # PPTX rendering engine (pptxgenjs)
├─ json-to-docx # public DOCX API
└─ json-to-pptx # public PPTX API
├─ jto-cli # lean CLI (generate/validate/schemas/...)
└─ jto # full CLI + dev server + playground (depends on jto-cli)All packages publish under the @json-to-office npm scope. See Architecture for what each layer does at runtime.
Turbo pipeline
Turborepo orchestrates the builds:
builddepends on^build(a package builds only after its workspace dependencies), withdist/**as cached output.test,test:coverage, andtypecheckdepend on^build; thetesttask's cache is disabled so tests always run.- A root task,
//#generate:schemas, depends on theshared,shared-docx, andshared-pptxbuilds and writes the top-levelschemas/**files.pnpm buildrunsturbo build generate:schemas, so a full build always leaves the JSON Schemas in sync with the source.
Testing
Tests are written with Vitest and live next to the code in __tests__ directories. Run pnpm test locally; CI runs the suite on a matrix of Node 20 and 22 × ubuntu-latest and windows-latest for pull requests (pushes to main only trigger the release job). Keep platform differences — path separators, binary discovery — in mind.
Commit conventions
The repo enforces Conventional Commits via commitlint (@commitlint/config-conventional) on a Husky hook, and a pre-commit hook runs lint-staged (eslint --fix + Prettier) on staged files. Commits like feat(pptx): ..., fix(cli): ..., chore: ... pass; free-form messages are rejected.
Release flow (changesets)
Releases are automated with Changesets:
As a contributor, after making your change, run:
bashpnpm changesetSelect the affected packages, choose the semver bump, and write a short summary. Commit the generated
.changeset/*.mdfile with your PR. Thenpnpm checkand open the PR againstmain.On merge to
main, the CI release job runschangesets/action@v1. It either opens/updates achore: version packagesPR (collecting pending changesets into version bumps and changelogs) or, when that PR is merged, publishes to npm viapnpm release(pnpm build && changeset publish).
Configuration notes:
- All
@json-to-office/*packages are linked, so packages that have changesets move to the same new version together. (This is why@json-to-office/sharedcan sit at 0.16.0 while the rest are at 0.20.0 — linking only bumps packages that actually had changesets.) access: public, base branchmain, internal dependency bumps aspatch.
TIP
You do not need to touch version numbers or changelogs manually — the changeset file is the only release metadata a PR should carry.
Further reading
- CONTRIBUTING.md — the canonical contribution guide in the repo
- CODE_OF_CONDUCT.md — community standards
- Architecture — how the packages fit together at runtime
- CLI guide — the tools you'll use while developing