This repository contains a collection of community contributions built on top of the Effection structured concurrency library. All packages are published to NPM under the @effectionx scope.
This repository uses Volta to manage Node.js and pnpm versions. The versions are pinned in package.json.
Install Volta if you haven't already:
curl https://get.volta.sh | bashVolta will automatically install the correct Node.js and pnpm versions when you run commands in this repository.
pnpm installpnpm build # Build all packages (TypeScript + optional bundling)
pnpm build:tsc # Build TypeScript only
pnpm test # Run all tests
pnpm test:matrix # Test against all supported peer dependency versions
pnpm check # Type-check all packages
pnpm lint # Lint all packages
pnpm fmt # Format all files
pnpm fmt:check # Check formatting
pnpm sync # Check tsconfig references
pnpm sync:fix # Fix tsconfig references and dependenciesPackages in this repository declare their compatible versions for peer dependencies
like Effection, Vitest, etc. via peerDependencies. To verify compatibility across
the full range of supported versions, run:
pnpm test:matrixThis command:
- Reads each package's
peerDependencies(e.g.,effection,vitest) - Resolves the minimum and maximum versions that satisfy each range
- Generates a cartesian product matrix of all version combinations
- For each combination, installs the specific versions and runs tests
- Reports a compatibility matrix showing pass/fail status per combination
For example, a package with effection: "^3 || ^4" and vitest: "^3 || ^4" will
be tested with all four combinations: e3+v3, e3+v4, e4+v3, e4+v4.
This ensures packages work correctly with both the oldest supported versions and the latest releases of all peer dependencies.
┌─────────────────────────────────────────────────────────────────────────────┐
│ pnpm test:matrix │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 1. Read peerDependencies from all workspace packages │
│ │
│ @effectionx/bdd → effection: "^3 || ^4" │
│ @effectionx/vitest → effection: "^3 || ^4", vitest: "^3 || ^4" │
│ @effectionx/process → effection: "^3 || ^4" │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 2. Fetch versions from npm & resolve min/max for each range │
│ │
│ effection "^3 || ^4" → [3.0.0, 4.0.0] │
│ vitest "^3 || ^4" → [3.0.0, 4.0.0] │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 3. Generate cartesian product matrix │
│ │
│ ┌─────────────────┬─────────────────┬──────────────────────────────┐ │
│ │ effection │ vitest │ packages │ │
│ ├─────────────────┼─────────────────┼──────────────────────────────┤ │
│ │ 3.0.0 │ - │ bdd, process, chain, ... │ │
│ │ 4.0.0 │ - │ bdd, process, chain, ... │ │
│ │ 3.0.0 │ 3.0.0 │ vitest │ │
│ │ 3.0.0 │ 4.0.0 │ vitest │ │
│ │ 4.0.0 │ 3.0.0 │ vitest │ │
│ │ 4.0.0 │ 4.0.0 │ vitest │ │
│ └─────────────────┴─────────────────┴──────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 4. For each matrix entry: │
│ │
│ a. Set pnpm overrides (e.g., pnpm.overrides.effection=3.0.0) │
│ b. Install dependencies with overrides applied │
│ c. Run tests for applicable packages │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 5. Print summary table │
│ │
│ effection vitest Packages Passed Failed Status │
│ ─────────────────────────────────────────────────────────────── │
│ 3.0.0 - 15 150 0 PASS │
│ 4.0.0 - 15 150 0 PASS │
│ 3.0.0 3.0.0 1 6 0 PASS │
│ 4.0.0 4.0.0 1 6 0 PASS │
└─────────────────────────────────────────────────────────────────────────────┘
cd <package-name>
node --env-file=../.env --test "*.test.ts"-
Create a directory for your package
-
Add a
package.json:{ "name": "@effectionx/your-package", "version": "0.1.0", "type": "module", "license": "MIT", "exports": { ".": { "development": "./mod.ts", "default": "./dist/mod.js" } }, "files": ["dist", "mod.ts", "src"], "scripts": { "test": "node --env-file=../.env --test \"*.test.ts\"" }, "peerDependencies": { "effection": "^3 || ^4" } } -
Add a
tsconfig.json:{ "extends": "../tsconfig.json", "compilerOptions": { "outDir": "dist", "rootDir": "." }, "include": ["**/*.ts"], "exclude": ["**/*.test.ts", "dist"], "references": [] } -
Add your package to
pnpm-workspace.yaml -
Add your package to
tsconfig.jsonreferences -
Run
pnpm sync:fixto update dependencies -
Add a
README.md(text before---will be used as a description) -
Add your source code and export it from
mod.ts -
Add doc strings to your source code - they will be used for documentation
Most packages only need TypeScript compilation, which is handled automatically by the root tsc --build command. However, if your package requires additional build steps (like bundling), you can add a build:bundle script:
{
"scripts": {
"build:bundle": "esbuild mod.ts --bundle --outfile=dist/bundle.js --format=esm"
}
}The build process runs in two phases:
- TypeScript compilation (
tsc --build) - produces.jsand.d.tsfiles indist/ - Bundling (
turbo run build:bundle) - runs only for packages with abuild:bundlescript
Bundle output should go to a separate file (e.g., dist/bundle.js) rather than overwriting the tsc output, so consumers can choose between bundled and unbundled versions.
Packages are automatically published to NPM when merged to main using OIDC-based authentication with provenance attestation.
- Update the version in the package's
package.json - Merge to main
- The CI will automatically publish if the version doesn't exist on NPM
For packages that don't exist on NPM yet, OIDC cannot be used. The workflow requires an NPM_PUBLISH_TOKEN secret for the initial publish.
Setup for first publish:
- Create an npm automation token at https://www.npmjs.com/settings/tokens
- Add it as a repository secret named
NPM_PUBLISH_TOKEN - Merge to main - the workflow will use the token for the first publish
After a package is published for the first time, configure OIDC to enable tokenless publishing:
- Go to
https://www.npmjs.com/package/@effectionx/<package-name>/access - Under Publishing access, select Require two-factor authentication or an automation token or OIDC
- Under Configure OIDC publishing, add:
- Repository:
thefrontside/effectionx - Workflow:
.github/workflows/publish.yaml
- Repository:
Once OIDC is configured, the package will publish automatically without needing a token.
.internal/ # Internal tooling scripts (not published)
<package>/ # Package directories
mod.ts # Main entry point
*.test.ts # Tests
package.json # Package manifest
tsconfig.json # TypeScript config
README.md # Package documentation