Development

This guide explains how to set up a local development environment for kiln, run tests, lint code, and build the documentation.

Prerequisites

You will need the following tools installed:

Install uv by following the uv installation instructions.

Install just by following the just installation instructions.

Install jsonnetfmt using your system package manager:

# macOS
brew install go-jsonnet

# Debian / Ubuntu
sudo apt install jsonnet

# Other Linux (via Go toolchain)
go install github.com/google/go-jsonnet/cmd/jsonnetfmt@latest

Fork and clone

Fork the repository on GitHub, then clone your fork:

git clone https://github.com/<your-username>/kiln
cd kiln

Install all dependency groups and activate the virtual environment:

uv sync --all-groups

Install the pre-commit hooks (runs ruff automatically on every commit). The hook is repo-wide, so run this from the workspace root:

just -f ../../justfile setup

That’s it. You’re ready to develop.

Running tests

kiln uses pytest for testing.

Tests are organised into two directories:

tests/unit/

Pure Python tests.

tests/integration/

End-to-end CLI tests.

For fast feedback during development, run pytest directly:

just dev-test

To run the full test suite with tox (installs the package into a clean environment, matching what CI does):

just test

Both commands pass arguments through to pytest:

just dev-test tests/unit
just dev-test -k test_something
just test tests/unit

Coverage

kiln uses coverage.py for coverage reporting:

just coverage

This runs the full pytest suite under coverage and prints a per-file coverage table to the terminal.

Linting and formatting

kiln uses ruff for Python linting and formatting, and jsonnetfmt for Jsonnet formatting. Both run automatically as pre-commit hooks, but you can also run them manually.

Python:

just lint

# auto-fix and format
uv run --group lint ruff check --fix
uv run --group lint ruff format

Jsonnet:

# format a single file
jsonnetfmt --indent 2 --string-style d --in-place path/to/file.jsonnet

# format all Jsonnet files in the repo
find . -name '*.jsonnet' -o -name '*.libsonnet' | xargs jsonnetfmt --indent 2 --string-style d --in-place

Type checking

kiln uses zuban for type checking (native mode, not mypy-compatible):

just type-check

Documentation

The docs are built with Sphinx using the alabaster theme.

To build the docs:

just docs

To serve the docs locally with live reload at http://localhost:8000:

just serve-docs-autoreload

Repository layout

The src/ tree is split into the target-agnostic engine, runtime helpers, and one package per target:

src/codegen/

Target-agnostic code-generation engine. Scope discovery, the @operation protocol, the build store, the render registry, and typed output dataclasses live here.

src/ingot/

Runtime helpers (auth, files, queue, telemetry) imported by the code generated by the be target. Pure Python, no codegen dependency.

src/be/

FastAPI / SQLAlchemy backend code generator built on codegen. The config schema, built-in operations, Jinja templates, and Jsonnet stdlib live here.

src/be_root/

One-shot bootstrap target for a be-driven project. Emits the initial main.py / pyproject.toml / justfile / config/project.jsonnet skeleton.

src/fe/

React / TypeScript frontend code generator – a thin wrapper over @hey-api/openapi-ts that translates a kiln-side jsonnet config into openapi-ts.config.ts so the fe-side codegen reads from the same source of truth as the rest of the project.

src/fe_root/

One-shot bootstrap target for a fe-driven project. Emits the initial package.json / justfile / tsconfig.json / vite.config.ts / src/ skeleton, wired to @fsh/components-library.

See Architecture for how the pieces fit together.

Contributing

Contributions are welcome. Fork the repository, make your changes with tests where applicable, verify the test suite and linter pass (see the sections above), then open a pull request against main.

Type annotations are required on all public API.

For security vulnerabilities, see SECURITY.md rather than opening a public issue.