Skip to content

Latest commit

 

History

History
395 lines (281 loc) · 12.5 KB

File metadata and controls

395 lines (281 loc) · 12.5 KB

@nodejs/doc-kit Contributing Guide

Thank you for your interest in contributing to the @nodejs/doc-kit project! We welcome contributions from everyone, and we appreciate your help in making this project better.

Table of Contents

Getting Started

The steps below will give you a general idea of how to prepare your local environment for the @nodejs/doc-kit project and general steps for getting things done and landing your contribution.

Prerequisites

  • Node.js (latest LTS version, check the .nvmrc file)
  • Git
  • A GitHub account

Setting Up Your Development Environment

  1. Fork the repository

    Click the fork button in the top right, or the link in this paragraph, to clone the Node.js doc-kit Repository

  2. Clone your fork

    git clone git@github.com:<YOUR_GITHUB_USERNAME>/doc-kit.git # SSH
    git clone https://github.com/<YOUR_GITHUB_USERNAME>/doc-kit.git # HTTPS
    gh repo clone <YOUR_GITHUB_USERNAME>/doc-kit # GitHub CLI
  3. Navigate to the project directory

    cd doc-kit
  4. Set up upstream remote

    git remote add upstream git@github.com:nodejs/doc-kit # SSH
    git remote add upstream https://github.com/nodejs/doc-kit # HTTPS
    gh repo sync nodejs/doc-kit # GitHub CLI
  5. Install dependencies

    npm install

Repository Layout

This repository is an npm workspaces monorepo. The root package is private and holds the shared tooling (linting, formatting, tests, changesets); every published package lives under packages/:

Everything else at the root supports the repo rather than shipping to npm: docs/ (the reference docs), www/ (the documentation site), scripts/ (build and comparison helpers), and e2e/ (Playwright tests).

Running the Tool Locally

doc-kit generates documentation from the Markdown API docs in the Node.js repository. To run the tool locally, you need a copy of those source files.

  1. Get the Node.js API docs (sparse checkout)

    You only need a few directories from the Node.js repo. A sparse checkout avoids downloading the entire repository:

    git clone --depth 1 --sparse https://github.com/nodejs/node.git ../node
    cd ../node
    git sparse-checkout set doc/api lib CHANGELOG.md
    cd ../doc-kit
  2. Run the tool against a single file

    For fast iteration during development, target a single Markdown file instead of all API docs:

    node packages/core/bin/cli.mjs generate \
      -t legacy-html \
      -i ../node/doc/api/fs.md \
      -o out \
      --index ../node/doc/api/index.md \
      -c ../node/CHANGELOG.md

    The three flags -i (input), -t (target generator), and -o (output directory) are effectively required. Without them the tool either crashes or silently does nothing.

  3. View the generated output

    npx serve out
  4. Use debug logging

    Add --log-level debug before the generate subcommand to see the full pipeline trace:

    node packages/core/bin/cli.mjs --log-level debug generate -t legacy-html -i ../node/doc/api/fs.md -o out

Tip

See the README for the full list of available generators and CLI options.

Development Workflow

Making Changes

  1. Create a new branch for your work

    git checkout -b <name-of-your-branch>
  2. Perform your changes

    Make your code changes, add features, fix bugs, or improve documentation.

  3. Keep your branch up-to-date

    git fetch upstream
    git merge upstream/main
  4. Test your changes

    node --run test
    node --run test:coverage # To check code coverage
  5. Check code quality

    node --run format:check
    node --run lint

Adding a Changeset

This project uses Changesets to manage versioning, the changelog, and npm releases. Any change that affects published behaviour should include a changeset so it shows up in CHANGELOG.md and triggers a release.

  1. Create a changeset

    node --run changeset

    You'll be prompted for the bump type and a short summary:

    • patch — bug fixes and other backwards-compatible changes
    • minor — new, backwards-compatible features
    • major — breaking changes

    The summary becomes the changelog entry, so write it for users of the package.

  2. Commit the generated file

    This writes a Markdown file under .changeset/. Commit it alongside your code changes so it lands with your Pull Request.

Note

Changes that don't affect the published package (e.g. tests, CI, or internal docs) don't need a changeset. See Releasing for what happens to changesets after they're merged.

Submitting Your Changes

  1. Add and commit your changes

    git add .
    git commit -m "describe your changes"
  2. Push to your fork

    git push -u origin <name-of-your-branch>
  3. Create a Pull Request

    Go to your fork on GitHub and create a Pull Request to the main repository.

Important

Before committing and opening a Pull Request, please go through our Commit Guidelines and ensure your code passes all tests and quality checks.

Writing Tests

Testing is a crucial part of maintaining code quality and ensuring reliability. All contributions should include appropriate tests.

Test Coverage

  • Patches (PRs) are required to maintain 80% coverage minimum
  • Contributors are encouraged to strive for 95-100% coverage
  • New features and bug fixes should include corresponding tests
  • Tests should cover both happy path and edge cases

Test File Organization

Tests should be organized to mirror the source code structure. The paths below are relative to the package the source file lives in (e.g. packages/core):

  • For a source file at /src/index.mjs, create a test file at /src/__tests__/index.test.mjs

  • For a source file at /src/utils/parser.mjs, create a test file at /src/utils/__tests__/parser.test.mjs

  • Test files should use the .test.mjs extension

  • For a fixture used in /src/__tests__/some.test.mjs, place the fixture at /src/__tests__/fixtures/some-fixture.mjs.

  • When fixtures are used in multiple tests, place them in the test directory of the closest shared ancestor. For instance, if a fixture is used by both /src/__tests__/some.test.mjs, and /src/utils/__tests__/parser.test.mjs, the fixture belongs in /src/__tests__/fixtures/.

Writing Test Code

Tests should follow these guidelines:

Use Node.js Built-in Test Runner

import assert from 'node:assert/strict';
import { describe, it } from 'node:test';

Test Structure

Use describe and it syntax for organizing tests:

describe('MyModule', () => {
  describe('myFunction', () => {
    it('should return expected result for valid input', () => {
      // Test implementation
      assert.strictEqual(actual, expected);
    });

    it('should throw error for invalid input', () => {
      assert.throws(() => {
        // Code that should throw
      });
    });
  });
});

Best Practices

  • Use strict assertions: Always use node:assert/strict over node:assert.
  • Focused testing: Tests should ideally only test the specific file they are intended for
  • Use mocking: Mock external dependencies to isolate the code under test
  • Code splitting: Encourage breaking down complex functionality for easier testing

Example Test File

// tests/index.test.mjs
import assert from 'node:assert/strict';
import { describe, it } from 'node:test';

import { myFunction } from '../index.mjs';

describe('index.mjs', () => {
  describe('myFunction', () => {
    it('should process valid input correctly', () => {
      const input = 'test input';
      const result = myFunction(input);
      assert.strictEqual(result, 'expected output');
    });

    it('should handle edge cases', () => {
      assert.strictEqual(myFunction(''), '');
      assert.strictEqual(myFunction(null), null);
    });

    it('should throw for invalid input', () => {
      assert.throws(() => myFunction(undefined), {
        name: 'TypeError',
        message: 'Input cannot be undefined',
      });
    });
  });
});

Running Tests

# Run all tests
node --run test

# Run tests with coverage
node --run test:coverage

# Run specific test file
node --test packages/core/src/utils/__tests__/parser.test.mjs

Code Quality

Linting and Formatting

This project uses automated code quality tools:

# Format code
node --run format # To only check formatting, use `format:check`

# Lint code
node --run lint # To apply changes, use `lint:fix`

Pre-commit Hooks

This project uses Husky for Git pre-commit hooks that automatically lint and format your code before committing.

You can bypass pre-commit hooks if necessary (not recommended):

git commit -m "describe your changes" --no-verify

Releasing

Releases are automated with Changesets and require no manual version bumps — maintainers never edit the version field in package.json by hand.

When changesets land on main, the Publish workflow opens (or updates) a "Version Packages" Pull Request that consumes the pending changeset files, bumps the version in package.json, and writes the corresponding CHANGELOG.md entries.

To ship a release, a maintainer merges that "Version Packages" PR. The same workflow then:

  • publishes the workspace packages to npm (via npm trusted publishing — no token required),
  • creates the matching v<x.y.z> git tag, and
  • cuts a GitHub Release from the changelog.

Commit Guidelines

This project follows the Conventional Commits specification.

Developer's Certificate of Origin 1.1

By contributing to this project, I certify that:

- (a) The contribution was created in whole or in part by me and I have the right to
  submit it under the open source license indicated in the file; or
- (b) The contribution is based upon previous work that, to the best of my knowledge,
  is covered under an appropriate open source license and I have the right under that
  license to submit that work with modifications, whether created in whole or in part
  by me, under the same open source license (unless I am permitted to submit under a
  different license), as indicated in the file; or
- (c) The contribution was provided directly to me by some other person who certified
  (a), (b) or (c) and I have not modified it.
- (d) I understand and agree that this project and the contribution are public and that
  a record of the contribution (including all personal information I submit with it,
  including my sign-off) is maintained indefinitely and may be redistributed consistent
  with this project or the open source license(s) involved.