Skip to main content

Getting Started

DomainDocs4s generates human-readable domain documentation directly from your Scala code. Instead of maintaining docs manually, you annotate and describe your domain in code, and then use a collector to build a documentation model that can be rendered into various output formats.

In this guide we’ll:

  1. Write a tiny domain example
  2. Describe the domain with annotations
  3. Collect symbols and generate documentation output

Dependency

Add the following dependency to your project:

"org.business4s" %% "domainDocs4s-collector" % "unreleased"

Create a Domain Example

Create a tiny domain model - for example, an Order aggregate with a status and identifier:

final case class Id(value: Int)

enum OrderStatus {
case Draft, Paid, Cancelled
}

final case class Order(id: Id, status: OrderStatus)

Annotate the Domain

Import @domainDoc annotation:

import domaindocs4s.domainDoc

Document the domain using annotations with proper descriptions and optional name overrides:

@domainDoc("Unique technical identifier of an Order", "OrderId")
final case class Id(value: Int)

@domainDoc("Business lifecycle state of an Order")
enum OrderStatus {
case Draft, Paid, Cancelled
}

@domainDoc("Aggregate root representing a customer Order")
final case class Order(id: Id, status: OrderStatus)

Generate Documentation

DomainDocs4s is built around a simple pipeline:

  • collect symbols and metadata from Scala 3 compilation artifacts (.tasty files)
  • build a documentation model (a structured model of documented symbols)
  • render it to an output format

Here is the minimal end-to-end example:

import domaindocs4s.collector.{DomainDocsContext, TastyContext, TastyQueryCollector}
import domaindocs4s.output.Glossary

@main def generateDomainDocs(): Unit = {

// 1) Setup collector
given DomainDocsContext = TastyContext.fromCurrentProcess()
val collector = new TastyQueryCollector

// 2) Collect documentation model
val docs =
collector
.collectSymbols("domaindocs4s.order") // the package with your domain

// 3) Generate glossary markdown (or other supported output and format)
val glossary =
Glossary
.build(docs) // build glossary
.asMarkdown // render markdown

// 4) Write the result to file
Glossary.write(glossary, "glossary.md")
}

After running it, you should have a file glossary.md which contains a glossary of your domain:

ParentNameDescription
OrderAggregate root representing a customer Order
OrderIdUnique technical identifier of an Order
OrderStatusBusiness lifecycle state of an Order