Contributing
slackblocks is a monorepo containing five language-native implementations and one shared conformance contract. A feature is complete when its wire output and validation category agree in Python, TypeScript, Go, Java, and C#.
Repository layout
spec/contains the normative fixtures, validation cases, limits, and principles.python/contains the Python package and its tests.typescript/contains the ESM TypeScript package and its tests.go/contains the Go v2 module, its directslack-go/slackblock integration, and its tests.java/contains the Java 17 Maven artifact, concrete fluent builders, direct Slack Java SDK model integration, and its tests.csharp/contains the .NET 8 NuGet package, its generated immutable value types, and its tests.docs/contains this Docusaurus site and executable examples.
Set up the workspace
Python development uses uv:
cd python
uv sync --all-groups
JavaScript development uses the pnpm workspace from the repository root:
pnpm install --frozen-lockfile
Run the checks
From python/:
uv run pytest test/unit test/conformance test/docs
uv run ruff check slackblocks test
uv run mypy slackblocks
uv build --clear
uv run twine check --strict dist/*
From the repository root:
pnpm --filter @nicklambourne/slackblocks typecheck
pnpm --filter @nicklambourne/slackblocks test
pnpm --filter @nicklambourne/slackblocks check:package
pnpm --filter @slackblocks/docs build
From go/:
go test -race -cover ./...
go vet ./...
From java/:
./mvnw clean verify
On JDK 21 or newer the Java build also runs google-java-format, Error Prone, and NullAway; on JDK 17 it compiles and tests only. The generated Java model comes from spec/model.json, the language-neutral model shared with the C# and Go generators. After changing that file or spec/limits.json, regenerate and format the sources from the repository root:
python3 java/generator/generate_models.py --check-go
(cd java && ./mvnw spotless:apply)
--check-go fails if the Java model and the Go builder registry expose different fields. The Go generator (go generate ./... in go/) reads the same spec/model.json and spec/limits.json to write the doc comments on every generated builder method, so a description, limit, or Slack link edited there reaches the Go and Java references together.
From csharp/, with the .NET 8 SDK or newer:
dotnet test
dotnet format --verify-no-changes
The build treats warnings as errors with the .NET analyzers enabled, and the tests compile and run every C# documentation snippet. The C# value types are generated from the same spec/model.json. After changing it, regenerate them from the repository root; CI fails when the checked-in output differs:
python3 csharp/generator/generate_models.py
All five conformance suites exercise every ID in spec/manifest.json. A checked-in conformance/skiplist.txt may document an intentional language gap, but unknown failures and stale skips fail the suite.
Add or change a Block Kit feature
- Add or update canonical JSON in
spec/fixtures/valid/, register it inspec/manifest.json, and link the exact official Slack reference used to validate it. - Map every new JSON-producing capability to at least one valid fixture in
spec/coverage.json. - Add invalid behavior to
spec/fixtures/invalid/manifest.jsonwhen the feature introduces a validation rule. New Slack icon names and surface block types go inspec/vocabulary.json. Every scalar leaf inspec/limits.jsonmust have a matching invalid case. - Update
spec/limits.jsonfor shared scalar constraints. - Implement the feature idiomatically in all five packages, or record a reason in the affected skip list.
- Add language-native tests and update the relevant guide or executable example.
When introducing a cross-language API, serialized JSON and validation outcomes are shared; public naming and construction style are language-native.
Documentation
Run the local site from the repository root:
pnpm --filter @slackblocks/docs start
Narrative pages live in docs/docs/. Python, TypeScript, Go, Java, and C# API pages are generated during every docs build. The Java pages come from the javadoc tool, through docs/scripts/java-reference/ReferenceDoclet.java, so building the site needs a JDK 17 or newer on PATH or in JAVA_HOME. The C# pages come from the compiled library's XML documentation, through docs/scripts/csharp-reference/, so building the site also needs the .NET 8 SDK or newer. Both render through docs/scripts/reference_pages.mjs. Reusable examples live under the matching directory in docs/examples/; tests execute them and compare their output with docs/examples/section_hello.json.
Use LanguageContent with Python, TypeScript, Go, Java, and CSharp children for language-specific prose or examples. The site-level selector controls which child is shown.
Pull requests
Keep changes scoped, add a regression test for bug fixes, and include fixture changes whenever wire behavior changes. All local checks relevant to the changed package should pass before review.