1. Wiki
  2. aether-packages
  3. Publishing

Publishing & Contributing

Both packages are published to the GitHub Package Registry under the @aetherAssembly scope. Publishing is fully automated — pushing a version tag triggers the workflow.

Development setup

You need Node.js 22+ and a GitHub personal access token with read:packages scope. Add it to ~/.npmrc (never the project's .npmrc):

//npm.pkg.github.com/:_authToken=YOUR_TOKEN
git clone https://github.com/AetherAssembly/aether-packages
cd aether-packages
npm install
npm run build
npm test
npm run typecheck

How the publish workflow works

.github/workflows/publish.yml triggers on any tag matching v*:

  1. Checks out the repo
  2. Sets up Node 22 with registry-url: https://npm.pkg.github.com and scope: @aetherAssembly
  3. Runs npm ci
  4. Runs npm run build (TypeScript composite build across all packages)
  5. Runs npm test
  6. Runs npm publish --workspaces --access public

NODE_AUTH_TOKEN is set to ${{ secrets.GITHUB_TOKEN }}, provided automatically by GitHub Actions — no manual secret setup required. If build or tests fail, publish never runs.

A separate CI workflow (.github/workflows/ci.yml) runs typecheck, build, and tests on every push and PR to main.

Versioning strategy

Packages are versioned independently — bumping @aetherAssembly/core doesn't require bumping @aetherAssembly/ui.

ChangeBump
Bug fix, no API changePatch (1.0.0 → 1.0.1)
New export, new optional prop, new adapterMinor (1.0.0 → 1.1.0)
Removed export, renamed prop, breaking interface changeMajor (1.0.0 → 2.0.0)
Downstream apps (Before It's Gone, Attyre) pin to ^1.0.0. A major bump requires updating their package.json and migrating call sites before cutting the release.

Release process

1. Bump the version

npm version patch --workspace packages/core

Or edit package.json manually.

2. Update the changelog

Add an entry to CHANGELOG.md with today's date in YYYY-MM-DD format.

3. Commit

git add packages/core/package.json CHANGELOG.md
git commit -m "chore(core): release v1.0.1"

4. Tag and push

# single package
git tag core-v1.0.1
git push origin core-v1.0.1

# both packages together
git tag v1.1.0
git push origin v1.1.0

Both formats match the v* trigger in the publish workflow.

5. Verify

Check the Actions tab to confirm the publish workflow completes. The package will appear under the repo's Packages section on GitHub.

Adding a new package

Create the directory under packages/, add a package.json (no "private": true), tsconfig.json extending the base, and a src/index.ts entry point. npm publish --workspaces picks it up automatically on the next tag push.

To exclude a package from publishing, set "private": true in its package.json.

Adding a storage adapter

Create packages/core/src/storage/<name>.ts, implement StorageAdapter, export it from packages/core/src/index.ts, and add tests in <name>.test.ts. See the Storage page for the full interface contract.

Adding a UI component

Create packages/ui/src/components/<Name>.tsx and export it from packages/ui/src/index.ts. Follow these conventions:

  • Props extend the relevant HTML element's attribute type and spread ...rest onto the root element.
  • All styling uses --ae-* CSS custom properties defined in styles.css — no hardcoded values.
  • BEM class names scoped to ae-: ae-<component>, ae-<component>__<element>, ae-<component>--<modifier>.
  • Accessibility first: correct roles, aria-* attributes, keyboard handling. Use native HTML elements (<dialog>, <button>, <input>) wherever possible.

TypeScript conventions

tsconfig.base.json enables strict options beyond strict: true:

  • exactOptionalPropertyTypes — don't pass prop: undefined where the type is prop?: T. Either omit the key or provide a value.
  • noUncheckedIndexedAccess — array index and object key access returns T | undefined. Always guard or assert.
  • noImplicitReturns — all code paths must return in non-void functions.

moduleResolution: bundler is used, so local imports use .js extensions even though the source is .ts.

Auth for CI pipelines

Pipelines in consuming repos that need to install these packages require NODE_AUTH_TOKEN set as a secret, or can use the built-in GITHUB_TOKEN if the repo is within the same organisation and has read:packages permission.

Last updated: 2026-10-04 AetherAssembly/aether-packages →