Self-hosted service
scala/docs.scala-lang avatar
scala/docs.scala-lang

docs.scala-lang and the source behind the Scala documentation site

The Scala Documentation website

574 stars1,037 forksHTMLLicense varies

At a glance

What is it?
The docs.scala-lang repository holds both the source of the Scala documentation website and the Scala Improvement Process proposals, built with Jekyll and Ruby, and it carries the content in fifteen translated trees alongside the English one. The interesting detail is the licensing split, where the prose is CC-BY-SA and the site machinery is under the Scala License.
Who is it for?
docs.scala-lang is a good fit for a contributor who wants to change the Scala documentation or draft a SIP, because the site source, the translation trees and the proposal files live in one repository with a documented contribution process and a Docker path that avoids Ruby setup entirely.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly HTML, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Two things in one repository

The repository description is a single line: the Scala Documentation website. The README says more than that, and the more is the interesting part. The repository contains the source for the Scala documentation website, as well as the source for Scala Improvement Process, or SIP, documents.

That pairing is the reason the repository exists as a single unit. A SIP is the mechanism by which the Scala language changes, and the documentation site is where the language as it currently stands is described. Keeping the proposals and the manuals in the same place means the person reading about a feature can also read the proposal that introduced it, and the people who write the SIPs are the same people who write the guides.

The structure at the root confirms the two-track layout. There is a _sips/ directory for the improvement process documents and a scala3/ directory for the Scala 3 pages, alongside the prose directories such as _tour/, _books/, _cheatsheets/, _glossary/, _overviews/ and an api/ directory. The top-level index.md, tutorials.md, books.md, online-courses.md and scalacenter-courses.md are the navigation entries, and there are additional directories for news/ and resources/.

The primary language is listed as HTML, which is a consequence of the site being a Jekyll project rather than a signal that the repository is mostly markup. There is a _sass/ directory, _layouts/, _includes/, _plugins/, _data/, _style/ and a _config.yml at the root, which is the standard Jekyll convention for separating templates from content.

The audience is two groups with different intentions. Contributors to the documentation are people who write guides and fix errors in existing ones. Contributors to the SIP process are people proposing language changes, and the documentation there is formal by design, following a template rather than a tutorial style.

A Jekyll site on Ruby 3.2.6 with a pinned Bundler

The site is built with Jekyll, a Ruby framework, and the README says you will need Ruby and Bundler installed, pointing at the Jekyll installation instructions for the details.

The container image pins the toolchain precisely. The Dockerfile starts from ruby:3.2.6 and installs bundler:2.6.5 as a gem, sets the working directory to /srv/jekyll, copies the Gemfile and the Gemfile.lock, then runs bundle install inside the image. The Gemfile.lock is committed at the repository root, which is what makes the container build reproducible: the versions resolved on a contributor's laptop and the versions in the image are the same set.

The comment on the Dockerfile says the bundle version is echoed after installation, which reads as a deliberate check rather than decoration. A Gemfile.lock that drifts out of step with the Bundler version is a classic source of a build that works for one contributor and fails for the next, and printing the version makes that visible in the build log.

One line in the Dockerfile is worth understanding before you use the image. The chmod u+s /bin/chown makes the chown binary setuid, and the compose file uses it for a specific reason, described below.

For the site itself, the Ruby dependency set is managed entirely through Bundler. The README notes that bundle install will automatically put the gems into ./vendor/bundle, so a local install does not touch the system gem path, which matters on a shared machine or a CI runner.

Running it locally, and the five minute first build

The local quickstart is two commands, and the README is candid about the timing.

bash
bundle install
bundle exec jekyll serve -I

The -I flag is the incremental build option, and the README asks you to use it. The quoted advice is that it might take around 5 minutes at first but incremental compilations will be fast. That first build is slow because Jekyll has to render the whole site, and with a documentation set this size, including the translated trees, that is a lot of Markdown and templates.

Once the server is running, the generated site is available at http://localhost:4000.

There is a second mode. If you add --watch at the end of the command line, Jekyll will watch the filesystem and regenerate the site automatically. The difference from -I is worth noting: -I makes the server faster by reusing previous output, while --watch rebuilds when files change. For a documentation author editing Markdown, --watch is the mode that makes the edit and preview loop usable.

There is also a macOS-specific note in the README, which links to a GitHub issue about trouble on MacOS, and a Windows-specific note about encoding errors. If you get incompatible encoding errors when generating the site under Windows, the console in which you are running Jekyll has to be able to work with UTF-8 characters, and the documented fix is to execute chcp 65001, a command the README says is best added to the jekyll.bat script.

That is the shape of the whole toolchain story: Jekyll, Bundler, kramdown for Markdown, and a handful of platform caveats that a contributor on Windows or macOS will hit at least once.

The Docker path and the root-owned file problem

The Docker Compose route exists so that contributors do not need Ruby at all, and the README gives a full set of instructions for it.

You need Docker Engine and Docker Compose installed. Under macOS on either Intel or Apple silicon, instead of installing Docker Desktop you can use Homebrew with Colima, and the README gives the exact command: brew install colima docker docker-compose.

Then there is the detail that trips people up. UID and GID environment variables are needed to avoid Docker writing files as root in your directory. The compose file sets the container user from them:

yaml
services:
  jekyll:
    user: "${UID}:${GID}"
    build: .
    command: sh -c "chown $UID / && bundle exec jekyll serve --incremental --host=0.0.0.0 "
    ports:
      - '4000:4000'

The chown $UID / at the start of the command is why the Dockerfile makes chown setuid. The container runs as your host user so that the files Jekyll writes into the mounted volume belong to you rather than to root, and the setuid bit lets that first ownership correction succeed without escalating privileges outside the container.

The start command is the same as the local one, with --incremental spelled out in full and the host bound to 0.0.0.0 so the published port is reachable from outside the container. The port mapping exposes 4000, so the site is at http://localhost:4000.

By default the compose file is docker-compose.yml, which builds the website and serves it. If you only need to build the site, the README says to add the -f docker-compose_build-only.yml flag, and the repository ships that second compose file for the purpose. When the website dependencies change, meaning the contents of the Gemfile, you have to rebuild the Docker image with docker-compose up --build, and if the image itself is the problem, docker-compose build --no-cache forces a clean rebuild.

Fifteen translation trees and how they fit together

The root directory listing shows the scale of the translation effort, with dedicated directories for each language: _ba for Bosnian, _de, _es, _fr, _glossary/, _it, _ja, _ko, _pl, _pt-br, _ru, _th, _uk, _zh-cn and _zh-tw.

Jekyll handles this by treating each collection directory as a source rather than as output, and _config.yml is where the site configuration, including the locale configuration, lives. The translated trees are not translations of the whole site. They cover the guides, and the same set of top-level entry points such as index.md and tutorials.md serve the whole site.

The consequence for a contributor is that a change to an English guide is not automatically reflected in the other languages, and the translation directories are updated by their own maintainers at their own pace. That is a normal arrangement for documentation of this size, and it is worth knowing before you go looking for why the French version of a page you just edited is still stale.

The content types are worth distinguishing, because the repository holds several different kinds of document. The _tour/ directory is the Scala Tour, the guided introduction. The _books/ directory holds longer book-length text, and the root books.md and online-courses.md point to external courses as well. The _cheatsheets/ directory holds quick reference pages, the _glossary/ directory the terminology list, and _overviews/ the topic overviews. The _sips/ directory holds the improvement process documents, and api/ holds API documentation.

The Markdown flavour is kramdown, using kramdown extensions, as the README states. For contributors on macOS the README suggests MacDown as a free Markdown editor, since it generates the translated Markdown in real time alongside the editor window, which is the same preview loop as --watch but without leaving your editor.

Licensing: two regimes in one repository

The licence section is the part of this README that most affects what you can do with the contents afterwards, and it deliberately splits the repository in two.

All documentation contained in the repository is licensed by EPFL under a Creative Commons Attribution-Share Alike 3.0 Unported licence, CC-BY-SA, unless otherwise noted. Submitting a pull request, or otherwise contributing, implicitly agrees to license the contribution under that same CC-BY-SA licence.

The source code of the website is licensed to EPFL under the Scala License, unless otherwise noted. That is a separate grant covering the Jekyll machinery, the templates and the build configuration rather than the prose.

The share-alike term in CC-BY-SA is the part to understand. If you take documentation from this repository and adapt it, the adaptation has to be released under the same licence, and attribution to EPFL is required. For anyone writing a course, a book or an internal handbook that quotes or reworks the Scala guides, that obligation travels with the text. The documentation licence is not the same thing as the licence of the Scala language implementation, which is separate.

The repository's own licence field is listed as unknown in the project metadata, so the two grants in the README are the operative statement of terms rather than a single licence identifier.

The contribution policy is stated just as plainly. Small changes, or corrected typos, will generally be pulled in right away. Large changes, such as the addition of new documents or the rewriting of existing documents, will be thoroughly reviewed, and new documents are expected to be very well-polished, complete and maintained in order to be accepted. The README points contributors to the Add New Guides/Tutorials page before making a contribution, and there is a CODE_OF_CONDUCT.md at the repository root.

Editorial conclusion

docs.scala-lang is a good fit for a contributor who wants to change the Scala documentation or draft a SIP, because the site source, the translation trees and the proposal files live in one repository with a documented contribution process and a Docker path that avoids Ruby setup entirely. It is a poor fit if you only want to read the documentation, since the published site at docs.scala-lang.org is the thing to use, and a poor fit if you want to run a fork of the site as your own product, because the content is CC-BY-SA and the site source carries its own Scala-specific licence terms. Before opening a pull request, read the Add New Guides/Tutorials page the README points to, and note that small typo fixes are pulled in quickly while new documents are expected to be complete and polished.

Frequently asked questions

How do I build the Scala documentation website locally?

Install Ruby and Bundler, then run `bundle install` followed by `bundle exec jekyll serve -I`. The README notes the first build may take around five minutes, while incremental compilations are fast, and the site is then available at http://localhost:4000.

Can I build the Scala docs site with Docker instead of Ruby?

Yes. The repository ships a docker-compose.yml that builds the site and serves it on port 4000, plus a docker-compose_build-only.yml for build only. You need Docker Engine and Docker Compose, and the UID and GID environment variables are needed so Docker does not write files as root.

What is in the Scala Improvement Process directory?

The repository holds the source for both the Scala documentation website and the Scala Improvement Process documents, in the _sips/ directory. A SIP is the proposal mechanism through which the language changes, and the _overviews/, _tour/, _books/, _cheatsheets/, _glossary/ and api/ directories hold the other documentation types.

Which languages is the Scala documentation available in?

The repository root has separate directories for Bosnian, German, Spanish, French, Italian, Japanese, Korean, Polish, Brazilian Portuguese, Russian, Thai, Ukrainian, Simplified Chinese and Traditional Chinese, alongside the English content and the _glossary/ directory.

What licence applies to the Scala documentation content?

All documentation in the repository is licensed by EPFL under Creative Commons Attribution-Share Alike 3.0 Unported, unless otherwise noted, and contributing means agreeing to that licence. The source code of the website itself is licensed separately under the Scala License.

Official sources

  1. Issues
  2. Project website
  3. README
  4. scala/docs.scala-lang on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/scala-docs-scala-lang.svg)](https://hysenlabs.com/projects/scala-docs-scala-lang)

Was this useful?