Contributing to Stacktower
May 1, 2026 · View on GitHub
Thank you for your interest in contributing! This guide covers the most common contribution paths: adding new languages, manifest parsers, and output formats.
Getting Started
git clone https://github.com/stacktower-io/stacktower.git
cd stacktower
make install-tools
make check
make check runs formatting, linting, tests, and vulnerability checks. All four must pass before submitting a PR.
Project Structure
cmd/stacktower/ CLI entrypoint
internal/cli/ CLI commands, flags, output formatting
internal/cli/ui/ Terminal UI components (spinners, tables, styles)
pkg/core/dag/ DAG data structure and crossing algorithms
pkg/core/deps/ Dependency resolution per language ecosystem
pkg/core/render/ Layout and rendering (tower, node-link)
pkg/pipeline/ Parse → layout → render pipeline
pkg/integrations/ External API clients (GitHub, OSV, registries)
pkg/security/ Vulnerability scanning
pkg/sbom/ SBOM generation (CycloneDX, SPDX)
pkg/cache/ Caching layer
pkg/graph/ Wire types for graph I/O
The boundary between pkg/ (stable library API) and internal/ (CLI-only) is intentional. Library consumers import from pkg/; CLI-specific behavior stays in internal/cli/.
Adding a New Language Ecosystem
Each language lives in its own package under pkg/core/deps/<language>/ and implements the deps.Language struct. Use an existing ecosystem (e.g., pkg/core/deps/python/) as a reference.
Steps
-
Create the package at
pkg/core/deps/<language>/. -
Define the
Languagevariable with registry info, manifest types, and resolver/parser factories:Name— lowercase identifier (e.g.,"python","rust")DefaultRegistry— primary registry nameManifestFilenames— map of filename to manifest typeNewResolver— factory for the registry resolverNewManifest— factory for manifest parsers
-
Implement a resolver that fetches package metadata from the registry and returns a
deps.Packagewith versions and dependencies. -
Implement manifest parsers for each supported manifest/lock file format.
-
Register the language in
pkg/core/deps/languages/languages.goby adding it to theAllslice. -
Add tests — at minimum, unit tests for the resolver and each manifest parser.
-
Add example manifests in
examples/manifest/for the new ecosystem. -
Update the README — add the language to the supported languages list and the manifest file table.
Adding a New Manifest Parser
To add support for a new manifest file within an existing language:
- Add a new manifest type in the language's package (e.g.,
pkg/core/deps/python/). - Register the filename in the language's
ManifestFilenamesmap. - Implement the parser — it receives raw file bytes and returns a dependency graph.
- Add unit tests with representative fixture files.
- Add an example manifest to
examples/manifest/.
Adding a New Output Format
Rendering output formats are handled in pkg/core/render/. To add a new format:
- Implement a sink in the appropriate render package (e.g.,
pkg/core/render/tower/sink/). - Register the format in
pkg/pipeline/formats.go. - Wire it into the CLI in
internal/cli/render.go.
Code Style
- Formatting:
gofmt+goimportswith local prefixgithub.com/stacktower-io/stacktower. Runmake fmtbefore committing. - Linting:
golangci-lintwith the config in.golangci.yml. Runmake lint. - Comments: Avoid obvious narration. Comments should explain why, not what.
- Errors: Use
CLIErrorwithKind,Message, andHintfor user-facing errors ininternal/cli/. Library code inpkg/returns plain errors. - Tests: Table-driven tests preferred. Use
_test.gofiles adjacent to the code they test.
Commit Messages
This project follows Conventional Commits. PR titles are validated automatically.
feat: add Swift ecosystem support
fix(python): handle empty requirements.txt
docs: update manifest file table
test(rust): add Cargo.lock parser edge cases
Valid types: feat, fix, docs, style, refactor, perf, test, chore, ci, build, revert.
Pull Requests
- One logical change per PR.
- Include tests for new functionality.
- Update the README if your change affects CLI behavior, flags, or supported ecosystems.
- All CI checks must pass (format, lint, test, vulncheck).
Reporting Issues
Use GitHub Issues for bugs and feature requests. For security vulnerabilities, see SECURITY.md.